Академический Документы
Профессиональный Документы
Культура Документы
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):
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).
En este caso, la representacin de grafos no dirigidos contiene cada uno de los arcos dos
veces.
Programacin Lgica
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.
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).
% min_dist(+Grafo,+Start,-MinDist)
min_dist(Grafo,Start,MinDist) :dijkstra(Grafo,[],[Start-0],MinDist).
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)
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).