Prolog中的Dijkstra

Prolog中的Dijkstra,prolog,shortest-path,dijkstra,Prolog,Shortest Path,Dijkstra,我被指派在Prolog中编写Dijkstra最短路径 首先,我不想要源代码或完整的实现,因为我试图理解代码(评估的一部分是解释代码)。我看过一些实现,但我不知道它是如何工作的 到目前为止,我有: edge(1,2,12). %edge(From,To,Cost) ... edge(1,4,13). vertex(1,100000,nil,false).%vertex(Id, Weight, Over, Closed). ... vertex(5,100000,nil,false). neig

我被指派在Prolog中编写Dijkstra最短路径

首先,我不想要源代码或完整的实现,因为我试图理解代码(评估的一部分是解释代码)。我看过一些实现,但我不知道它是如何工作的

到目前为止,我有:

edge(1,2,12). %edge(From,To,Cost)
...
edge(1,4,13).

vertex(1,100000,nil,false).%vertex(Id, Weight, Over, Closed).
...
vertex(5,100000,nil,false).

neigh(V1, V2):-edge(V1,V2,_).

open_neigh(V1,V2):-edge(V1,V2,_),vertex(V2,_,_,P),not(P).

nearest_neighbor(From,Who,Cost):-findall(Node,neigh(From, Node),NeighL),
    nearest_in_list(From,Who,NeighL,Cost).

n_hood(From,NeighList):-findall(Node, neigh(From,Node), NeighList).

open_n_hood(From,NeighList):-findall(Node, open_neigh(From,Node), NeighList).

nearest_in_list(_,Who,[Who],_).
nearest_in_list(From,Who,[H,K|T],Cost) :-
    edge(From,H,C1),
    edge(From,K,C2),
    C1 =< C2,
    Cost is C1,
    nearest_in_list(From,Who,[H|T],Cost).

nearest_in_list(From,Who,[H,K|T],Cost) :-
    edge(From,H,C1),
    edge(From,K,C2),
    C1 > C2,
    Cost is C2,
    nearest_in_list(From,Who,[K|T],Cost).
边缘(1,2,12)。%优势(从、到、成本)
...
边缘(1,4,13)。
顶点(1100000,零,假)。%顶点(Id,重量,结束,关闭)。
...
顶点(5100000,零,假)。
neigh(V1,V2):-edge(V1,V2,2;)。
开环(V1,V2):-边(V1,V2,P),顶点(V2,P),非(P)。
最近邻(来自,谁,成本):-findall(节点,neigh(来自,节点),NeighL,
清单中最近的单位(来源、卫生组织、邻居、成本)。
n_hood(From,NeighList):-findall(Node,neigh(From,Node),NeighList)。
打开引擎盖(从,邻居列表):-findall(节点,打开邻居(从,节点),邻居列表)。
在_列表中最近的_(u,Who,[Who],u)。
清单中最近的单位(来自、世卫组织、[H、K | T]、成本):-
边缘(从,H,C1开始),
边缘(从,K,C2),
C1=C2,
成本是C2,
清单中最近的单位(来自、世卫组织、[K|T]、成本)。
问题是,我不知道如何更新有关顶点的信息。我尝试过assert/1和retract/1,但都不起作用。我得到一个错误,无法修改静态过程vertex/4

我目前正在使用SWI Prolog,但该程序应该可以在Amzi上运行!Prolog也是,所以我希望它尽可能接近基本的Prolog


谢谢。

如果您确实需要更新值,我建议您使用
标志/3
。然而,正如评论中所建议的,Prolog程序通常没有通过算法步骤更新的“全局变量”


相反,我建议你找到一个正确的方法来计算Dijkstra的成本。请注意,Dijkstra算法中的初始参数始终是“未访问”节点,一个列表(
[a,b,c,d |…]
)。在每一步中,您都通过“访问”其中一个节点并更新其成本来更新此列表。我在这里看到一个清晰的递归调用

好吧,要么没用,要么我用错了。我在文件的开头加上了它。仍然是相同的错误-无法修改静态变量。您能提供更多信息吗?另外,它是SWI特定的还是通用的?始终先让您的程序在没有断言的情况下工作,然后使用它进行优化。prolog的要点是您没有存储数据。您需要的是某种类型的数据结构,作为参数传递,以及一个函数,该函数接受该数据结构并返回其修改版本。然后,当您让它工作时,以不会改变代码语义的方式使用assert(即如果谓词以前成功,那么现在就成功了)。请注意,
标志/3
谓词是SWI Prolog专有谓词。但是,它可以在其他Prolog实现中进行模拟。