Problema del Sudoku
Modelo
Variables
Variables de decisión:
Función objetivo
La función objetivo en este caso no es necesaria
Puesto que es un problema de factibilidad, pero con esta función estaríamos haciendo un sudoku modificado más interesante.
Restricciones
- Asignación única por celda:
- No repetir dígito en cada configuración (filas, columnas y bloques):
- Fijación de pistas (decisiones ya tomadas):
- Dominio:
Código
m=81 # nº Celdas
k=27 # nº Configuraciones: n filas + n columnas + n cuadrantes
n=9 # nº Digitos
C=1:m # Conjunto de celdas
F = [] # Array con los array de celdas correspondientes a cada configuración. Columnas/filas/cuadrantes
# Añadir filas (cada fila tiene celdas consecutivas)
for i in 1:9
push!(F, [(i - 1) * 9 + j for j in 1:9]) # Ej: fila 1 tiene celdas 1 a 9
end
# Añadir columnas (cada columna tiene celdas separadas por 9)
for j in 1:9
push!(F, [j + 9 * (i - 1) for i in 1:9]) # Ej: columna 1 tiene celdas 1, 10, 19...
end
# Añadir cuadrantes (3x3 bloques)
for q_row in 0:2
for q_col in 0:2
# Corregir el cálculo para que los índices estén en el rango de 1 a 81
start = 27 * q_row + 3 * q_col + 1
# println("Number: ",[start + i % 3 + 9 * div(i, 3) for i in 0:8])
push!(F, [start + i % 3 + 9 * div(i, 3) for i in 0:8])
end
end
# Verificación de que tenemos 27 configuraciones
@assert length(F) == 27 # F ahora tiene las celdas para 9 filas, 9 columnas y 9 cuadrantes
D=1:n
model = Model(HiGHS.Optimizer)
set_silent(model)
@variable(model, x[C,D], Bin)
@objective(model, Min, 0) # Tenemos como objetivo minimizar a 0, porque en este problema nos importa que simplemente se resuelva el sudoku
@constraint(model, [i in C], sum(x[i,:]) == 1) # cada celda tiene un único digito y por tanto cada celda tendrá un dígito
@constraint(model, [f in 1:k, j in D], sum(x[i,j] for i in F[f]) == 1) # Cada configuración sólo puede tener una vez al digito j
println(model)
status = optimize!(model)
@show termination_status(model)
println("Total: ",objective_value(model))
# Imprimir el sudoku en formato 9x9
println("\nSolución de Sudoku:")
for i in 1:m
for j in 1:n
# Verificar cuál valor de j está asignado a la celda i
if value(x[i,j]) > 0.5
print("$j ") # Imprimir el valor j asignado a la celda i
end
end
# Formato para cada fila: después de cada 9 celdas, pasar a la siguiente línea
if i % 9 == 0
println()
end
end
Notas
- La restricción (2) compacta filas , columnas y bloques .
- Expansión alternativa:
- Filas
- Columnas
- Bloques
Problema de gestión de un almacén de una fábrica single-item uncapacitated lot-sizing problem
.
Tengo una fábrica y me dedico a fabricar un producto.