Llop_Sudoku - Paquete Llop_Sudoku_Java
Llop Site Home > Visual Studio .NET > Sudoku > Llop_Sudoku_Java
Clase Sudoku
import java.util.Date;
public class Sudoku {
// Constantes para definir el problema del sudoku.
public static final int CUATRO_X_CUATRO = 0;
public static final int SEIS_X_SEIS = 1;
public static final int NUEVE_X_NUEVE = 2;
public static final int DOCE_X_DOCE = 3;
public static final int DIECISEIS_X_DIECISEIS = 4;
public static final int[][] TABLA_RANGOS = {{4, 6}, {9, 12}, {24, 40}, {50, 72}, {96, 124}};
// El generador y el solucionador.
private Generador generador;
private Solucionador solucionador;
// Variables para representar el problema y la solución.
private int[] rangoPistas;
private int[][] problema;
private Solucion solucion;
// Variables que representan las diferentes dimensiones del sudoku.
protected int numeroCasillas;
protected int numeroCasillasRegion;
protected int numeroRegiones;
protected int numeroFilas;
protected int numeroColumnas;
protected int numeroFilasRegion;
protected int numeroColumnasRegion;
// Poner en true para sacar mensajes de seguimiento de las principales funciones de la clase.
private boolean depurar;
public Sudoku(int numFil, int numCol, int numFilReg, int numColReg) throws Exception {
depurar = false;
depura("--- Constructor Sudoku " + numFil + "x" + numCol + " ---");
long t1 = new Date().getTime();
if (numFil % numFilReg != 0 || numCol % numColReg != 0)
throw new Exception("Imposible crear un sudoku de estas dimensiones. Las regiones no caben bien en la cuadrícula.");
numeroFilas = numFil;
numeroColumnas = numCol;
numeroFilasRegion = numFilReg;
numeroColumnasRegion = numColReg;
numeroCasillas = numFil * numCol;
numeroCasillasRegion = numFilReg * numColReg;
numeroRegiones = (numFil / numFilReg) * (numCol / numColReg);
switch(numeroCasillas) {
case 16: rangoPistas = TABLA_RANGOS[CUATRO_X_CUATRO]; break;
case 36: rangoPistas = TABLA_RANGOS[SEIS_X_SEIS]; break;
case 81: rangoPistas = TABLA_RANGOS[NUEVE_X_NUEVE]; break;
case 144: rangoPistas = TABLA_RANGOS[DOCE_X_DOCE]; break;
case 256: rangoPistas = TABLA_RANGOS[DIECISEIS_X_DIECISEIS]; break;
default: throw new Exception("El tamaño del sudoku no está permitido.");
}
generador = new Generador(this);
solucionador = new Solucionador(this);
depura("Instancia de Sudoku " + numFil + "x" + numCol + " creada en " + (new Date().getTime() - t1) + " ms.");
}
private void depura(String mensaje) { if (depurar) System.out.println(mensaje); }
public Problema generaProblema() throws Exception {
long t1 = new Date().getTime();
Problema problema = generador.genera();
depura("Generación sudoku: " + (new Date().getTime() - t1) + " ms.");
return problema;
}
private void resuelveProblema() throws Exception {
long t1 = new Date().getTime();
solucion = solucionador.resuelveProblema(problema);
depura("Solución sudoku: " + (new Date().getTime() - t1) + " ms.");
}
public void setNumeroPistas(int nuevoNumeroPistas) throws Exception {
if (nuevoNumeroPistas < rangoPistas[0] || nuevoNumeroPistas > rangoPistas[1])
throw new Exception("Número de pistas fuera de rango.");
generador.setNumeroPistas(nuevoNumeroPistas);
}
public void setProblema(Problema nuevoProblema) throws Exception {
setProblema(nuevoProblema.getProblema());
}
public void setProblema(int[][] nuevoProblema) throws Exception {
if (nuevoProblema.length != numeroFilas || nuevoProblema[0].length != numeroColumnas)
throw new Exception("El problema no respeta las dimensiones de este sudoku.");
for (int i = 0; i < numeroFilas; i++) for (int j = 0; j < numeroColumnas; j++)
if (nuevoProblema[i][j] < 0 || nuevoProblema[i][j] > numeroCasillasRegion)
throw new Exception("El valor de fila " + i + ", columna " + j + " no es válido.");
problema = nuevoProblema;
solucion = null;
}
public void setMaximoSoluciones(int nuevoMaxSols) throws Exception {
solucionador.setMaximoSoluciones(nuevoMaxSols);
}
public Solucion getSolucion() throws Exception {
if (problema == null) throw new Exception("Todavía no se ha establecido el problema.");
if (solucion == null) resuelveProblema();
return solucion;
}
public int getNumeroPistas() { return generador.getNumeroPistas(); }
public int getMaximoSoluciones() { return solucionador.getMaximoSoluciones(); }
public int getNumeroCasillas() { return numeroCasillas; }
public int getNumeroCasillasRegion() { return numeroCasillasRegion; }
public int getNumeroRegiones() { return numeroRegiones; }
public int getNumeroFilas() { return numeroFilas; }
public int getNumeroColumnas() { return numeroColumnas; }
public int getNumeroFilasRegion() { return numeroFilasRegion; }
public int getNumeroColumnasRegion() { return numeroColumnasRegion; }
public int[] getRangoPistas() { return rangoPistas; }
public static int[] getRangoPistasPorDimension(int dimension) { return TABLA_RANGOS[dimension]; }
}
Clase Problema
public class Problema {
private int[][] problema;
private long tiempoGeneracion;
private long cambios;
public Problema(int[][] nuevoProblema, long nuevoTiempoGeneracion, long nuevoCambios) {
problema = nuevoProblema;
tiempoGeneracion = nuevoTiempoGeneracion;
cambios = nuevoCambios;
}
public int[][] getProblema() { return problema; }
public long getTiempoGeneracion() { return tiempoGeneracion; }
public long getCambios() { return cambios; }
}
Clase Solucion
public class Solucion {
private int[][][] soluciones;
private int numeroSoluciones;
private long tiempoSolucion;
private long cambios;
public Solucion(int[][][] nuevoSoluciones, long nuevoTiempoSolucion, long nuevoCambios) {
soluciones = nuevoSoluciones;
numeroSoluciones = soluciones.length;
tiempoSolucion = nuevoTiempoSolucion;
cambios = nuevoCambios;
}
public int[][] getSolucion(int numeroSolucion) throws Exception {
if (numeroSolucion < 0 || numeroSolucion > soluciones.length - 1)
throw new Exception("'numeroSolucion' no es un índice válido.");
return soluciones[numeroSolucion];
}
public int getNumeroSoluciones() { return numeroSoluciones; }
public long getTiempoSolucion() { return tiempoSolucion; }
public long getCambios() { return cambios; }
}
![]()
Clase Generador
import Llop_Circular_Doubly_Linked_List_2D.*;
import java.util.Date;
import java.util.Random;
public class Generador {
// Variables del sudoku.
private int numeroFilasSudoku;
private int numeroColumnasSudoku;
private int numeroFilasRegionSudoku;
private int numeroColumnasRegionSudoku;
private int numeroRegionesSudoku;
private int numeroCasillasRegionSudoku;
private int numeroCasillasSudoku;
private int offsetCasillaSudoku;
private int offsetColumnaSudoku;
private int offsetRegionSudoku;
// Variables de control.
private int numeroPistas;
private int cuentaPistas;
private int cuentaSoluciones;
private boolean solucionConseguida;
private long cambios;
private int contadorBusqueda;
private float frecuenciaAleatorias;
// Poner en true para sacar mensajes de seguimiento de las principales funciones de la clase.
private boolean depurar;
// Variables para almacenar el problema.
private NodoBase[] problemaTemp;
private int[][] problema;
private int[][] problemaMaster;
// Variables que representan la circular doubly linked list.
private boolean[][] matriz;
private int[][][][] patron;
private NodoBase raiz;
private Columna[] columnas;
private Nodo[][] nodos;
public Generador(Sudoku sudoku) throws Exception {
depurar = false;
depura("--- Constructor Generador ---");
long t1 = new Date().getTime();
numeroFilasSudoku = sudoku.getNumeroFilas();
numeroColumnasSudoku = sudoku.getNumeroColumnas();
numeroRegionesSudoku = sudoku.getNumeroRegiones();
numeroCasillasSudoku = sudoku.getNumeroCasillas();
numeroCasillasRegionSudoku = sudoku.getNumeroCasillasRegion();
numeroFilasRegionSudoku = sudoku.getNumeroFilasRegion();
numeroColumnasRegionSudoku = sudoku.getNumeroColumnasRegion();
offsetColumnaSudoku = numeroCasillasRegionSudoku * numeroFilasSudoku;
offsetRegionSudoku = offsetColumnaSudoku + numeroCasillasRegionSudoku * numeroColumnasSudoku;
offsetCasillaSudoku = offsetRegionSudoku + numeroCasillasRegionSudoku * numeroRegionesSudoku;
numeroPistas = sudoku.getRangoPistas()[0];
int numeroFilasMatriz = numeroCasillasRegionSudoku * numeroCasillasSudoku;
int numeroColumnasMatriz = offsetCasillaSudoku + numeroCasillasSudoku;
if (numeroCasillasSudoku == 256) frecuenciaAleatorias = 9;
else if (numeroCasillasSudoku == 144) frecuenciaAleatorias = 3.5f;
else frecuenciaAleatorias = 2.5f;
int valor = 0, fila = 0, columna = 0, region = 0, casilla = 0;
int restriccionFila, restriccionColumna, restriccionRegion, restriccionCasilla;
matriz = new boolean[numeroFilasMatriz][numeroColumnasMatriz];
patron = new int[numeroFilasSudoku][numeroColumnasSudoku][numeroCasillasRegionSudoku][4];
for (int i = 0; i < numeroFilasMatriz; i++) {
restriccionFila = numeroColumnasSudoku * fila + valor;
restriccionColumna = offsetColumnaSudoku + numeroFilasSudoku * columna + valor;
restriccionRegion = offsetRegionSudoku + numeroRegionesSudoku * region + valor;
restriccionCasilla = offsetCasillaSudoku + casilla;
matriz[i][restriccionFila] = true;
matriz[i][restriccionColumna] = true;
matriz[i][restriccionRegion] = true;
matriz[i][restriccionCasilla] = true;
patron[fila][columna][valor][0] = restriccionFila;
patron[fila][columna][valor][1] = restriccionColumna;
patron[fila][columna][valor][2] = restriccionRegion;
patron[fila][columna][valor][3] = restriccionCasilla;
columna++;
casilla++;
if (casilla % numeroCasillasSudoku == 0) casilla = 0;
if ((i + 1) % numeroCasillasSudoku == 0) valor++;
if (columna % numeroColumnasSudoku == 0) { columna = 0; fila++; }
if (fila % numeroFilasSudoku == 0) fila = 0;
region = (fila / numeroFilasRegionSudoku) * numeroFilasRegionSudoku + columna / numeroColumnasRegionSudoku;
}
raiz = new NodoBase();
columnas = new Columna[matriz[0].length];
nodos = new Nodo[matriz.length][matriz[0].length];
problemaTemp = new NodoBase[numeroCasillasSudoku];
problemaMaster = new int[numeroFilasSudoku][numeroColumnasSudoku];
raiz.setDerecha(raiz);
raiz.setIzquierda(raiz);
inicializaTabla();
depura("Instancia de Generador creada en " + (new Date().getTime() - t1) + " ms.");
}
private void inicializaTabla() {
int i, j, k;
for (i = 0; i < matriz.length; i++) {
for (j = 0; j < matriz[i].length; j++) {
if (matriz[i][j]) {
if (nodos[i][j] == null) nodos[i][j] = new Nodo();
for (k = j + 1; k != j; k++) {
if (k == matriz[i].length) k = 0;
if (matriz[i][k]) { if (nodos[i][k] == null) nodos[i][k] = new Nodo(); break; }
}
nodos[i][j].setDerecha(nodos[i][k]);
for (k = j - 1; k != j; k--) {
if (k == -1) k = matriz[i].length - 1;
if (matriz[i][k]) { if (nodos[i][k] == null) nodos[i][k] = new Nodo(); break; }
}
nodos[i][j].setIzquierda(nodos[i][k]);
for (k = i + 1; k != i; k++) {
if (k == matriz.length) {
if (columnas[j] == null) { columnas[j] = new Columna(); columnas[j].setId(j); }
nodos[i][j].setAbajo(columnas[j]); break;
}
if (matriz[k][j]) {
if (nodos[k][j] == null) nodos[k][j] = new Nodo();
nodos[i][j].setAbajo(nodos[k][j]); break;
}
}
for (k = i - 1; k != i; k--) {
if (k == -1) {
if (columnas[j] == null) { columnas[j] = new Columna(); columnas[j].setId(j); } nodos[i][j].setArriba(columnas[j]);
break;
}
if (matriz[k][j]) {
if (nodos[k][j] == null) nodos[k][j] = new Nodo();
nodos[i][j].setArriba(nodos[k][j]); break;
}
}
if (columnas[j] == null) { columnas[j] = new Columna(); columnas[j].setId(j); }
nodos[i][j].setColumna(columnas[j]);
}
}
}
for (j = 0; j < columnas.length; j++) {
if (columnas[j] != null) {
for (k = j + 1; k != j; k++) {
if (k == columnas.length) {
columnas[j].setDerecha(raiz);
raiz.setIzquierda(columnas[j]);
break;
}
if (columnas[k] != null) { columnas[j].setDerecha(columnas[k]); break; }
}
for (k = j - 1; k != j; k--) {
if (k == -1) {
columnas[j].setIzquierda(raiz);
raiz.setDerecha(columnas[j]);
break;
}
if (columnas[k] != null) { columnas[j].setIzquierda(columnas[k]); break; }
}
for (k = 0; ; k++) {
if (k == matriz.length) { columnas[j].setAbajo(columnas[j]); break; }
if (matriz[k][j]) { columnas[j].setAbajo(nodos[k][j]); break; }
}
for (k = matriz.length - 1; ; k--) {
if (k == -1) { columnas[j].setArriba(columnas[j]); break; }
if (matriz[k][j]) { columnas[j].setArriba(nodos[k][j]); break; }
}
for (i = k = 0; k < matriz.length; k++) if (matriz[k][j]) i++;
columnas[j].setTamano(i);
}
}
}
private void depura(String mensaje) { if (depurar) System.out.println(mensaje); }
public Problema genera() {
problema = new int[numeroFilasSudoku][numeroColumnasSudoku];
long t1 = new Date().getTime(), t2 = t1;
inventaSolucion();
depura("Inventa solución: " + (new Date().getTime() - t2) + " ms.");
t2 = new Date().getTime();
while (!generaProblema()) { restauraProblema(); }
depura("Genera problema: " + (new Date().getTime() - t2) + " ms.");
return new Problema(problema, new Date().getTime() - t1, cambios);
}
private void inventaSolucion() {
solucionConseguida = false;
inventaSolucion(0);
}
private void inventaSolucion(int profundidad) {
if (solucionConseguida) return;
if (raiz.getDerecha() == raiz) { trataSolucion(); return; }
Columna columna = buscaColumnaRandom();
quitaColumna(columna);
NodoBase nodo1, nodo2;
for (nodo1 = columna.getAbajo(); nodo1 != columna; nodo1 = nodo1.getAbajo()) {
problemaTemp[profundidad] = nodo1;
for (nodo2 = nodo1.getDerecha(); nodo2 != nodo1; nodo2 = nodo2.getDerecha())
quitaColumna(((Nodo)nodo2).getColumna());
inventaSolucion(profundidad + 1);
for (nodo2 = nodo1.getIzquierda(); nodo2 != nodo1; nodo2 = nodo2.getIzquierda())
restauraColumna(((Nodo)nodo2).getColumna());
}
restauraColumna(columna);
}
private void trataSolucion() {
solucionConseguida = true;
boolean[][] sol = new boolean[problemaTemp.length][];
boolean[] filaSol;
int i, j, valor, casilla, fila, columna;
NodoBase nodo1, nodo2;
for (i = 0; i < problemaTemp.length; i++) {
filaSol = new boolean[nodos[0].length];
nodo1 = problemaTemp[i];
filaSol[((Nodo)nodo1).getColumna().getId()] = true;
for (nodo2 = nodo1.getDerecha(); nodo2 != nodo1; nodo2 = nodo2.getDerecha())
filaSol[((Nodo)nodo2).getColumna().getId()] = true;
sol[i] = filaSol;
}
for (i = 0; i < sol.length; i++){
for (j = 0; !sol[i][j]; j++) {}
valor = j % numeroColumnasSudoku + 1;
for (j = sol[i].length - 1; !sol[i][j]; j--) {}
casilla = j - offsetCasillaSudoku;
fila = casilla / numeroColumnasSudoku;
columna = casilla % numeroColumnasSudoku;
problemaMaster[fila][columna] = problema[fila][columna] = valor;
}
}
private boolean generaProblema() {
cuentaPistas = problemaTemp.length;
Random random = new Random();
int i, filaRnd, columnaRnd, repes = 0;
for (i = 0; i < problemaTemp.length; i++) {
do {
filaRnd = random.nextInt(numeroFilasSudoku);
columnaRnd = random.nextInt(numeroColumnasSudoku);
} while (problema[filaRnd][columnaRnd] == 0);
problema[filaRnd][columnaRnd] = 0;
cuentaPistas--;
solucionaRapido();
if (cuentaSoluciones == 1 && cuentaPistas == numeroPistas) return true;
else if (cuentaSoluciones == 2) {
problema[filaRnd][columnaRnd] = problemaMaster[filaRnd][columnaRnd];
cuentaPistas++; repes++; i --;
}
if (repes == problemaTemp.length - cuentaPistas) break;
}
return false;
}
private int iSR;
private int jSR;
private int kSR;
private int[] filaPatron;
private void solucionaRapido() {
cambios = cuentaSoluciones = 0;
for (iSR = 0; iSR < problema.length; iSR++) for (jSR = 0; jSR < problema[0].length; jSR++)
if (problema[iSR][jSR] > 0) {
filaPatron = patron[iSR][jSR][problema[iSR][jSR] - 1];
for (kSR = 0; kSR < 4; kSR++) quitaColumna(filaPatron[kSR]);
}
soluciona();
for (iSR = problema.length - 1; iSR >= 0 ; iSR--) for (jSR = problema[0].length - 1; jSR >= 0; jSR--)
if (problema[iSR][jSR] > 0) {
filaPatron = patron[iSR][jSR][problema[iSR][jSR] - 1];
for (kSR = 3; kSR >= 0; kSR--) restauraColumna(filaPatron[kSR]);
}
}
private void soluciona() {
if (cuentaSoluciones >= 2) return;
if (raiz.getDerecha() == raiz) { cuentaSoluciones++; return; }
Columna columna = buscaColumna();
quitaColumna(columna);
NodoBase nodo1, nodo2;
for (nodo1 = columna.getAbajo(); nodo1 != columna; nodo1 = nodo1.getAbajo()) {
for (nodo2 = nodo1.getDerecha(); nodo2 != nodo1; nodo2 = nodo2.getDerecha())
quitaColumna(((Nodo)nodo2).getColumna());
soluciona();
for (nodo2 = nodo1.getIzquierda(); nodo2 != nodo1; nodo2 = nodo2.getIzquierda())
restauraColumna(((Nodo)nodo2).getColumna());
}
restauraColumna(columna);
}
private Columna buscaColumnaRandom() {
if (contadorBusqueda++ % frecuenciaAleatorias != 0) return buscaColumna();
int random = new Random().nextInt(nodos[0].length);
NodoBase nodo = raiz.getDerecha();
for (int i = 0; i <= random; i++) nodo = nodo.getDerecha();
if (nodo == raiz) nodo = nodo.getDerecha();
return (Columna)nodo;
}
private Columna buscaColumna() {
int tamano = nodos.length;
Columna columna = null;
for (NodoBase nodo = raiz.getDerecha(); nodo != raiz; nodo = nodo.getDerecha())
if (((Columna)nodo).getTamano() < tamano) {
columna = (Columna)nodo;
tamano = columna.getTamano();
}
return columna;
}
public void restauraColumna(int indiceColumna) { restauraColumna(columnas[indiceColumna]); }
private void restauraColumna(Columna columna) {
NodoBase nodo1, nodo2;
for (nodo1 = columna.getArriba(); nodo1 != columna; nodo1 = nodo1.getArriba())
for (nodo2 = nodo1.getIzquierda(); nodo2 != nodo1; nodo2 = nodo2.getIzquierda()) {
((Nodo)nodo2).getColumna().setTamano(((Nodo)nodo2).getColumna().getTamano() + 1);
nodo2.getAbajo().setArriba(nodo2);
nodo2.getArriba().setAbajo(nodo2);
cambios++;
}
columna.getDerecha().setIzquierda(columna);
columna.getIzquierda().setDerecha(columna);
cambios++;
}
public void quitaColumna(int indiceColumna) { quitaColumna(columnas[indiceColumna]); }
private void quitaColumna(Columna columna) {
NodoBase nodo1, nodo2;
columna.getDerecha().setIzquierda(columna.getIzquierda());
columna.getIzquierda().setDerecha(columna.getDerecha());
cambios++;
for (nodo1 = columna.getAbajo(); nodo1 != columna; nodo1 = nodo1.getAbajo())
for (nodo2 = nodo1.getDerecha(); nodo2 != nodo1; nodo2 = nodo2.getDerecha()) {
nodo2.getAbajo().setArriba(nodo2.getArriba());
nodo2.getArriba().setAbajo(nodo2.getAbajo());
((Nodo)nodo2).getColumna().setTamano(((Nodo)nodo2).getColumna().getTamano() - 1);
cambios++;
}
}
private void restauraProblema() {
for (int i = 0; i < problema.length; i++) for (int j = 0; j < problema[i].length; j++)
if (problema[i][j] == 0) problema[i][j] = problemaMaster[i][j];
}
public long getCambios() { return cambios; }
public int getNumeroPistas() { return numeroPistas; }
public void setNumeroPistas(int nuevoNumeroPistas) { numeroPistas = nuevoNumeroPistas; }
}
![]()
Clase Solucionador
import Llop_Circular_Doubly_Linked_List_2D.Lista;
import java.util.Date;
public class Solucionador {
// Variables del sudoku.
private int numeroFilasSudoku;
private int numeroColumnasSudoku;
private int numeroFilasRegionSudoku;
private int numeroColumnasRegionSudoku;
private int numeroRegionesSudoku;
private int numeroCasillasRegionSudoku;
private int numeroCasillasSudoku;
private int offsetCasillaSudoku;
private int offsetColumnaSudoku;
private int offsetRegionSudoku;
// Poner en true para sacar mensajes de seguimiento de las principales funciones de la clase.
private boolean depurar;
// Variables circular doubly linked list
private Lista lista;
private int[][][][] patron;
public Solucionador(Sudoku sudoku) {
depurar = false;
depura("--- Constructor Solucionador ---");
long t1 = new Date().getTime();
numeroFilasSudoku = sudoku.getNumeroFilas();
numeroColumnasSudoku = sudoku.getNumeroColumnas();
numeroRegionesSudoku = sudoku.getNumeroRegiones();
numeroCasillasSudoku = sudoku.getNumeroCasillas();
numeroCasillasRegionSudoku = sudoku.getNumeroCasillasRegion();
numeroFilasRegionSudoku = sudoku.getNumeroFilasRegion();
numeroColumnasRegionSudoku = sudoku.getNumeroColumnasRegion();
offsetColumnaSudoku = numeroCasillasRegionSudoku * numeroFilasSudoku;
offsetRegionSudoku = offsetColumnaSudoku + numeroCasillasRegionSudoku * numeroColumnasSudoku;
offsetCasillaSudoku = offsetRegionSudoku + numeroCasillasRegionSudoku * numeroRegionesSudoku;
inicializaLista();
depura("Instancia de Solucionador creada en " + (new Date().getTime() - t1) + " ms.");
}
private void inicializaLista() {
int valor = 0, fila = 0, columna = 0, region = 0, casilla = 0;
int restriccionFila, restriccionColumna, restriccionRegion, restriccionCasilla;
int numeroFilasMatriz = numeroCasillasRegionSudoku * numeroCasillasSudoku;
int numeroColumnasMatriz = offsetCasillaSudoku + numeroCasillasSudoku;
boolean[][] matriz = new boolean[numeroFilasMatriz][numeroColumnasMatriz];
patron = new int[numeroFilasSudoku][numeroColumnasSudoku][numeroCasillasRegionSudoku][4];
for (int i = 0; i < numeroFilasMatriz; i++) {
restriccionFila = numeroColumnasSudoku * fila + valor;
restriccionColumna = offsetColumnaSudoku + numeroFilasSudoku * columna + valor;
restriccionRegion = offsetRegionSudoku + numeroRegionesSudoku * region + valor;
restriccionCasilla = offsetCasillaSudoku + casilla;
matriz[i][restriccionFila] = true;
matriz[i][restriccionColumna] = true;
matriz[i][restriccionRegion] = true;
matriz[i][restriccionCasilla] = true;
patron[fila][columna][valor][0] = restriccionFila;
patron[fila][columna][valor][1] = restriccionColumna;
patron[fila][columna][valor][2] = restriccionRegion;
patron[fila][columna][valor][3] = restriccionCasilla;
columna++;
casilla++;
if (casilla % numeroCasillasSudoku == 0) casilla = 0;
if ((i + 1) % numeroCasillasSudoku == 0) valor++;
if (columna % numeroColumnasSudoku == 0) { columna = 0; fila++; }
if (fila % numeroFilasSudoku == 0) fila = 0;
region = (fila / numeroFilasRegionSudoku) * numeroFilasRegionSudoku + columna / numeroColumnasRegionSudoku;
}
lista = new Lista(matriz);
}
private void depura(String mensaje) { if (depurar) System.out.println(mensaje); }
public Solucion resuelveProblema(int[][] problema) throws Exception {
if (problema == null) throw new Exception("No se ha establecido el problema en este sudoku.");
long t1 = new Date().getTime();
int i, j, k, valor, casilla, fila, columna;
for (i = 0; i < problema.length; i++) for (j = 0; j < problema[0].length; j++)
if (problema[i][j] > 0)
for (k = 0; k < 4; k++)
lista.quitaColumna(patron[i][j][problema[i][j] - 1][k]);
boolean[][][] sols = lista.soluciona();
for (i = problema.length - 1; i >= 0 ; i--) for (j = problema[0].length - 1; j >= 0; j--)
if (problema[i][j] > 0)
for (k = 3; k >= 0; k--)
lista.restauraColumna(patron[i][j][problema[i][j] - 1][k]);
int[][][] soluciones = new int[sols.length][numeroFilasSudoku][numeroColumnasSudoku];
for (i = 0; i < sols.length; i++) {
for (j = 0; j < problema.length; j++) for (k = 0; k < problema[j].length; k++)
if (problema[j][k] != 0) soluciones[i][j][k] = problema[j][k];
for (j = 0; j < sols[i].length; j++) {
for (k = 0; !sols[i][j][k]; k++) {}
valor = k % numeroColumnasSudoku + 1;
for (k = sols[i][j].length - 1; !sols[i][j][k]; k--) {}
casilla = k - offsetCasillaSudoku;
fila = casilla / numeroColumnasSudoku;
columna = casilla % numeroColumnasSudoku;
soluciones[i][fila][columna] = valor;
}
}
depura("Tiempo solución: " + (new Date().getTime() - t1) + " ms");
depura("Numero cambios solución: " + lista.getCambios());
depura("Numero soluciones: " + sols.length);
return new Solucion(soluciones, new Date().getTime() - t1, lista.getCambios());
}
public void setMaximoSoluciones(int nuevoMaxSols) throws Exception {
lista.setMaximoSoluciones(nuevoMaxSols);
}
public int getMaximoSoluciones() { return lista.getMaximoSoluciones(); }
}
![]()
¿Comentarios, sugerencias?: llopsite.at.yahoo.es | © 2005-07 Albert Lobo
Última actualización: 18-Feb-2007