Está en la página 1de 5

Sudoku con AMPL

Stefano Nasini

Dept. of Statistics and Operations Research


Universitat Politécnica de Catalunya

La solución de un sudoku siempre es un cuadrado latino, es decir, una matriz de n×n elementos, en la
que cada casilla está ocupada por uno de los n símbolos de tal modo que cada uno de ellos aparece
exactamente una vez en cada columna y en cada fila, aunque el recíproco en general no es cierto ya que el
sudoku establece la restricción añadida de que no se puede repetir un mismo número en una región.
Para costruir un modelo de optimizaciòn que nos permita solucionar un Sudoku hace falta convertir
en costricciones de un problema de programaciòn matematica las que son las reglas del juego.
Dichas reglas son rellenar una cuadrícula de 9 × 9 celdas (81 casillas) dividida en subcuadrículas de
3 × 3 (también llamadas "cajas" o "regiones") con las cifras del 1 al 9 partiendo de algunos números ya
dispuestos en algunas de las celdas. El sudoku que querriamos solucionar es el siguiente:

Antes que todo, nuestras variables de deciciones han de ser variables binarias que nos informan de la
presencia o absencia de una cifra en una casilla. Asì que dicha variable de deciciòn estarà definida por tres
subindices: fila, columna, digito, y tomaràvalor 1 en el caso en el que en una determinada casilla
(identificada por sus coordenadas) hay un determinado digito.
Imponemos que en cada celda solo haya un digito y no màs.

1
9

∑ Cell
c =1
abc =1

Imponemos que un digito de 0 a 9 aparezca solo una vez por cada fila.

∑ Cell
a =1
abc =1

Imponemos que un digito de 0 a 9 aparezca solo una vez por cada columna.

∑ Cell
b =1
abc =1

Imponemos que en un cuadrado 3x3 un digito aparezca una sola vez.

3 3

∑∑ Cell
a =1 b =1
abc =1

Imponemos que en un cuadrado 3x3 un dado digito aparezca una sola vez.

3 3 3 6 3 9

∑∑ Cellabc = 1
a =1 b =1
∑∑ Cellabc = 1
a =1 b = 4
∑∑ Cell
a =1 b = 7
abc =1
6 3 6 6 6 7

∑∑ Cell
a = 4 b =1
abc =1 ∑∑ Cell
a =4 b=4
abc =1 ∑∑ Cell
a = 4 b =7
abc =1
9 3 7 6 9 9

∑∑ Cell
a = 7 b =1
abc =1 ∑∑ Cell
a =7 b = 4
abc =1 ∑∑ Cell
a =7 b =7
abc =1

De dicho problema buscamo una cualquiera soluciòn factible, asì que no hace falta poner ninguna
funciòn objetivo. Lo implementamos en AMPL como problema de programaciòn entera de la forma
siguiente.

var Cell{1..9,1..9,1..9} binary;

minimize Niente;

subject to Somma_1 {a in 1..9,b in 1..9}:


sum{c in 1..9} Cell[a,b,c]=1;

subject to Somma_2 {a in 1..9,c in 1..9}:


sum{b in 1..9} Cell[a,b,c]=1;

subject to Somma_3 {b in 1..9,c in 1..9}:


sum{a in 1..9} Cell[a,b,c]=1;

subject to Riquadri_1 {c in 1..9}:


sum{a in 1..3,b in 1..3} Cell[a,b,c]=1;

subject to Riquadri_2 {c in 1..9}:


sum{a in 1..3,b in 4..6} Cell[a,b,c]=1;

subject to Riquadri_3 {c in 1..9}:


sum{a in 1..3,b in 7..9} Cell[a,b,c]=1;

subject to Riquadri_4 {c in 1..9}:

2
sum{a in 4..6,b in 4..6} Cell[a,b,c]=1;

subject to Riquadri_5 {c in 1..9}:


sum{a in 4..6,b in 1..3} Cell[a,b,c]=1;

subject to Riquadri_6 {c in 1..9}:


sum{a in 4..6,b in 7..9} Cell[a,b,c]=1;

subject to Riquadri_7 {c in 1..9}:


sum{a in 7..9,b in 1..3} Cell[a,b,c]=1;

subject to Riquadri_8 {c in 1..9}:


sum{a in 7..9,b in 4..6} Cell[a,b,c]=1;

subject to Riquadri_9 {c in 1..9}:


sum{a in 7..9,b in 7..9} Cell[a,b,c]=1;

subject to C1: Cell[1,1,5]=1;


subject to C2: Cell[1,2,3]=1;
subject to C3: Cell[1,5,7]=1;
subject to C4: Cell[2,1,6]=1;
subject to C5: Cell[2,4,1]=1;
subject to C6: Cell[2,5,9]=1;
subject to C7: Cell[2,6,5]=1;
subject to C8: Cell[3,2,9]=1;
subject to C9: Cell[3,3,8]=1;
subject to C10: Cell[3,8,6]=1;
subject to C11: Cell[4,1,8]=1;
subject to C12: Cell[4,5,6]=1;
subject to C13: Cell[4,9,3]=1;
subject to C14: Cell[5,1,4]=1;
subject to C15: Cell[5,4,8]=1;
subject to C16: Cell[5,6,3]=1;
subject to C17: Cell[5,9,1]=1;
subject to C18: Cell[6,1,7]=1;
subject to C19: Cell[6,5,2]=1;
subject to C20: Cell[6,5,2]=1;
subject to C21: Cell[6,9,6]=1;
subject to C22: Cell[7,2,6]=1;
subject to C23: Cell[7,7,2]=1;
subject to C24: Cell[7,8,8]=1;
subject to C25: Cell[8,4,4]=1;
subject to C26: Cell[8,5,1]=1;
subject to C27: Cell[8,6,9]=1;
subject to C28: Cell[8,9,5]=1;
subject to C29: Cell[9,5,8]=1;
subject to C30: Cell[9,8,7]=1;
subject to C31: Cell[9,9,9]=1;

En el ultimo grupo de constricciones hemos impuesto los valores predefinidos de algunas celdas,
como mostra la representaciòn grafica de la pagina anterior. Utilizando CPLEX como solver, optenemos la
siguiente soluciòn binaria de nuestro problema.
Cada matriz corresponde a una fila del sudoku. Los valores de fila de la matriz corresponden a las
columnas del sudoku y los valores en columna a cala digito que puede ser introducido. Por ejemplo el valor
Cell[1,1,1]=0 nos dice que en la celda(1,1) del sudoku el valor 1 no esta presente.

ampl: model sudoku1.mod;


ampl: solve;
Solution determined by presolve;
objective Niente = 0.

3
ampl: display Cell;
Cell [1,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 0 0 0 0 1 0 0 0 0
2 0 0 1 0 0 0 0 0 0
3 0 0 0 1 0 0 0 0 0
4 0 0 0 0 0 1 0 0 0
5 0 0 0 0 0 0 1 0 0
6 0 0 0 0 0 0 0 1 0
7 0 0 0 0 0 0 0 0 1
8 1 0 0 0 0 0 0 0 0
9 0 1 0 0 0 0 0 0 0

[2,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 0 0 0 0 0 1 0 0 0
2 0 0 0 0 0 0 1 0 0
3 0 1 0 0 0 0 0 0 0
4 1 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 1
6 0 0 0 0 1 0 0 0 0
7 0 0 1 0 0 0 0 0 0
8 0 0 0 1 0 0 0 0 0
9 0 0 0 0 0 0 0 1 0

[3,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 1 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 1
3 0 0 0 0 0 0 0 1 0
4 0 0 1 0 0 0 0 0 0
5 0 0 0 1 0 0 0 0 0
6 0 1 0 0 0 0 0 0 0
7 0 0 0 0 1 0 0 0 0
8 0 0 0 0 0 1 0 0 0
9 0 0 0 0 0 0 1 0 0

[4,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 0 0 0 0 0 0 0 1 0
2 0 0 0 0 1 0 0 0 0
3 0 0 0 0 0 0 0 0 1
4 0 0 0 0 0 0 1 0 0
5 0 0 0 0 0 1 0 0 0
6 1 0 0 0 0 0 0 0 0
7 0 0 0 1 0 0 0 0 0
8 0 1 0 0 0 0 0 0 0
9 0 0 1 0 0 0 0 0 0

[5,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 0 0 0 1 0 0 0 0 0
2 0 1 0 0 0 0 0 0 0
3 0 0 0 0 0 1 0 0 0
4 0 0 0 0 0 0 0 1 0
5 0 0 0 0 1 0 0 0 0
6 0 0 1 0 0 0 0 0 0
7 0 0 0 0 0 0 1 0 0
8 0 0 0 0 0 0 0 0 1
9 1 0 0 0 0 0 0 0 0

[6,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 0 0 0 0 0 0 1 0 0
2 1 0 0 0 0 0 0 0 0
3 0 0 1 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 1
5 0 1 0 0 0 0 0 0 0

4
6 0 0 0 1 0 0 0 0 0
7 0 0 0 0 0 0 0 1 0
8 0 0 0 0 1 0 0 0 0
9 0 0 0 0 0 1 0 0 0

[7,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 0 0 0 0 0 0 0 0 1
2 0 0 0 0 0 1 0 0 0
3 1 0 0 0 0 0 0 0 0
4 0 0 0 0 1 0 0 0 0
5 0 0 1 0 0 0 0 0 0
6 0 0 0 0 0 0 1 0 0
7 0 1 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 1 0
9 0 0 0 1 0 0 0 0 0

[8,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 0 1 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 1 0 0
4 0 0 0 1 0 0 0 0 0
5 1 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 1
7 0 0 0 0 0 1 0 0 0
8 0 0 1 0 0 0 0 0 0
9 0 0 0 0 1 0 0 0 0

[9,*,*]
: 1 2 3 4 5 6 7 8 9 :=
1 0 0 1 0 0 0 0 0 0
2 0 0 0 1 0 0 0 0 0
3 0 0 0 0 1 0 0 0 0
4 0 1 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 1 0
6 0 0 0 0 0 1 0 0 0
7 1 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 1 0 0
9 0 0 0 0 0 0 0 0 1
;

ampl:

Introduciendo en la tabla del sudoku dicha soluciòn obtenemos el siguiente resultado.

5 3 4 6 7 8 9 1 2
6 7 2 1 9 5 3 4 8
1 9 8 3 4 2 5 6 7
8 5 9 7 6 1 4 2 5
4 2 6 8 5 3 7 9 1
7 1 3 9 2 4 8 5 6
9 6 1 5 3 7 2 8 4
2 8 7 4 1 9 6 3 5
3 4 5 2 8 6 1 7 9

También podría gustarte