2013-04-26 80 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