Prolog:处理图遍历中的循环

时间:2015-12-14 00:10:34

标签: graph prolog cycle graph-traversal

road(london, paris, 135).
road(paris, london, 135).
road(paris, madrid, 250).
road(madrid, paris, 250).
road(madrid, barcelona, 70).
road(barcelona, madrid, 70).

route(X, Y, [X|Y], N) :-
   road(X, Y, N).
route(X, Y, [X|T], N) :- 
   road(X, Z, A),
   route(Z, Y, [_|T], B),
   N is A + B.

这是我面临的问题的示例代码。我的测试输入是

?- route(london, barcelona, R, 455).

此输入将继续通过london-paris和paris-london重复进行,但是我注意到如果我删除,它会找到从伦敦巴塞罗那出发的路线,周期巴黎 - 伦敦。

我的问题是,如果有任何方法可以实现一个允许我忽略循环的谓词。

2 个答案:

答案 0 :(得分:2)

您可以进行以下修改:

road(london, paris, 135).
road(paris, madrid, 250).
road(madrid, paris, 250). 
road(madrid, barcelona, 70).
road(barcelona, madrid, 70).

path(From, To, List, N) :-
   route(From, To, [From], N).

route(X, Y, Passed_city, N) :-
   road(X, Y, N).
route(X, Y, Passed_city, N) :- 
   road(X, Z, A),
   \+ member(Z, Passed_city),
   route(Z, Y, [Z|Passed_city], B),
   N is A + B.

并调用查询

?- path(london, barcelona, R, 455).

我所做的是为path/4创建新规则 要在包含您传递的所有城市的列表中插入第一个城市发件人,例如:route(From, To, [From], N)

然后我插入了目标\+ member(Z, Passed_city) 在第二条规则的主体中。

\+表示“不可证明”,所以 如果\+ member(Z, Passed_city)失败,即member(Z, Passed_city)不在Z中,则Passed_city为真。

答案 1 :(得分:-2)

Now work..

road(london, paris, 135).
road(paris, madrid, 250).
road(madrid, paris, 250). 
road(madrid, barcelona, 70).
road(barcelona, madrid, 70).

path(From, To, List, N) :-
   route(From, To, [From], N).

route(X, Y, Passed_city, N) :-
   road(X, Y, N), Passed_city = [Passed_city|Y].
route(X, Y, Passed_city, N) :- 
   road(X, Z, A),
   \+ member(Z, Passed_city),
   route(Z, Y, [Z|Passed_city], B),
   N is A + B.