我给出了一个弧列表:
arc(a,b).
arc(b,c).
arc(c,d).
arc(d,b).
arc(d,e).
arc(e,e).
arc(e,f).
我写了一组子句,告诉我是否有从节点X
到节点Y
的路径。循环可能会发生,我已经解释了。
path(X,Y) :-
arc(X,Y).
path(X,Y) :-
arc(X,Z),
path(Z,Y,[X]).
path(X,Y,P) :-
arc(X,Y).
path(X,Y,P) :-
\+ member(X,P),
arc(X,Z),
append([X],P,L),
path(Z,Y,L).
我需要将其修改为成功时返回遍历的节点列表。我不清楚我将如何做到这一点。
我认为我的基本情况类似于path2(X,Y,[X,Y]) :- arc(X,Y).
,但这不适用于我的程序。我前一部分的解决方案是否有问题,或者我只是错过了一个小修改?任何帮助,将不胜感激。谢谢!
答案 0 :(得分:2)
关闭......但请考虑:
path(Start, End, Path) :-
path(Start, End, [], Path).
使用起始和结束节点调用path/3
将构建它们之间的路径(如果存在),并回溯以为您提供备用路由。没有两次访问节点。 []
是一个节点累加器列表,因此我们可以检查我们是否在构建路径时不在圈内。
path(Now, End, Acc, Path) :-
arc(Now, Mid),
Mid == End, !,
append(Acc, [Now, End], Path).
path(Now, End, Acc, Path) :-
arc(Now, Mid),
\+ member(Mid, Acc),
path(Mid, End, [Now|Acc], Path).
这些谓词可以完成实际工作。第一个是基本情况,通过另一个arc/2
调用到达终端节点;在这种情况下,已经建立了一条路径。第二个遍历(有向)图,但仅遍历尚未访问过的节点。
可以使用findall/3
通过以下方式立即找到所有路径:
findall(Path, path(Start,End,Path), Paths).
对于节点原子的Start
和End
的绑定值。
答案 1 :(得分:1)
转到higher level并使用transitive-closure 1 作为基本习语!
% your binary predicate arc/2 gets used here % | % v ?- path(arc, Path, From, To). From = To , Path = [To] ; From = a, To = b, Path = [a,b] ; From = a, To = c, Path = [a,b,c] ; From = a, To = d, Path = [a,b,c,d] ; From = a, To = e, Path = [a,b,c,d,e] ; From = a, To = f, Path = [a,b,c,d,e,f] ; From = b, To = c, Path = [b,c] ; From = b, To = d, Path = [b,c,d] ; From = b, To = e, Path = [b,c,d,e] ; From = b, To = f, Path = [b,c,d,e,f] ; From = c, To = d, Path = [c,d] ; From = c, To = b, Path = [c,d,b] ; From = c, To = e, Path = [c,d,e] ; From = c, To = f, Path = [c,d,e,f] ; From = d, To = b, Path = [d,b] ; From = d, To = c, Path = [d,b,c] ; From = d, To = e, Path = [d,e] ; From = d, To = f, Path = [d,e,f] ; From = e, To = f, Path = [e,f] ; false.
脚注1:由多才多艺的meta-predicate path/4
实施。
答案 2 :(得分:0)
sharky给出的答案对我来说似乎没有用,但是下面的mod确实对我来说更直接。 :
path(Now, End, Acc, [Now,End]) :-
arc(Now, End),
\+ member(Now, Acc),
\+ member(End, Acc).
path(Now, End, Acc, Path) :-
arc(Now, Mid),
\+ member(Mid, Acc),
path(Mid, End, [Now|Acc], Path).
请告诉我,我是否遗漏了某些东西。