2012-01-13 74 views
0

我有充分的事實,如數據庫:序言 - 幫助固定規則

overground(newcrossgate,brockley,2). 
overground(brockley,honoroakpark,3). 
overground(honoroakpark,foresthill,3). 
overground(foresthill,sydenham,2). 
overground(sydenham,pengewest,3). 
overground(pengewest,anerley,2). 
overground(anerley,norwoodjunction,3). 
overground(norwoodjunction,westcroydon,8). 
overground(sydenham,crystalpalace,5). 
overground(highburyandislington,canonbury,2). 
overground(canonbury,dalstonjunction,3). 
overground(dalstonjunction,haggerston,1). 
overground(haggerston,hoxton,2). 
overground(hoxton,shoreditchhighstreet,3). 

例如:newcrossgate到Brockley的需要2分鐘。

然後我創建了一個規則,這樣如果我輸入查詢istime(newcrossgate,honoroakpark,Z)。那麼prolog應該給我兩個站之間的時間。 (我制定的規則旨在計算任何兩個電臺之間的距離,而不是相鄰電臺之間的距離)。

istime(X,Y,Z):- istime(X,Y,0,Z); istime(Y,X,0,Z). 
istime(X,Y,T,Z):- overground(X,Y,Z), T1 is T + Z. 
istime(X,Y,Z):- overground(X,A,T), istime(A,Y,T1), Z is T + T1. 
istime(X,Y,Z):- overground(X,B,T), istime(B,X,T1), Z is T + T1. 

它似乎適用於新的crossgate到第一對情侶站,比如newcrossgate到foresthill或sydenham。然而,在測試新賽季到westcroydon需要26分鐘後,我嘗試了新的crossgate進行crystalpalace,prolog說應該花費15分鐘......儘管事實上它是westcroydon之後的下一站。很顯然,這裏有些事情是錯誤的,但是它對大多數電臺都有效,偶爾會偶爾出現一些錯誤,誰能告訴我什麼是錯的? :S

+0

最後一項是否正確?你似乎從X到B,然後從B到X.你什麼時候去Y? – mgibsonbr 2012-01-13 23:32:39

回答

1

您是否試圖循環回答;? 26mins是 newcrossgate和westcroydon之間的最短時間...

編輯:我的壞!顯然,較短的結果是由於代碼中的錯誤(請參閱我對第4條的評論)。但是,您的代碼是正確的,15分鐘是newcrossgate和crystalpalace之間的最短路線。只是因爲有一條從newcrossgate到westcroydon,然後是crystalpalace的路線,這並不意味着它是最短的路線,或者程序最先屈服的路線。

更新:如果你遇到了問題,以找到一些途徑,我建議改變第三子句:

istime(X,Y,_,Z):- overground(X,A,T), istime(A,Y,T1), Z is T + T1. 

原因很簡單:你的第一句話交換X與Y,這很好,因爲你說的路線是對稱的。然而,第3條款並沒有從中受益,因爲它從未被交換過的商品調用過。忽略第三個參數(你還沒有使用它),從而讓第一個子句調用第三個參數可能會解決你的問題,因爲現在有一些以前沒有使用的有效路由。

(也:我同意尼古拉斯·凱莉的答案,這將是更好地使用第三個參數作爲蓄能器,但正如我所說,忽略它現在可能只是工作)

+0

我改變了從B到X的路由到B到Y的路由代碼的最後一行,我希望那就是你的意思。我正在測試,看看它的工作是否完美。 (X,Y,Z): - 地上(X,B,T),istime(B,Y,T1),Z是T + T1。 – JimmyK 2012-01-14 11:44:16

+0

該死的似乎沒有工作...每次我嘗試一個較長的旅程,如里士滿咆哮,我只是得到錯誤... – JimmyK 2012-01-14 11:56:53

+0

@JimmyK不是真的,如果仔細觀察,改變的子句與第三個子句相同(將變量的名稱從A更改爲B無關緊要),因此它只會重複計算。 – mgibsonbr 2012-01-14 13:48:44

2

這在本質上是相同的問題作爲你以前的問題,唯一的區別就是你需要隨着時間累積時間。

我看到的一件事是你的「公開」謂詞istime/3試圖做太多。它應該做的就是種子累加器並調用工作者謂詞istime/4。既然你正在尋找途徑/時間在兩個方向上,市民謂語應該只是

istime(X , Y , Z) :- istime(X , Y , 0 , Z) . 
istime(X , Y , Z) :- istime(Y , X , 0 , Z) . 

以上基本上是你的istime/3謂詞的第一條

istime(X,Y,Z):- istime(X,Y,0,Z); istime(Y,X,0,Z). 

istime/3其餘條款,遞歸的:

istime(X,Y,Z):- overground(X,A,T), istime(A,Y,T1), Z is T + T1. 
istime(X,Y,Z):- overground(X,B,T), istime(B,X,T1), Z is T + T1. 

應該適當地的istime/4一部分,並具有存在於蓄壓器。這就是你的問題所在。

給它另一個鏡頭並編輯你的問題來顯示下一個迭代。如果你仍然無法弄清楚,我會告訴你一些不同的方法來做到這一點。

一些提示

  1. 你的「工人」謂詞可能會看起來很像你前面的練習「中找到兩個站之間的路線」,但它有一個額外的參數,累加器的經過時間。

  2. 有兩種特殊情況。如果您使用您在使用的方法「找兩個站之間的路線」的解決方案,在特殊情況下是

    • A和B是直接相鄰。
    • A和B通過至少一箇中間停止點連接。

還有另一種方法爲好,可能被描述爲使用先行,在這種情況下,特殊情況是

  • A和B是相同的,在這種情況下你到達。
  • A和B不是且通過零個或多箇中間停靠點連接。

FWIW,您不應該期望經過時間最短或跳數最少的路線成爲第一個找到的解決方案。回溯將產生所有路線,但是它們的發現順序與事實存儲在數據庫中的順序有關。對圖表的最低成本搜索完全是另一個魚羣。

+0

試着你現在說的,謝謝你的幫助。 – JimmyK 2012-01-14 11:46:01

1

爲了使其發揮作用,您需要做與上一句中所述的旅程相反的操作。 將謂詞保持原樣,istime(X,Y,Z)並且只是生成另一個包含反向旅程的子句。 這種方式適用於所有車站。 (試過並測試過)

+0

嗯..似乎沒有工作太好,我得到了兩個不同的時間爲同一個確切的旅程完成一種方式,然後在相反 – JimmyK 2012-01-14 16:41:20