我已制定规则以获取图形的路径,其边缘定义如下:
graph(a,b).
graph(a,a).
graph(b,c).
但现在我需要在事实存在时这样做,例如:
graph(a,[a,b,e]).
graph(b,[c,d]).
graph(d,[]).
我有这个:
path(Origin, Dest, List) :- path(Origin, Dest, List, [Origin]).
path(X, X, List, Temp) :- reverse(Temp, List).
path(Origin, Dest, List, Temp) :- graph(Origin, Inter),
not(member(Inter, Temp)),
path(Inter, Dest, List, [Inter|Temp]).
我知道问题出现在图表中(Origin,Inter),但我不知道如何调整它以便它可以进入列表,我已经尝试graph(Origin, [Inter|_])
但显然它只是检查第一。任何帮助(即使它不是代码)都将不胜感激。
答案 0 :(得分:3)
假设有向图:
edge(X,Y) :- graph(X,Nodes), member(Y,Nodes).
答案 1 :(得分:0)
我设法解决了这个问题,以防其他人遇到同样的问题:
node(X) :- graph(X,_).
allnodes(Nodes) :- setof(X, node(X), Nodes).
path(Origin,Dest,List) :- allnodes(X),
path(Origin, Dest, List1, X, X),
reverse(List1,List),!.
path(X,X,[X],_,_).
path(Origin,Dest,[Dest|List],[X|_],AN) :- graph(X, Inter),
member(Dest, Inter),
path(Origin,X,List,AN,AN).
path(Origin,Dest,List,[X|Y],AN) :- graph(X, Inter),
\+ member(Dest, Inter),
path(Origin,Dest,List,Y,AN).
答案 2 :(得分:0)
这是我的解决方案,适用于定向或无向图,有或没有循环。
使用@larsmans建议你可以使用adjacency-list之类的输入。
edge(X,Y) :- graph(X,Nodes), member(Y,Nodes).
它还会尝试查找所有路径,而无需重新访问。
c(1,2).
% ... c(X,Y) means X and Y are connected
d(X,Y):- c(X,Y).
d(X,Y):- c(Y,X).
% Use d instead of c to allow undirected graphs
findPathHelper(_, Begin, [], End):- d(Begin, End).
findPathHelper(Front, Begin, [Next|NMiddle], End):-
not(member(Begin,Front)),
d(Begin, Next),
append([Front,[Begin]], NFront),
findPathHelper(NFront, Next, NMiddle, End).
findPath(Start, End, Path):-
findPathHelper([], Start, Middle, End),
append([[Start],Middle,[End]], Path).