我目前正在實施prolog程序來計算兩點之間的最短路徑。 該框架已經存在於Java項目中。作爲要求,路徑必須在序言中實現。 所以我用gnu.prolog(http://www.gnu.org/software/gnuprologjava/)序言上的性能問題
的Java應用我稱之爲searchPath(1,5,Path)
的將返回Path=[5,4,3,2,1]
這裏是我的序言代碼:
:- dynamic(path/3).
findPath([Goal | Rest], Goal, Temp, Temp, [Goal | Rest]).
findPath([A | Rest], Goal, Cost, Temp, Path) :-
path(A,B,C),
\+member(B, [A | Rest]),
NewCosts is (Temp + C),
findPath([B, A | Rest], Goal, Cost, NewCosts, Path).
searchPath(Start,Goal,Path_to_goal) :-
findPath([Start], Goal, Cost1, 0, Path),
findPath([Start], Goal, Cost2, 0, Path2),
Cost1=<Cost2,
Path_to_goal = Path.
我有兩個問題與:
searchPath
方法應該返回最短路徑。然而它 確實不是。這導致我的幻影「決定」在某點處切換 方向,導致幻影從左邊的 向右抖動。我的序言代碼最多需要6秒才能返回結果。我不需要告訴你這是太多的時間。不過有時prolog只需要19ms。我無法弄清楚這取決於哪些情況。例如,一個包含99個元素的路徑列表需要19ms的時間來計算,但是在一個僅包含38個元素的列表上花費了6秒。
你能提出任何改進建議嗎?
感謝您的幫助提前!
謝謝您的建議。代碼完美。但不幸的是,有一個原因,它不能幫助我:這個項目是大學的一項任務,我不允許複製任何代碼。對於我來說,dijkstra算法實現起來非常複雜:-( – Markus 2013-04-04 11:10:19
感謝您爲我投入這麼多時間!!!您的實現工作正常!然而,我有一些問題或許可以回答:1.即使在閱讀手冊後, m沒有真正意識到'nb_setarg'和'setarg'之間的區別,是不是真的知道'nb_setarg'和'setarg'之間的區別?如果回溯找到另一個解決方案,但是'nb_setarg'不會發生這種情況,用'setarg'取代Value?2.我無法確定爲什麼在你的算法中有一個'fail'和'true',你能解釋一下它們的用途嗎? – Markus 2013-04-04 17:10:52
這些是Prolog的特性.'fail'通過findPath產生下一個解決方案,但是在產生最後一個解決方案之後,它會失敗,'true'將允許完成這個過程。參見 - > [控制謂詞](http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%274.8% 27,swi%28%27/doc/Manual/control.html%27%29%29)無關:我認爲重複/ 0可以被刪除編輯。 – CapelliC 2013-04-04 17:25:55