2011-11-29 114 views
9

我查看了類似的問題,但無法找到與我的問題相關的任何內容。我在努力尋找「迴路」,將找到CityACityB路徑的算法或一組,使用的簡體中文Prolog旅行推銷員

distance(City1,City2,Distance) 

事實數據庫。到目前爲止,我設法做到的是在下面,但它總是回溯到write(X),,然後完成最後一次迭代,這是我希望它做的,但只在一定程度上。

例如,我不希望它打印出任何死衚衕的城市名稱,或者使用最終的迭代。我想要它基本上從CityACityB的路徑,寫出它在路徑上的城市名稱。

我希望有人能幫助我!

all_possible_paths(CityA, CityB) :- 
    write(CityA), 
    nl, 
    loop_process(CityA, CityB). 

loop_process(CityA, CityB) :- 
    CityA == CityB. 
loop_process(CityA, CityB) :- 
    CityA \== CityB, 
    distance(CityA, X, _), 
    write(X), 
    nl, 
    loop_process(X, CityB). 

回答

7

我試圖證明你如何實現你正在做的事情,以便你能更好地理解它是如何工作的。所以,因爲你的OP不是很完整,所以我採取了一些自由!下面是我的工作的事實:

road(birmingham,bristol, 9). 
road(london,birmingham, 3). 
road(london,bristol, 6). 
road(london,plymouth, 5). 
road(plymouth,london, 5). 
road(portsmouth,london, 4). 
road(portsmouth,plymouth, 8). 

這是我們會打電話找我們的路,get_road/4謂語。它基本上稱爲工作謂詞,它有兩個累加器(一個用於已經訪問的點,另一個用於我們經歷的距離)。

get_road(Start, End, Visited, Result) :- 
    get_road(Start, End, [Start], 0, Visited, Result). 

這裏是工作謂詞,
get_road/6:get_road(+開始,結束+,+航點,+ DistanceAcc,-Visited,-TotalDistance):
第一個子句通知,如果我們的第一點和最後一點之間有一條路,我們可以在這裏結束。

get_road(Start, End, Waypoints, DistanceAcc, Visited, TotalDistance) :- 
    road(Start, End, Distance), 
    reverse([End|Waypoints], Visited), 
    TotalDistance is DistanceAcc + Distance. 

第二子句通知,如果有我們的第一點和中間點之間的道路,我們可以把它再解決get_road(中間,結尾)。

get_road(Start, End, Waypoints, DistanceAcc, Visited, TotalDistance) :- 
    road(Start, Waypoint, Distance), 
    \+ member(Waypoint, Waypoints), 
    NewDistanceAcc is DistanceAcc + Distance, 
    get_road(Waypoint, End, [Waypoint|Waypoints], NewDistanceAcc, Visited, TotalDistance). 

用法如下:

?- get_road(portsmouth, plymouth, Visited, Distance). 

和產量:

Visited = [portsmouth, plymouth], 
Distance = 8 ; 
Visited = [portsmouth, london, plymouth], 
Distance = 9 ; 
Visited = [portsmouth, plymouth, london, plymouth], 
Distance = 18 ; 
false. 

我希望這將是對你有所幫助。

+0

你先生,已經超越了職責範圍!這是令人難以置信的,它是完美的,它實際上是有道理的!對不起,我是個假人,對於prolog來說我真的很陌生,雖然很多事情都很自然地發生,但我真的爲這個任務而努力。非常感謝你這麼sooooo much:] –

+0

不要猶豫,如果你再次努力瞭解這個代碼,我或其他人會回答他們的評論:) – m09

1

您應該在all_possible_paths中返回一個成功的列表作爲Out變量。然後寫出那個清單。不要在同一個程序中進行這兩項操作。

+0

感謝您的幫助:] –

4

請將純粹的部分與不純(I/O,如write/1,nl/0,但也(==)/2(\==)/2)分開。只要它們完全與純粹的代碼交織在一起,你就不會期待太多。

也許你想要一個起點,終點和之間的路徑之間的關係。

該路徑應該是非循環的 還是允許循環

爲了確保元素X並不在列表Xs發生使用目標maplist(dif(X),Xs). 你不需要任何進一步的輔助謂詞,使這個美好的關係!

+0

一旦城市被使用,它不能再用於同一條路徑。所以,非循環。還有,純粹和不純的是什麼意思? –

+0

我在上面添加了一個解釋。 – false

+0

感謝您的幫助! :] –