这是代码
flight(roc,syr,25).
flight(roc,jfk,55).
flight(jfk,bos,65).
flight(bos,syr,40).
flight(jfk,syr,50).
flight(bos,roc,50).
layover(roc,25).
layover(jfk,55).
layover(syr,30).
layover(bos,40).
route(X,Y,R,D) :-
flight(X,Y,L),
D is L,
R = [X,Y].
route(X,Y,R,D) :-
flight(X,Z,L),
route(Z,Y,P,M),
R = [X|P],
layover(Z,T),
D is M+L+T,
\+ member(X,P).
这是发生了什么。第二个条款
route(X,Y,R,D) :-
flight(X,Z,L),
route(Z,Y,P,M),
R = [X|P],
layover(Z,T),
D is M+L+T,
\+ member(X,P).
进入无限循环。它显示我想要的答案,然后不断找到更多的答案(因为你可以基本上保持循环停止)并进行无限循环直到它停止。该程序应该找到每个可能不会在停靠点周围循环的航线。我知道为什么会这样,但不知道如何更改我的代码来修复它。请帮忙。
这是一个解决方案
?- route(roc, syr, Routing, Duration).
Routing = [roc, syr],
Duration = 25 ;
Routing = [roc, jfk, syr],
Duration = 160 ;
Routing = [roc, jfk, bos, syr],
Duration = 255 ;
false.
答案 0 :(得分:0)
我的回答有一点需要注意 - 我对你的变量做了一些假设。我假设X是起点,Y是目的地,R是从X到Y(包括)的路径的位置列表,D是行进的距离?或者也许等待时间。无所谓。
看起来你的基本情况有问题。您的基本情况是检查是否存在满足路径的flight(X,Y,L)
。你需要检查的是从X到Y(R,如果我没有记错)的位置列表是否已经从X到Y覆盖。也就是说,如果列表R = Y的最后一个元素和R的第一个元素= X,那你完成了。
您可以使用的最后一项功能是:
last([X],X).
last([H|T],R):- last(T,R).
然后你可以有一个基本案例:
route(X,Y,R,D):- last(R,L), L == Y, [H|T] = R, H == X.
或类似的东西,无论如何。自从我使用prolog以来已经有一段时间......
如果有帮助,请告诉我。
答案 1 :(得分:0)
我认为您的问题应该在递归调用之前移动\+member(X,P)
来解决。这是因为Prolog通过深度优先搜索子句来实现逻辑,即自上而下和从左到右选择和匹配。
当然,移动测试需要更改P
计算。现在是在访问后建成的。一个简单的方法是使用累加器,在第一次调用时初始化为[],并在目标上统一到完整路径。即。
route(X,Y,Acc, [X,Y|Acc], D) :- flight(X,Y,L), D is L.
...
?- route(roc, syr, [], Routing, Duration).