下图展示了图形。我需要判断两个节点之间是否存在路径,并打印出路径。例如:我的查询是path(a,c),它会返回True。现在当我查询path(g,f)时,前两个结果是True,但在返回结果后程序并没有终止,而是开始循环。我是Prolog的新手。请建议一些方法来停止递归,以便在找到正确数量的路径后停止。这些是事实
arc(a,b). arc(b,c). arc(c,d). arc(d,b). arc(b,g). arc(g,b). arc(d,g). arc(g,d). arc(f,d). arc(a,e). arc(f,e). arc(a,d). arc(f,g). arc(c,f). path(X,Y):- arc(X,Y). path(X,Y):- arc(X,Z),path(Z,Y).
回答:
您正在遍历一个有向图。假设图是无环的,这应该能枚举所有可能的路径:
path(X,Y) :- % 从X到Y存在路径 arc(X,Y) % 如果从X到Y存在一条边 . %path(X,Y) :- % 否则,从X到Y存在路径 arc(X,Z) , % 如果从X存在一个出边 Z \== Y , % 其目的地(Z)不是Y,并且 path(X,Y) % 从Z到Y存在路径 . % 简单!
我们在这里使用 \==/2 是因为这个谓词可能会被调用时参数未绑定。
另一种写法可能是:
path(X,Y) :- % 从X到Y存在路径 arc(X,Z) , % 如果从X存在一个出边, ( % 并且 Z = Y % Y是那个目的地(Z) ; % 或者 path(Z,Y) % 从Z可以到达Y。 ) .
如果您的图是有环的,您需要构建并随身携带一个已访问节点的列表,以便您可以跳过已经访问过的节点,以免陷入无限递归的兔子洞。