2013-04-26 81 views
1

由于Prolog的回溯循环遍历目标,导致我的多重解决方案问题。虽然我理解,在技术上,提供的每个解决方案都是正确的,但对我无用。有没有删除重复的方法?如何防止序言中的重复项

这里是我到目前为止的代码:

flight(london, paris). 
flight(paris, amsterdam). 
flight(amsterdam, rome). 
flight(rome, paris). 
flight(rome, rio_de_janeiro). 
route_from(A,B) :- 
    flight(A,B). 
route_from(A,B) :- 
    flight(A,R), 
    route_from(R,B). 

示例查询是:

?- route_from(A, paris). 
A = london ; 
A = rome ; 
A = london ; 
A = london ; 
A = london ; 
A = london ; 
A = london ; 
A = london ; 
A = london ; 
etc. 

问候。

回答

3

除了返回重复解决方案之外,您还有一个更大的问题。你的程序就像无限循环一样,因为图中有循环。

为了避免循环,你可以保持走访城市的列表:

route_from(A,B) :- 
    route_from(A,B, []). 

route_from(A,B, _) :- 
    flight(A,B). 
route_from(A,B, Visited) :- 
    flight(A,R), 
    \+ member(A, Visited), 
    route_from(R,B, [A|Visited]). 

现在,这不会阻止,如果有去一个城市不止一种方式返回重复。您可以使用setof/3 + member/2收集所有解决方案而不重复。

route_from_without_duplicates(A,B):- 
    setof(A-B, route_from(A,B), Routes), 
    member(A-B, Routes). 
+0

谢谢,\ +的目的是什么? – 2013-04-26 19:36:27

+0

它的否定(如果调用失败,则成功);在这个例子中它意味着'A'不应该是'Visited'的成员 – gusbro 2013-04-26 19:43:04