Вы находитесь на странице: 1из 5

Programacin Lgica

GRAFOS EN PROLOG
Un Grafo es otra estructura de datos que es ampliamente usada en los
algoritmos actuales. En esta clase describiremos una representacin de grafos en
PROLOG y desarrollaremos algunos programas para operaciones de grafo tpicas
(coloreado, bsqueda).

REPRESENTACIN
Un grafo es usualmente definido como un par (V,E), donde V es un
conjunto de vrtices y E es un conjunto de arcos o aristas (edges). Hay muchas
representaciones posibles de grafos en PROLOG, mostraremos dos de ellas.
Representacin A mantiene los vrtices y arcos en dos listas diferentes
(conjuntos):

g([Vertice, ...],[e(Vertice1,Vertice2,Valor), ...])

Notar, que sta representacin es apropiada para grafos dirigidos tambin como para
grafos no dirigidos. En caso de grafos no dirigidos, uno puede agregar cada una de los arcos
no dirigidos e(V1,V2,H) como dos arcos dirigidos e(V1,V2,H), e(V2,V1,H) o, mejor, es
posible ajustar el acceso al procedimiento arco (definido abajo).

Representacin B est basada en la idea de vecindad (adyacencia) y el


grafo es representado como una lista de vrtices y sus vecinos.

[Vertice-[Vertice2-Valor, ...], ...]

En este caso, la representacin de grafos no dirigidos contiene cada uno de los arcos dos
veces.

Procedimiento para acceder a los arcos en la representacin A.


arco(g(Es,Vs),V1,V2,Valor) :miembro(e(V1,V2,Valor),Vs).

Docente: Ing. Arturo Daz Pulido

Programacin Lgica

Si el grafo es no dirigido, el procedimiento arco puede ser ajustado de la


siguiente forma:
arco(g(Es,Vs),V1,V2,Valor) :miembro(e(V1,V2,Valor),Vs) ; miembro(e(V2,V1,Valor),Vs).

Procedimiento arco para la representacin B.


arco(Grafo,V1,V2,Valor) :miembro(V1-NB,Grafo),
miembro(V2-Valor,NB).

Ahora, es posible definir el procedimiento para encontrar la vecindad de un


vrtice usando el procedimiento arco.
vecindad(Grafo,V,NB) :setof(V1-E,arco(Grafo,V,V1,E),NB).

En caso de la representacin B es mejor (ms eficiente) definir la vecindad


directamente.
vecindad(Grafo,V,NB) :- miembro(V1-NB,Grafo).

Notar, que algunos grafos no usan valores en los arcos mientras otros asignan
valores tambin a los vrtices. En esos casos, los procedimientos de arriba tienen
que ser reescritos por consiguiente.

Docente: Ing. Arturo Daz Pulido

Programacin Lgica

BSQUEDA
Otro grupo de algoritmos con relacin a grafos son los de bsqueda (sobre el
grafo). En sta clase presentaremos dos algoritmos: bsqueda simple que
encuentra el camino entre dos vrtices y el algoritmo de Dijkstra el cual
encuentra el camino de distancia mnima desde un vrtice a todos los vrtices.
El siguiente programa encuentra un camino desde vrtice a otro vrtice. El
mismo programa puede ser usado para encontrar un camino en grafos dirigidos y
no dirigidos dependiendo de la definicin del procedimiento arco. Notar, que
usamos acumulador para que contenga parte del camino y prevenir ciclos.

% camino(+Grafo,+Start,+Stop,-Camino)
camino(Grafo,Start,Stop,Camino) :camino1(Grafo,Start,Stop,[Start],Camino).

camino1(Grafo,Stop,Stop,Camino,Camino).
camino1(Grafo,Start,Stop,ActCamino,Camino) :Start\=Stop,
arco(Grafo,Start,Proximo),
non_miembro(Proximo,ActCamino),
camino1(Grafo,Proximo,Stop,[Proximo|ActCamino],Camino).

non_miembro(_,[]).
non_miembro(X,[Y|T]) :X\=Y,
non_miembro(X,T).

El algoritmo de Dijkstra es bien conocido por encontrar el camino mnimo en


grafos con arcos (no negativos). Aqu est su implementacin en PROLOG el
cual encuentra la distancia mnima a todos los vrtices desde un vrtice dado.

% min_dist(+Grafo,+Start,-MinDist)
min_dist(Grafo,Start,MinDist) :dijkstra(Grafo,[],[Start-0],MinDist).

Docente: Ing. Arturo Daz Pulido

Programacin Lgica

% dijkstra(+Grafo,+CerradoVertices,+AbiertoVertices,-Distancias)
dijkstra(_,MinDist,[],MinDist).
dijkstra(Grafo,Cerrado,Abierto,MinDist) :escoger_v(Abierto,V-D,RestAbierto),
vecindad(Grafo,V,NB),
distancia a V

NB

es

una

lista

de

vrtices

adyacentes

diff(NB,Cerrado,NuevoNB),
merge(NuevoNB,RestAbierto,D,NuevoAbierto),
dijkstra(Grafo,[V-D|Cerrado],NuevoAbierto,MinDist).

% escoger_v(+AbiertoVertices,-VerticeToExpand,-RestAbiertoVertices)
escoger_v([H|T],MinV,Rest) :escoger_minv(T,H,MinV,Rest).

escoger_minv([],MinV,MinV,[]).
escoger_minv([H|T],M,MinV,[H2|Rest]) :H=V1-D1, M=V-D,
(D1<D -> ProximoM=H,H2=M
; ProximoM=M,H2=H),
escoger_minv(T,ProximoM,MinV,Rest).

% diff(+ListaOfVertices,+Cerrado,-ListaOfNonCerradoVertices)
diff([],_,[]).
diff([H|T],Cerrado,L) :H=V-D,
(miembro(V-_,Cerrado) -> L=NuevoT ; L=[H|NuevoT]),
diff(T,Cerrado,NuevoT).

% mezclar(+ListaOfVertices,+OldAbiertoVertices,-AllAbiertoVertices)
mezclar([],L,_,L).
mezclar([V1-D1|T],Abierto,D,NuevoAbierto) :(remover(Abierto,V1-D2,RestAbierto)
-> VD is min(D2,D+D1)

Docente: Ing. Arturo Daz Pulido

Programacin Lgica
; RestAbierto=Abierto,VD is D+D1),
NuevoAbierto=[V1-VD|SubAbierto],
mezclar(T,RestAbierto,D,SubAbierto).

remover([H|T],H,T).
remover([H|T],X,[H|NT]) :H\=X,
remover(T,X,NT).

Comparar el procedimiento remover con el procedimiento borrar (parte de coloreado). Ves


la diferencia?
Extiende el programa de arriba en una forma que tambin encuentre el camino mnimo (no
slo la distancia mnima) a todos los vrtices.

Docente: Ing. Arturo Daz Pulido

Вам также может понравиться