Anda di halaman 1dari 8

Proyecto de Algoritmos Avanzados:

El laberinto con ramificacin y poda

Alumnos: Juan Antonio Sopale Thompson Jorge Colmenar Casas Vctor Puerta Rodriguez

ndice de contenido
Objetivos del trabajo.............................................................................................................................3 Descripcin del trabajo realizado.........................................................................................................3 Algoritmo codificado y decisiones de diseo.......................................................................................3 Anlisis de la complejidad....................................................................................................................6 Conclusiones.........................................................................................................................................7 Bibliografa...........................................................................................................................................8

2 de 8

OBJETIVOS DEL TRABAJO


La intencin de este trabajo ser ahondar en la codificacin del algoritmo para recorrer un laberinto hasta llegar a la meta correspondiente. La peculiaridad de nuestro trabajo es que adems de buscar una solucin tratamos de encontrar la solucin cuyo camino sea el mnimo posible hasta la meta. Para ello usaremos la tcnica de ramificacin y poda con cotas para buscar la solucin ptima a nuestro problema.

DESCRIPCIN DEL TRABAJO REALIZADO


Descrito ya el objetivo del trabajo procederemos con la descripcin del trabajo realizado.. Primeramente, hemos analizado el problema del laberinto, y como encontrar una solucin vlida al problema. Una vez analizado, procedemos a buscar cual es la estructura de datos que vamos a usar para representar el laberinto. Ya con la estructura elegida, evaluamos las restricciones del problema (movimientos en el laberinto, muros, lmites del laberinto y casillas ya transitadas) y las adaptamos a nuestra estructura. Entonces tenemos ya todas las caractersticas del laberinto representadas y procedemos a evaluar y aplicar la ramificacin y poda al laberinto.

ALGORITMO CODIFICADO Y DECISIONES DE DISEO


Decisin de diseo: Tabla:

3 de 8

La tabla tiene dimensiones NxM, por tanto el nmero de casillas es N*M. En nuestro caso usaremos un laberinto cuyo nmero de filas y nmero de columnas tienen valores independientes, es decir, N y M no tienen porque ser iguales. El contenido de la tabla, las casillas, pueden ser de tres tipos: Con valor igual a 0: Se corresponde con una casilla del laberinto vaca. Con valor igual a -1: Se corresponde con un un muro del laberinto. Con valor igual a un nmero natural (que no sea 0): Se corresponde con una casilla del laberinto que ya ha sido transitada y que antes de ser transitada tena valor igual a 0. El valor de la casilla es igual al nmero de pasos que llevemos dados en el laberinto. Una vez tenemos el laberinto representado en una matriz, la serie de movimientos que podemos efectuar son: Ir hacia la derecha, hacia abajo, hacia la izquierda y hacia arriba. Cada uno de estos movimientos son vlidos siempre y cuando la casilla a la que nos desplazamos tenga valor 0. Para los desplazamientos usaremos dos vectores: Vector que incrementa la coordenada x Vector que incrementa la coordenada y Ambos vectores tienen un tamao de 4 elementos debido a que slo tenemos 4 movimientos posibles. Nuestra posicin actual est definida por un x y un y determinados. Cuando nos movamos, a esa posicin actual le sumamos Vx(i) y Vy(i), donde Vx y Vy son los vectores de incremento de la coordenada x y la coordenada y respectivamente, e i es el movimiento que se realiza (i: con valor 0 derecha, con valor 1 abajo, con valor 2 izquierda y con valor 3 arriba). Respecto a las cotas hacemos uso de la cota superior. Inicialmente la cota superior es el total de casillas que componen el laberinto. Conforme vamos obteniendo soluciones actualizamos el valor de la cota a una mejor solucin. De ese modo al tener una cota mejor estimada nos permite ahorrarnos soluciones peores.

Algoritmo codificado:
public class Laberinto { private boolean encontrado = false; //si encuentra una solucin 'encontrado'=true private int cota; //nos indica el nmero de pasos mnimos posibles hasta el momento private final int MURO = -1; //el muro est indicado en el laberinto como -1 private int laberinto[][]; //matriz que representa el laberinto private int solucion [][]; //matriz con la solucin del laberinto private int dim1; //nmero de columnas private int dim2; //nmero de filas public Laberinto(int dim1, int dim2) { //este constructor inicializa el laberinto this.dim1 = dim1; this.dim2 = dim2; cota = dim1*dim2; //inicializamos la cota a un valor igual al nmero de casillas del laberinto. laberinto = new int[dim1][dim2]; //asignamos dimensiones al laberinto. for (int i = 0; i < dim1; i++) { for (int j = 0; j < dim2; j++) { laberinto[i][j] = 0; } } }

4 de 8

public void ponerMuro(int x, int y) { //esta funcin nos permite poner los muros que queramos. laberinto[x][y] = MURO; } public boolean resolver () { int nodo[] = new int[2];//nodo actual con 2 elementos la x y la y. //Las dos siguientes variables permiten los movimientos hacia derecha con incrX(0) e incrY(0), //hacia abajo con incrX(1) e incrY(1), hacia la izquierda con incrX(2) e incrY(2) y hacia arriba //con incrX(3) e incrY(3) int[] incrX = {1, 0, -1, 0}; int[] incrY = {0, 1, 0, -1}; //Nos siuamos en la posicin incial 0,0 del laberinto: laberinto[0][0] = 1; nodo[0] = 0; nodo[1] = 0; solucion = new int[dim1][dim2]; //Matriz en la que tendremos la solucin del laberinto expandir(solucion, laberinto, nodo, dim1, dim2, incrX, incrY, 1); if (encontrado) { //Si hay solucin vlida imprimimos la solucin for (int i = 0; i < dim2; i++) { for (int j = 0; j < dim1; j++) { System.out.print(solucion[j][i] + "\t"); } System.out.println(); } return true; } else { // Si no imprimimos que no hemos encontrado solucin System.out.println("No se ha encontrado solucion"); return false; } } private void expandir(int[][] solucion, int laberinto[][], int[] nodo, int dim1, int dim2, int[] incrX, int[] incrY, int pasos) { int[] nodoAux = new int[2]; for (int i = 0; i < incrX.length; i++) { //Nos desplazamos en una direccin (derecha o izquierda o arriba o abajo) nodoAux[0] = nodo[0] + incrX[i]; nodoAux[1] = nodo[1] + incrY[i]; if (((nodoAux[0] >= 0) && (nodoAux[0] < dim1)) && ((nodoAux[1] >= 0) && (nodoAux[1] < dim2))) {//si estan dentro del rango del laberinto. if ((laberinto[nodoAux[0]][nodoAux[1]] == 0) && (pasos < cota)) { //si no estamos en un muro o casilla ocupada y no superamos la cota: laberinto[nodoAux[0]][nodoAux[1]] = pasos + 1; pasos++; if ((nodoAux[0] == dim1 - 1) && (nodoAux[1] == dim2 - 1)) {//si estamos en la meta: encontrado = true; cota = pasos - 1; //actualizamos la cota. //copiamos solucin vlida en el vector solucin: for (int m = 0; m < dim1; m++) { System.arraycopy(laberinto[m], 0, solucion[m], 0, dim2); } laberinto[nodoAux[0]][nodoAux[1]] = 0;//deshacemos } else { //si no es solucin seguimos expandiendo expandir(solucion, laberinto, nodoAux, dim1, dim2, incrX, incrY, pasos); //deshacemos: laberinto[nodoAux[0]][nodoAux[1]] = 0; pasos--; } } } } }

5 de 8

//Caso de prueba: public static void main(String[] args) { // TODO Auto-generated method stub Laberinto lab = new Laberinto(6,6); lab.ponerMuro(0, 4); lab.ponerMuro(1, 2); lab.ponerMuro(2, 1); lab.ponerMuro(2, 2); lab.ponerMuro(2, 4); lab.ponerMuro(3, 2); lab.ponerMuro(3, 4); lab.ponerMuro(4, 0); lab.ponerMuro(4, 2); lab.ponerMuro(5, 4); lab.resolver(); } }

ANLISIS DE LA COMPLEJIDAD
Respecto al anlisis de la complejidad, depende ms bien de la cantidad de muros que haya, es decir, es variable. Por tanto sacar un valor estimado de complejidad no es significativo. Se puede ver claramente la influencia de los muros en la complejidad:

Ejemplo 1

Ejemplo 2

6 de 8

En el ejemplo 1, estamos en la posicin inicial rodeados de muros. La complejidad sera O(1) ya que no podemos hacer ningn movimiento vlido y tampoco podemos llegar a ninguna solucin.. En cambio en el ejemplo 2 para llegar a la meta recorremos N columnas ms M filas hasta llegar a la meta, complejidad O(N + M). Como vemos, segn estn distribuidos los muros tenemos una complejidad u otra, por consiguiente variable. Otro enfoque de la complejidad est en el uso de la ramificacin y poda con cota. Con este uso conseguimos podar ramas inservibles y por tanto la complejidad en comparacin de no usar cotas es menor. Un rbol de recursin grande con el uso de cotas puede quedar reducido a algo significativamente ms pequeo. Por eso se aprecia una mejora en la complejidad.

CONCLUSIONES
Como hemos comprobado, la ramificacin y poda puede ser aplicado a una variedad de problemas consiguiendo una mejora considerable a la hora de buscar soluciones ptimas. Aplicado al problema del laberinto nos ahorramos tener que recorrer caminos que no nos llevan a soluciones mejores, es decir, ganamos en tiempo de computacin. Para buscar el camino mnimo en el laberinto y en general para cualquier problema de optimizacin, el uso de la ramificacin y poda es una tcnica eficiente.

7 de 8

BIBLIOGRAFA
http://www.lcc.uma.es/~av/Libro/CAP7.pdf

8 de 8

Anda mungkin juga menyukai