0 évaluation0% ont trouvé ce document utile (0 vote)
391 vues6 pages
Este documento describe el problema de las 8 reinas, que consiste en colocar 8 reinas en un tablero de ajedrez de manera que ninguna esté amenazada por otra. Explica que resolverlo mediante fuerza bruta requeriría analizar más de 200 mil millones de combinaciones, lo que demoraría meses. En cambio, propone un algoritmo recursivo que coloca una reina por columna verificando que no esté amenazada por las ya colocadas.
Este documento describe el problema de las 8 reinas, que consiste en colocar 8 reinas en un tablero de ajedrez de manera que ninguna esté amenazada por otra. Explica que resolverlo mediante fuerza bruta requeriría analizar más de 200 mil millones de combinaciones, lo que demoraría meses. En cambio, propone un algoritmo recursivo que coloca una reina por columna verificando que no esté amenazada por las ya colocadas.
Este documento describe el problema de las 8 reinas, que consiste en colocar 8 reinas en un tablero de ajedrez de manera que ninguna esté amenazada por otra. Explica que resolverlo mediante fuerza bruta requeriría analizar más de 200 mil millones de combinaciones, lo que demoraría meses. En cambio, propone un algoritmo recursivo que coloca una reina por columna verificando que no esté amenazada por las ya colocadas.
Este problema consiste en determinar si se pueden colocar 8 damas en un tablero de
ajedrez de 64 casillas, de tal manera que no queden amenazadas. Si furamos a resolver este problema con fuerza bruta, tendramos que analizar todas las ubicaciones posibles de 8 reinas en el tablero hasta que nos encontremos con una combinacin en la que ninguna reina est amenazada o hayamos realizado todas las ubicaciones posibles. Para la colocacin de la primera dama hay 64 casillas disponibles. Cuando colocamos sta, quedaran 63 casillas posibles para la segunda dama. Y as sucesiva y recursivamente hasta que llegaramos a un total de combinaciones posibles de 64 * 63 * 62 * 61* 60 * 59 * 58 * 57, para un total de 200 000 millones de combinaciones. Una computadora muy rpida trabajando da y noche demorara ms de medio ao solamente para obtener todas las combinaciones, eso sin analizarlas. Por lo que evidentemente esta es una solucin muy costosa y puede mejorarse como se ver a continuacin. Sabemos que si podemos ubicar 8 reinas sin que se amenacen, entonces solo puede haber una reina por columna, ya que dos reinas en una misma columna estaran amenazndose. Por tanto el algoritmo de este problema consiste en: 1 Si n es cero, entonces ya no quedan reinas por poner y el problema tiene solucin. 2 Se intenta ubicar una reina en cada columna de izquierda a derecha. 3 Se intenta colocar la reina en cada celda de la columna y se verifica si desde esta posicin se amenaza a las reinas ubicadas en las columnas a la izquierda. Si no se amenazan las reinas anteriores, entonces trataremos de colocar las reinas restantes en las columnas de la derecha (aproximacin recursiva al caso base). 4 Si ninguna celda de la columna satisface el paso 3, no se puede ubicar una reina en la columna y se vuelve atrs para intentar ubicar en otra posicin a la reina ubicada en la columna anterior. Si estamos en la primera columna, entonces el problema no tiene solucin.
ubicareinas1 Backtracking. Problema del laberinto
Este mtodo lo nico que hace es verificar si se ha recibido un tablero correcto (es cuadrado y tiene todas las celdas en false). Luego llama al mtodo privado UbicaReinas que es el que intenta ubicar k reinas a partir del ancho del tablero.
ubicareinas2 Backtracking. Problema del laberinto
El mtodo Amenaza sera el encargado de verificar si se amenaza alguna otra dama, recorriendo el array de forma vertical, horizontal y diagonal, a partir de la posicin [i , j]. Adems de implementar este mtodo como ejercicio, puede mejorar un poco ms el algoritmo. Fjese que dos reinas no pueden ubicarse en la misma fila. Buscar la salida en un laberinto Al menos para mi este problema es el ideal para demostrar el poder del backtracking. Se trata de encontrar la salida dentro de un laberinto. La estrategia a seguir para salir de un laberinto es primeramente, explorar hacia delante un posible camino y ver si conduce a una solucin. Si no conduce a una solucin, hay que desandar el camino y volver atrs para intentar con otro.
Considere un laberinto representado por un array rectangular (bidimensional) de bool,
en el que una celda con valor false significa que hay un obstculo por el que no se puede atravesar. Y una celda con valor true es una celda por la que se puede pasar. El problema consiste por ejemplo en suponer que entramos por la celda en la posicin 0,0 y se quiere encontrar en camino hasta la posicin m,n donde m es la cantidad de filas del array y n la cantidad de columnas. Puede resolverse de igual forma si se empieza y se termina por otras celdas. El mtodo C# HaySalida es el siguiente:
haysalida Backtracking. Problema del laberinto
Como se ha visto en los ejemplos anteriores, este primer mtodo es el que se encarga de llamar al otro mtodo privado y recursivo de igual nombre. Veamos ahora el cdigo y luego lo comentamos.
haysalida2 Backtracking. Problema del laberinto
Empezamos desde la lnea 2 donde se indica el caso base de la recursividad. O sea, si
se ha llegado a la celda de salida y esta es true. Despus comprobamos si estamos en una celda por la cual no se puede pasar, en caso de que no se pueda pasar retornamos false. Si se puede pasar por esa casilla, la ponemos en false para garantizar que no pasaremos de nuevo por ella en caso que el camino no conduzca a una salida. Luego, en las prximas llamadas recursivas se intenta averiguar si hay salida desde las casillas vecinas y se retorna true en caso de encontrar la salida. Si se llega a la ltima lnea es porque desde ninguna de las celdas vecinas hay salida, y por tanto no hay salida desde la celda actual, por lo que se retorna false. El mtodo HaySalida solamente nos dice si existe o no salida del laberinto, pero no nos da la respuesta de cual es la salida, o sea, el camino a seguir para llegar a la salida. Intenta hacer un mtodo SalidaLaberinto que devuelva un array con los puntos por los que se debe pasar para llegar a la salida mas corta. En este caso para estar seguros de encontrar el camino ms corto, habra que explorar todos los caminos posibles y compararlos. Note que en el mtodo HaySalida, primero se explora el camino que va en direccin diagonal y luego los caminos ms cercanos a esta, lo cual no quiere decir que se encuentre el camino ms corto. Esto es lo que se conoce como heurstica, que consiste en mejorar los algoritmos basados en la experiencia, el conocimiento y el sentido comn. Solo agregar que esta tcnica de backtracking o Vuelta Atrs, es muy utilizada en juegos, ya que ante una determinada situacin del juego se exploran los diferentes caminos a seguir segn las posibles jugadas del contrario y as sucesivamente, decidiendo las jugadas, hasta que se conduce a la victoria. Bueno, hasta aqu este pequeo tutorial de recursividad en C#. Seguro faltaron muchas cosas por tratar en este tema, ya que no soy un experto ni mucho menos. Para aprender recursividad lo ms importante es practicar, leer y copiar cdigo. Aqu dejo algunos ejercicios. Si quieres luego debatimos las soluciones. 1- Escriba un mtodo recursivo string Invierte (string s) que devuelva el reverso de la cadena s. 2- Implemente un mtodo que demuestre que con un caballo se pueden recorrer todas las casillas de un tablero de ajedrez sin pasar dos veces por una misma casilla. 3- Escriba el mtodo static long Factorial(int n) que devuelva el factorial del nmero n. 0! = 1, y para n 1, n! = n * (n 1)! 4- Escriba el mtodo static bool EsPalndromo(string s) que diga si el string s es palndromo. Un string es palndromo si se lee de la misma forma de izquierda a derecha que de derecha a izquierda.
5- Implemente el mtodo static void DescomposicionSumandos(int n) que muestre en
la pantalla todas las formas posibles de descomponer el nmero n en sumandos. Por ejemplo, para n=5, en la pantalla se muestra: 11111 1112 122 113 14 23 5 6- El Taxista: Un taxista se desplaza en su taxi por una ciudad en la cual slo est permitido conducir hacia el ESTE y hacia el SUR. Implemente el mtodo static int CantidadCaminos(int xOrig, int yOrig, int xDest, int yDest) que devuelva la cantidad de caminos diferentes por los que se puede llegar desde el punto (xOrig, yOrig) hasta el punto (xDest, yDest). Asuma que xDest xOrig y que yDest yOrig.