0

这是代码

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.
4

2 回答 2

0

我认为您的问题应该在递归调用\+member(X,P) 之前解决。这是因为Prolog 通过对子句的深度优先搜索来实现逻辑,即自上而下和从左到右的选择和匹配。

当然,移动测试需要改变P计算。现在是参观后建成的。一种简单的方法是使用累加器,在第一次调用时初始化为 [],并统一到目标的完整路径。IE

route(X,Y,Acc, [X,Y|Acc], D) :- flight(X,Y,L), D is L.
...

?- route(roc, syr, [], Routing, Duration).
于 2013-04-30T05:39:40.890 回答
0

我的回答有一个警告-我正在对您的变量做出一些假设。我假设 X 是起点,Y 是目的地,R 是从 X 到 Y(含)的路径上的位置列表,D 是经过的距离?或者也许等待时间。应该没关系。

您的基本案例似乎有问题。您的基本情况是检查是否存在flight(X,Y,L)满足路线的 a 。您需要检查的是从 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以来已经有一段时间了...

让我知道这是否有帮助。

于 2013-04-29T23:11:17.413 回答