Llop_Sudoku - Paquete Llop_Circular_Doubly_Linked_List_2D
Llop Site Home > Visual Studio .NET > Sudoku > Llop_Circular_Doubly_Linked_List_2D
![]()
Clase NodoBase
public class NodoBase {
private NodoBase arriba;
private NodoBase abajo;
private NodoBase izquierda;
private NodoBase derecha;
public NodoBase() {}
public void setArriba(NodoBase nuevoArriba) { arriba = nuevoArriba; }
public void setAbajo(NodoBase nuevoAbajo) { abajo = nuevoAbajo; }
public void setIzquierda(NodoBase nuevaIzquierda) { izquierda = nuevaIzquierda; }
public void setDerecha(NodoBase nuevaDerecha) { derecha = nuevaDerecha; }
public NodoBase getArriba() { return arriba; }
public NodoBase getAbajo() { return abajo; }
public NodoBase getIzquierda() { return izquierda; }
public NodoBase getDerecha() { return derecha; }
public boolean equals(Object o) {
if (o != null && o.getClass().equals(this.getClass())) {
NodoBase n = (NodoBase)o;
return arriba == n.arriba && abajo == n.abajo && derecha == n.derecha && izquierda == n.izquierda;
}
return false;
}
}
Clase Nodo
public class Nodo extends NodoBase {
private Columna columna;
public Nodo() {}
public void setColumna(Columna nuevaColumna) { columna = nuevaColumna; }
public Columna getColumna() { return columna; }
public boolean equals(Object o) {
if (o != null && o.getClass().equals(this.getClass())) {
if(!super.equals(o)) return false;
Nodo n = (Nodo)o;
return columna == n.columna;
}
return false;
}
}
Clase Columna
public class Columna extends NodoBase {
private int tamano;
private int id;
public Columna() {}
public int getTamano() { return tamano; }
public int getId() { return id; }
public void setTamano(int nuevoTamano) { tamano = nuevoTamano; }
public void setId(int nuevoId) { id = nuevoId; }
public boolean equals(Object o) {
if (o != null && o.getClass().equals(this.getClass())) {
if(!super.equals(o)) return false;
Columna c = (Columna)o;
return tamano == c.tamano && id == c.id;
}
return false;
}
}
![]()
Clase Lista
import java.util.*;
public class Lista {
private int maximoSoluciones;
private int cuentaSoluciones;
private long cambios;
private ArrayList matrizSoluciones;
private NodoBase raiz;
private Columna[] columnas;
private Nodo[][] nodos;
private NodoBase[] solucion;
public Lista(boolean[][] matriz) {
maximoSoluciones = 300;
matrizSoluciones = new ArrayList();
columnas = new Columna[matriz[0].length];
nodos = new Nodo[matriz.length][matriz[0].length];
solucion = new NodoBase[matriz[0].length];
raiz = new NodoBase(); // Inicializar nodo raiz como si la
raiz.setDerecha(raiz); // circular doubly linked list estuviera
raiz.setIzquierda(raiz); // vacía (sin columnas).
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);
}
}
}
public boolean[][][] soluciona() {
matrizSoluciones.clear();
cambios = cuentaSoluciones = 0;
soluciona(0);
boolean[][][] retorno = new boolean[cuentaSoluciones][][];
for (int i = 0; i < cuentaSoluciones; i++)
retorno[i] = (boolean[][])matrizSoluciones.get(i);
return retorno;
}
private void soluciona(int profundidad) {
if (raiz.getDerecha() == raiz) { trataSolucion(profundidad); return; }
if (cuentaSoluciones >= maximoSoluciones) return;
Columna columna = buscaColumna();
quitaColumna(columna);
NodoBase nodo1, nodo2;
for (nodo1 = columna.getAbajo(); nodo1 != columna; nodo1 = nodo1.getAbajo()) {
solucion[profundidad] = nodo1;
for (nodo2 = nodo1.getDerecha(); nodo2 != nodo1; nodo2 = nodo2.getDerecha())
quitaColumna(((Nodo)nodo2).getColumna());
soluciona(profundidad + 1);
for (nodo2 = nodo1.getIzquierda(); nodo2 != nodo1; nodo2 = nodo2.getIzquierda())
restauraColumna(((Nodo)nodo2).getColumna());
}
restauraColumna(columna);
}
private void trataSolucion(int profundidad) {
boolean[][] sol = new boolean[profundidad][];
boolean[] filaSol;
NodoBase nodo1, nodo2;
for (int i = 0; i < profundidad; i++) {
filaSol = new boolean[nodos[0].length];
nodo1 = solucion[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;
}
matrizSoluciones.add(sol);
cuentaSoluciones++;
}
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++;
}
}
public void setMaximoSoluciones(int nuevoMaxSols) throws Exception {
if (nuevoMaxSols < 1 || nuevoMaxSols > 300)
throw new Exception ("Valor no permitido. El máximo de soluciones debe estar entre 1 y 300.");
maximoSoluciones = nuevoMaxSols;
}
public int getMaximoSoluciones() { return maximoSoluciones; }
public long getCambios() { return cambios; }
}
![]()
¿Comentarios, sugerencias?: llopsite.at.yahoo.es | © 2005-07 Albert Lobo
Última actualización: 24-Feb-2007