Beruflich Dokumente
Kultur Dokumente
Contenido
Estudio de la resolucin de diferentes configuraciones del 8-puzzle con diferentes heursticas .................. 2 8-Puzzle de 6 movimientos ..................................................................................................................... 2 8-Puzzle de 12 movimientos ................................................................................................................... 3 8-Puzzle de 18 movimientos ................................................................................................................... 4 Conclusiones de las pruebas de 8-puzzle .................................................................................................... 5 ALGORITMO DE PUZZLE EN JAVA ............................................................................................................... 6 CODIGO DEL 8-PUZZLE EN LISP ................................................................................................................. 12
Para llegar a estas conclusiones nos hemos basado en la resolucin de 3 tableros diferentes de 8-puzzle con una complejidad de 6, 12 y 18 movimientos. En todas ella se pretende llegar a la misma matriz solucin:
8-Puzzle de 6 movimientos
La primera matriz utilizada ha sido la siguiente (el 0 representa la casilla vaca):
Para resolver esta matriz de forma ptima se deben realizar 6 movimientos, los cuales son descritos a continuacin:
Para llegar a este resultado se han tenido que efectuar los 6 movimientos que acabamos de describir y que enumeramos a continuacin: Izquierda, Abajo, Izquierda, Abajo, Derecha, Arriba Todas las heursticas utilizadas llegan a una solucin optima, pero la diferencia principal radica en le cantidad de recursos que necesitan para resolver el problema. Vamos a mostrar las principales diferencias obtenidas en la resolucin del problema con las diferentes heursticas:
8-Puzzle de 12 movimientos
Para la prueba de 12 movimientos hemos utilizado la siguiente matriz:
Para este ejercicio y para el de 18 movimientos, no vamos a escribir las configuraciones de las matrices en la resolucin de este problema pues resultara muy tedioso, pero si que daremos una descripcin optima de los pasos a seguir. Una solucin ptima encontrada para la resolucin de esta matriz de forma ptima es: Arriba, Arriba, Derecha, Abajo, Izquierda, Abajo, Derecha, Arriba, Derecha, Arriba, Izquierda, Abajo. Si hacemos una comparacin entre las diferentes heursticas podremos comprobar que:
8-Puzzle de 18 movimientos
Para la prueba de 18 movimientos hemos utilizado la siguiente matriz:
Una solucin ptima encontrada para la resolucin de esta matriz de forma ptima es: Arriba, Izquierda, Abajo, Derecha, Arriba, Derecha, Abajo, Abajo, Izquierda, Arriba, Izquierda, Arriba, Derecha, Abajo, Derecha, Arriba, Izquierda, Abajo. Si hacemos una comparacin entre las diferentes heursticas podremos comprobar que:
*/
/* Si no es la primera fila, se mira a ver si el hueco est encima * de la pieza */ if (fila != 0) if (tablero[fila-1][columna] == HUECO) { /* Se hace el movimiento de la pieza a la fila superior */ mueve (fila, columna, fila-1, columna); return true; }
/* Si la fila no es la litma, se mira a ver si el hueco est en la * fila de abajo de la pieza */ if (fila != (numeroFilas -1)) if (tablero[fila+1][columna] == HUECO) { /* Se hace el movimiento hacia abajo */ mueve (fila, columna, fila+1, columna); return true; } /* Si la columna no es la de la izquierda, se mira a ver si el hueco * est a la izquierda de la pieza */ if (columna != 0) if (tablero[fila][columna-1] == HUECO) { /* Se hace el movimiento hacia la izquierda */ mueve (fila, columna, fila, columna-1); return true; } /* Si la columna no es la de la derecha del todo, se mira a ver si el * hueco est a la derecha de la pieza */ if (columna != (numeroColumnas-1)) if (tablero[fila][columna+1] == HUECO) { /* Se hace el movimiento hacia la derecha */ mueve (fila, columna, fila, columna+1); return true; } /* Si se llega hasta aqu, es que la pieza no tiene el hueco alrdedor y * por tanto no se puede mover */ return false; } /** * Devuelve la pieza que est en la fila, columna indicadas. -1 si * fila,columna est fuera del tablero. */ public int damePieza (int fila, int columna) { /* Si fila,columna no est dentro del tablero, se devuelve -1 */ if (!compruebaCoordenadas (fila, columna)) return -1; /* Se devuelve la pieza en fila,columna */ return tablero[fila][columna]; } /** * Aade el observador que se le pasa a la lista de observadores. */ public void anhadeObservador (ObservadorMovimiento nuevoObservador) { if (nuevoObservador != null) observadores.add (nuevoObservador); } /** * Se elimina el observador que se le pasa de la lista de observadores */ public void quitaObservador (ObservadorMovimiento unObservador) { if (unObservador != null) { observadores.remove (unObservador); }
} /** * Devuelve el nmero de filas del tablero */ public int dameFilas() { return numeroFilas; } /** * Devuelve el nmero de columnas del tablero */ public int dameColumnas() { return numeroColumnas; } /** * Devuelve el numero de piezas que se pueden mover. */ public int dameNumeroPosiblesMovimientos() { int numeroPosiblesMovimientos = 4; /* * * if Si el hueco est en la primera fila o en la ltima fila, hay un movimiento menos. No se puede mover la pieza desde fuera del tablero. */ ((this.filaHueco == 0) || (this.filaHueco == numeroFilas-1)) numeroPosiblesMovimientos--;
/* Idem si es primera o ltima columna */ if ((this.columnaHueco == 0) || (this.columnaHueco == numeroColumnas-1)) numeroPosiblesMovimientos--; return numeroPosiblesMovimientos; } /** * Devuelve un array con las posiciones de las piezas que se pueden mover. */ public Casilla[] damePosiblesMovimientos () { /* Array auxiliar para poner las posiciones de las piezas que se pueden * mover y devolverlo */ Casilla [] aux = new Casilla[dameNumeroPosiblesMovimientos()]; int i=0; /* Si el huecho no esta en la primera fila, se puede bajar la pieza que * est encima del hueco. */ if (this.filaHueco != 0) { aux[i] = new Casilla (this.filaHueco-1, this.columnaHueco); i++; } /* Si el hueco no est en la ltima fila, se puede subir la pieza que * est debajo del hueco. */ if (this.filaHueco != (numeroFilas -1)) { aux[i] = new Casilla (this.filaHueco+1, this.columnaHueco); i++; } /* si el hueco no est en la primera columna, se puede mover la pieza * que est a la izquierda del hueco. */
if (this.columnaHueco != 0) { aux[i] = new Casilla (this.filaHueco, this.columnaHueco-1); i++; } /* Si el hueco no est en la ltima columna, se puede mover la pieza * que est a la derecha del hueco */ if (this.columnaHueco != (numeroColumnas -1)) { aux[i] = new Casilla (this.filaHueco, this.columnaHueco+1); i++; } return aux; } /** * Devuelve true si el puzzle est ordenado. false en caso contrario. * * Se inicializa un contador con el valor de pieza 1, que debe estar en * la posicin 1,1. Se incrementa el contador y se pasa a la siguiente * casilla. Comparando el contador con el contenido de la casilla, se sabe * si el puzzle est ordenado. */ public boolean estaOrdenado() { /* Para recorrer el tablero */ int fila, columna; /* Para ver la pieza que toca en cada casilla */ int contador = 1; /* Bucle doble para cada fila y columna, recorriendo as todo el * tablero */ for (fila=0; fila < numeroFilas; fila++) for (columna=0; columna < numeroColumnas; columna++) { /* Tratamiento especial para el hueco en la ltima posicin * del tablero. Si hemos llegado hasta la ltima posicin del * tablero, todas las dems piezas estn en su sitio. La ltima * posicin estar ocupada por el hueco (el 0) y no por la pieza * nmero filas*columnas, que no existe. */ if (contador == numeroFilas*numeroColumnas) return true; /* Si la pieza no es la que debe, se devuelve false */ if (tablero[fila][columna] != contador) return false; /* Se pone en contador el valor de la siguiente pieza del * del puzzle */ contador++; } /* Si se llega hasta aqu, el puzzle est ordenado */ return true; } /** * Mueve una pieza al hueco. Presupone que los parmetros que se le pasan * son correctos y no los verifica. * Notifica del movimiento a los observadores de movimiento de piezas. * Verifica si el puzzle ya est ordenado para avisar a los observadores. */ private void mueve (int fila, int columna, int filaHueco, int columnaHueco) { /* Se realiza el movimiento */
tablero [filaHueco][columnaHueco] = tablero[fila][columna]; tablero [fila][columna] = HUECO; /* Se actuliazan las variables que mantienen la posicin actual del * hueco */ this.filaHueco=fila; this.columnaHueco=columna; /* Notifica del movimiento a los suscriptores de movimientos de pieza */ notificaMovimiento (fila, columna, filaHueco, columnaHueco); /* Verifica si est ordenado para notificar a los suscriptores de * tablero ordenado */ if (estaOrdenado()) notificaOrdenado(); } /** * Notifica a los suscriptores el movimiento de una pieza. */ private void notificaMovimiento ( int filaVieja, int columnaVieja, int filaNueva, int columnaNueva) { int i; /* Variable auxiliar para hacer el cast ms cmodo */ ObservadorMovimiento aux; /* Bucle para cada observador */ for (i=0; i<observadores.size(); i++) { aux =(ObservadorMovimiento)observadores.get(i); /* Se notifica el movimiento */ aux.tomaMovimiento ( filaVieja, columnaVieja, filaNueva, columnaNueva); } } /** * Notifica a los observadores que el puzzle est ordenado */ private void notificaOrdenado() { int i; /* Variable auxiliar para hacer ms cmodo el cast */ ObservadorMovimiento aux; /* Bucle para cada observador */ for (i=0; i<observadores.size(); i++) { aux =(ObservadorMovimiento)observadores.get(i); /* Se notifica que est ordenado */ aux.ordenado(); } } /** * Devuelve true si la fila,columna cae dentro del tablero. false en * caso contario */ private boolean compruebaCoordenadas (int fila, int columna) { // Si la fila, columna no es del tablero, se devuelve false y no se // hace nada. if ( (fila < 0) || (fila >= numeroFilas) || (columna < 0) || (columna >=numeroColumnas))
return false; return true; } /** Nmero de filas del puzzle. Por defecto 3 */ private int numeroFilas = 3; /** Nmero de columnas del puzzle. Por defecto 3 */ private int numeroColumnas = 3; /** Array bidimensional que representa el tablero. Las piezas sern enteros * 1, 2, 3, etc. El Hueco es el 0 */ private int [][] tablero; /* Fila en la que est el hueco */ private int filaHueco; /* Columna en la que est el hueco */ private int columnaHueco; /** Entero que representa el hueco en el puzzle */ static public final int HUECO=0; /** Lista de observadores */ private LinkedList observadores = new LinkedList(); }
(defun move-right(state) (let* ((at-space (find-square 'space state)) (i (first at-space)) (j (second at-space)) (new-state (copy-board state))) (when (< j 2) (setf (aref new-state i j) (aref new-state i (+ j 1))) (setf (aref new-state i (+ j 1)) 'space) new-state)))
(defun random-move(state) "randomly pick one of 4 operators. If it returns nil, choose again" (let ((r (random 4))) (or (cond ((= r 0)(move-left state)) ((= r 1) (move-right state)) ((= r 2) (move-up state)) ((= r 3) (move-down state))) (random-move state)))) (defun random-moves (n state) "make N random moves" (loop for i from 1 to n do (setq state (random-move state))) state) (defparameter *start-state* (random-moves 20 *goal-state*)) (defun solution-state?(state) "A state description is the solution if it matches the goal state" (equalp state *goal-state*)) (defparameter *eight-puzzle-operators* '(move-up move-down move-left move-right)) (defun estimated-distance-from-goal (board) "Compute Manhattan distance for each tile (except space)" (loop for i from 1 to 8 summing (manhattan-distance (find-square i board) (find-square i *goal-state*)))) (defun manhattan-distance (p1 p2) "given two lists of x-y coords, sum the difference between x's and y's" (+ (abs (- (first p1) (first p2))) (abs (- (second p1) (second p2))))) (defun cost-of-applying-operator (state operator) 1)