Dijkstra路径(不仅是距离)

时间:2015-05-22 16:58:29

标签: prolog logic-programming

我有计算Dijkstra路径最小距离的代码。你能帮我编辑我的代码,不仅可以打印最小距离,还可以打印完整路径吗?

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

edge(g(Es,Vs),V1,V2,Value):-
   member(e(V1,V2,Value),Vs) ;
   member(e(V2,V1,Value),Vs).

neighbourhood(Graph,V,NB):-
   setof(V1-E,edge(Graph,V,V1,E),NB).

% dijkstra(+Graph,+ClosedVertices,+OpenVertices,-Distances)
dijkstra(_,MinDist,[],MinDist).
dijkstra(Graph,Closed,Open,MinDist):-
   choose_v(Open,V-D,RestOpen),
   neighbourhood(Graph,V,NB),  % NB is a list of adjacent vertices+distance to V
   diff(NB,Closed,NewNB),
   merge(NewNB,RestOpen,D,NewOpen),
   dijkstra(Graph,[V-D|Closed],NewOpen,MinDist).

% choose_v(+OpenVertices,-VertexToExpand,-RestOpenVertices)
choose_v([H|T],MinV,Rest):-
   choose_minv(T,H,MinV,Rest).
choose_minv([],MinV,MinV,[]).
choose_minv([H|T],M,MinV,[H2|Rest]):-
   H=V1-D1, M=V-D,
   (D1<D -> NextM=H,H2=M
          ; NextM=M,H2=H),
   choose_minv(T,NextM,MinV,Rest).

% diff(+ListOfVertices,+Closed,-ListOfNonClosedVertices)
diff([],_,[]).
diff([H|T],Closed,L):-
   H=V-D,
   (member(V-_,Closed) -> L=NewT ; L=[H|NewT]),
   diff(T,Closed,NewT).

% merge(+ListOfVertices,+OldOpenVertices,-AllOpenVertices)
merge([],L,_,L).
merge([V1-D1|T],Open,D,NewOpen):-
   (remove(Open,V1-D2,RestOpen)
      -> VD is min(D2,D+D1)
       ; RestOpen=Open,VD is D+D1),
   NewOpen=[V1-VD|SubOpen],
   merge(T,RestOpen,D,SubOpen).

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

谢谢!
编辑:我编辑了我的代码,因为我忘了添加邻域和边缘谓词。

1 个答案:

答案 0 :(得分:1)

很好的来源,组织良好,评论很好。

我建议你修改你的&#34;合并&#34;这些语句不仅可以更新最小距离,还可以包含第三个字段,该字段的顶点可以达到最小值。

(警告:对这些陈述的评论缺少一个论点)。

类似的东西:

merge([V1-D1|T],Open,V-D-_,[V1-VD-O|SubOpen]):-
   (remove(Open,V1-D2-O2,RestOpen)
      -> ( D2<D+D1 -> VD=D2, O=O2 ; VD is D+D1, O=V)
      ; RestOpen=Open,VD is D+D1,O=V),
   merge(T,RestOpen,D,SubOpen).

这意味着您必须调整所有余数以传递表格的条款&#34; Vertice-Distance-Origin&#34;。