有人可以详细说明旅行的功能/条件(A,B,访问,路径)和旅行(A,B,P,[B | P])..此代码找到路径A和B之间的路径在图表中
edge(a,b).
edge(b,c).
edge(b,d).
edge(c,d).
edge(d,b).
edge(e,f).
edge(e,g).
edge(e,h).
edge(h,i).
edge(i,g).
edge(b,e).
connectedEdges(X,Y) :- edge(X,Y).
connectedEdges(X,Y) :- edge(Y,X).
path(A,B,Path) :-
travel(A,B,[A],Q),
reverse(Q,Path).
travel(A,B,P,[B|P]) :-
connectedEdges(A,B).
travel(A,B,Visited,Path) :-
connectedEdges(A,C),
C \== B,
\+member(C,Visited),
travel(C,B,[C|Visited],Path).
答案 0 :(得分:1)
让我们从第一个travel/4
规则开始:
travel(A,B,P,[B|P]) :-
connectedEdges(A,B).
"如果A点和B点直接相互连接,那么我们找到了一个直接的子路径,因此可以通过将B点添加到与我们访问过的所有点统一的路径中来取得成功到目前为止。"
换句话说,既然我们已经解决了一个子问题(通过找到与2个节点的直接连接),我们基本上可以说P
(到目前为止我们访问过的所有内容),是路径列表[B|P]
(总路径是我们访问过的最后一个节点....当前目标节点,预先到我们访问过的所有先前节点)。
travel/4
规则:
travel(A,B,Visited,Path) :-
connectedEdges(A,C),
C \== B,
\+member(C,Visited),
travel(C,B,[C|Visited],Path).
重要的是要注意,无论第一条规则是否成功,都将始终尝试使用第二条规则作为替代规则。由于此实现的这一事实,这里的含义是此代码可能找到多个路径(如果存在多个路径)。
无论如何,在第二条规则中,我们发现任何节点都连接到A
,而不是 B
。为什么?,这是因为上面的第一条规则已经尝试过了;在这条规则中,我们正在寻找替代方案。如果该节点C
尚未访问过,我们只需尝试从该点(C
)前往目的地。然后我们再次递归查询/调用travel/4
,直到我们找到完整的路径。
再次注意,此实现可能会找到给定查询的0,1或1个以上的解决方案。
<小时/> 总结一下,第一条规则被称为在点之间找到直接连接。调用第二个规则来查找点之间的间接连接。