Después de un rato jugar el videojuego The testament of Sherlock Holmes me encontré con este acertijo conocido.
Se trata del tour del caballo como las máquinas sirven para hacer prueba y error dejé la consola y encendí el PC para escribir la solución a este.
Hay que decir que este problema es bastante sencillo de resolver para tableros pequeños y basta con un dfs o backtracking y se obtienen no sólo una sino todas las soluciones posibles :)
Así pues la idea básica del algoritmo es:
Guardar los deltas de los movimientos en alguna estructura puede ser un arreglo.
función solución(f, c, cam, vis):
si ya visitó todas las casillas imprima cam y retorne
para cada movimiento:
si es posible(no se ha realizado y no se sale del tablero)
movf = f+deltaf iésimo
movc = c+deltac iésimo
solución(movf, movc, cam+(movf+movc), vis+(movf+movc))
remover movf y movc de cam y de vis
y la llamada inicial sería algo como
solucíon(0,0,'',estruc)
donde estruc es alguna estructura que permita eficientemente controlar qué casillas ya se han visitado.
Si se usa un conjunto se puede saber cuántas se han visitado aunque con una matriz también funcionaría se necesitaría un contador como parámetro adicional.
Que se diviertan!
Mostrando entradas con la etiqueta backtrack. Mostrar todas las entradas
Mostrando entradas con la etiqueta backtrack. Mostrar todas las entradas
martes, 31 de diciembre de 2013
Sherlock Homes y el problema del caballo
Publicado por
Nicolas Castro
en
21:39
0
comentarios


Enviar por correo electrónicoEscribe un blogCompartir en XCompartir con FacebookCompartir en Pinterest
Etiquetas:
algorithm,
algoritmia,
backtrack,
dfs,
knight tour,
problema,
problema del caballo,
programacion,
programming,
sherlock holmes
martes, 18 de diciembre de 2012
Solucionando sudokus
Su Doku es un juego muy conocido, no entraré en detalles históricos. Este problema puede ser visto como el problema de colorear un grafo, de esta forma los colores son cada uno de los números del uno al nueve, los nodos son cada una de las casillas y están conectados si están en un mismo recuadro, en una misma fila o en una misma columna.
Pasando a la solución por backtracking bien se puede ver que la fuerza bruta consiste en ubicar las casillas vacias y poner un numero en cada una de ellas y ver cuando ya no hayan casillas vacias si el sudoku ha sido resuelto, de no ser así se vuelve a atrás y se intenta con otros números. El problema de este enfoque es que si hay n casillas vacías se tendrán n! (n factorial) formas de llenar estas casillas. Tal vez para unas 9 casillas vacías funcione, pero si se intenta con 10 o más en un ordenador común en la actualidad, puede tardar mucho tiempo.
Así que la mejor forma de hacerlo es ver cuál casillas de las vacías tiene menos posibilidades y optar por una de ellas y hacer lo mismo recursivamente hasta que no hayan casillas vacías, en este punto se verifica si el sudoku está bien, de ser así ya está, si no entonces se vuelve atrás y se opta por otra de las posibilidades en la casilla que tenia varias posibilidades. Finalmente, si el sudoku está bien construido se podrá llegar a una solución.
En pseudocódigo esto podría ser algo como (la implementación en java o cpp no va más de 80 líneas! :) )
Creo que esta es la forma mas simple de resolver este problema, otro enfoque es usando la ténica de Knuth de "Dancing links". El enfoque presentado aquí no es el más eficiente pero es bastante sencillo de programar y puede ser útil en un concurso de programación :)
Cualquier comentario o duda, comenten.
Nota: les dejo algunos problemas que se pueden resolver con este algoritmo.
https://icpcarchive.ecs.baylor.edu/index.php?option=onlinejudge&page=show_problem&problem=2246
http://projecteuler.net/problem=96
Publicado por
Nicolas Castro
en
19:35
0
comentarios


Enviar por correo electrónicoEscribe un blogCompartir en XCompartir con FacebookCompartir en Pinterest
Etiquetas:
algoritmo solucionar sudoku,
algoritmo solucionar sudoku java cpp,
backtrack,
coloracion grafo sudoku,
graph coloring,
project euler problem 96,
solving sudoku algorithm,
su su sudoku
Suscribirse a:
Entradas (Atom)