You are on page 1of 3

Programación Declarativa

Universidad de Málaga 3.o de Ingeniería Informática


E.T.S.I. Informática Enero de 2008

Tema 6. Grafos y espacios de estados

Ejercicios

Ejercicio 1. Un camino euleriano es un camino que va desde un nodo X a un nodo Y pasando


exactamente una vez por cada arco del grafo. Un circuito euleriano es un camino euleriano
que empieza y acaba en el mismo nodo. Define los predicados Prolog:
camino_euleriano(X,Y,Cs)
circuito_euleriano(X,Cs)

que permiten obtener caminos y circuitos eulerianos de un grafo. Escribe versiones para
grafos orientados, no orientados y etiquetados.
Ejercicio 2. Un camino hamiltoniano es un camino que va desde un nodo X a un nodo
Y pasando exactamente una vez por cada nodo del grafo. Un circuito hamiltoniano es un
camino hamiltoniano que empieza y acaba en el mismo nodo (éste sí se visita dos veces, al
principio y al final). Define los predicados Prolog:
camino_hamiltoniano(X,Y,Cs)
circuito_hamiltoniano(X,Cs)

que permiten obtener caminos y circuitos hamiltonianos de un grafo. Escribe versiones para
grafos orientados, no orientados y etiquetados.
Ejercicio 3. Las siguientes figuras se pueden dibujar sin levantar el lápiz del papel y sin
trazar dos veces la misma recta.

a b c

d e f b d
b c
a e
g h i
a c

d e j f g h
Escribe un programa Prolog que, para cada figura, obtenga el orden en que deben ser trazadas
sus rectas; es decir, el orden por el que se pasa por los puntos etiquetados.
Observa que cada figura puede representarse como un grafo no dirigido, donde los puntos
etiquetados se corresponden con los nodos y los trazos con aristas. El trazado de la figura se
corresponde, por tanto, con un camino euleriano del grafo correspondiente.
Ejercicio 4. Tres misioneros y tres caníbales se disponen a cruzar un río con una canoa con
capacidad para dos personas. Escribe un programa que genere un plan para cruzar el río,

1
teniendo en cuenta que nunca puede haber menos misioneros que caníbales en alguna de las
márgenes del río, pues serían devorados.
Ejercicio 5. Un granjero, un lobo, una cabra y una col desean cruzar un río con la ayuda
de una barca con capacidad para cualesquiera dos de ellos, y en la que sólo puede remar
el granjero. Escribe un programa Prolog que genere un plan para cruzar el río, teniendo en
cuenta que si el lobo queda a solas con la cabra, la devorará, y si la cabra queda a solas con
la col, se la comerá.
Ejercicio 6. Un sabio dispone de dos relojes de arena con capacidad para medir 7 y 11
minutos respectivamente. Los relojes se ponen en marcha simultáneamente y cuando uno se
acaba se puede:

dejar acabar al otro

volver los dos relojes

volver uno solo de los relojes

Escribir un programa Prolog que genere una secuencia de movimientos de los relojes que
permita medir una cantidad N de minutos.
Ejercicio 7. Cinco matrimonios se encuentran aislados por una inundación. Para huir, cuentan
con un bote con capacidad para tres personas. Los maridos son tan celosos que en ningún
caso permitirían que sus esposas se encontraran en compañía de otros hombres sin estar
ellos mismos presentes. Escribe un programa Prolog que genere un plan para salvar a estos
matrimonios.
Ejercicio 8. La plantilla de la búsqueda en anchura que hemos estudiado devuelve como
solución la secuencia de estados visitados. Por ejemplo, para el problema de los contenedores
obtenemos como primera solución:

?- resolver(cont,Sol).
Sol = [ (0, 0), (8, 0), (8, 5), (0, 5), (5, 0), (5, 5), ...]

Modifica la definición de la plantilla y del predicado mover/2 de forma que obtengamos como
solución la secuencia de movimientos realizados. Por ejemplo:

?- resolver(cont,Sol).
Sol = [ llenar_x, llenar_y, vaciar_x, verter_comp_Y_en_X, llenar_y, ...]

Ejercicio 9. Define el predicado:

resolver(IdProblema,ProfMáx,Solución)

que resuelve un problema de espacio de estados IdProblema, aplicando una búsqueda por
profundización progresiva con profundidad máxima de ProfMáx. Escribe dos versiones: una
que represente la Solución como la secuencia de estados visitados, y otra que la represente
como la secuencia de movimientos realizados.
Aplica esta estrategia para resolver los problemas anteriores. ¿Cuáles son las ventajas e
inconvenientes con respecto a la búsqueda en profundidad?
Ejercicio 10. El siguiente predicado vecinos(X,Vs), definido en términos del predicado pre-
definido findall/3, permite obtener todos los vecinos de un nodo X en una lista Vs:

vecinos(X,Vs) :- findall(Y,arco(X,Y),Vs).

2
Por ejemplo, considera el siguiente grafo dirigido:

arco(a,b).
a f arco(a,c).
arco(b,d).
c
g arco(c,d).
arco(c,e).
e arco(d,a).
b
arco(d,b).
d arco(d,d).
arco(d,e).
arco(f,g).

Los siguientes objetivos obtienen todos los vecinos de un nodo dado sin necesidad de retro-
ceso:

?- vecinos(a,Vs).
Vs = [b, c] ;
No

?- vecinos(d,Vs).
Vs = [a, b, d, e] ;
No

?- vecinos(g,Vs).
Vs = [] ;
No

Observa que si un nodo no tiene vecinos, vecinos/2 devuelve la lista vacía.


La ventaja de obtener todos los vecinos de un nodo de forma simultánea es que nos
permite programar diferentes versiones de la búsqueda en anchura. Utilizando vecinos/2,
define los siguientes predicados Prolog:

conectados_anchura(X,Y) que realiza un recorrido en anchura para comprobar si los


nodos X e Y están conectados.

resolver_anchura(IdProblema,Solución) que resuelve un problema de espacio de es-


tados IdProblema empleando una búsqueda en anchura.

You might also like