Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Misioneros y Canibales
Misioneros y Canibales
Tres misioneros y tres caníbales están en una de las márgenes de un río junto a un bote en la
que sólo cabe 1 o 2 personas. Hay que encontrar la manera de pasarlos al otro lado del río pero
teniendo cuidado que en ningún momento quede un grupo de misioneros junto con un grupo
de caníbales, siendo la cantidad de misioneros menor a la de caníbales.
Operadores posibles:
Pueden ser que un bote:
No lleva ningún misionero y lleva un caníbal.
Lleva 2 misioneros y ningún caníbal.
Lleva 2 caníbales y ningún misionero.
Lleva 1 caníbal y un misionero.
No lleva ningún caníbal y lleva un misionero.
Solo está permitido si hay igual o más misioneros que caníbales en una orilla o no hay
misioneros que afectar en una orilla.
En la búsqueda preferente por profundidad siempre se expande uno de los nodos que se
encuentre en los más profundo de árbol, por lo tanto los nodos sucesores estarán a
profundidades cada vez mayores.
DESARROLLO EN PROLOG:
domains
orilla=orilla(byte,byte,byte)
bote=bote(byte,byte)
hecho=hecho(orilla,orilla)
database - canymis
hecho(orilla,orilla)
predicates
ejecutar.
profundidad(orilla,orilla).
ejecutar_movimiento(orilla,orilla,orilla,orilla).
movimiento(orilla,orilla,orilla,orilla).
imprime_estado(orilla,orilla).
invertir_orillaOproceder(orilla,orilla,orilla,orilla).
mostrar_movimiento(bote).
movimiento(bote).
permitido(orilla).
adicionar(orilla, bote, orilla).
quitar(orilla, bote, orilla).
aplicable(orilla,bote).
mostrar_bote(byte).
clauses
/* si la situación es permitida */
permitido(orilla(0,_,_)) :- !. /* corte continua donde quedó */
permitido(orilla(M,C,_)) :- M >= C. /* si hay igual o más misioneros que canibales para que no se los coman */
profundidad(Izq,Der) :-
/* Si no es el ESTADO OBJETIVO efectúa la búsqueda */
ejecutar_movimiento(Izq,Der,SgteIzq,SgteDer), /* ejecutar movimiento desde el estado actual */
imprime_estado(SgteIzq,SgteDer),
profundidad(SgteIzq,SgteDer). /* y llamarse recursivamente */
ejecutar_movimiento(Izq,Der,SgteIzq,SgteDer) :-
write("Toma la primera movida permitida que encuentre\n"),
movimiento(Izq,Der,SgteIzq,SgteDer), /* ver movimiento */
/* si no está el mov sgte. para no repetir situación */
not(hecho(SgteIzq,SgteDer)), /* para obtener un nuevo estado */
/* grabar el mov */
assert(hecho(SgteIzq,SgteDer)),
permitido(SgteIzq), permitido(SgteDer). /* ver si es permitido */
/* Adicionar al destino */
adicionar(orilla(MD,CD,0), bote(MB,CB), orilla(MR,CR,1)) :-
/* Pj si el destino inicial es 0,0,0 y el bote (0,1) entonces :
MR = 0+0 = 0 misioneros a la orilla derecha por que no se transportó ninguno
CR = 0+1 = 1 caníbal a la orilla derecha por se transportó 1, el resultado
será que la orilla derecha tendrá 0 misioneros y 1 caníbal */
MR = MD+MB, CR = CD+CB.
goal
ejecutar.