两个城市之间最快的方式

时间:2015-12-14 20:24:36

标签: prolog

我需要找到从一个城市到另一个城市旅行的最快方式。我有类似

的东西
 way(madrid, barcelona, 4).
 way(barcelona, paris, 5).
 way(madrid, londres, 3).
 way(londres,paris,1).

我提出了一个谓词短路(A,B,C,D),其中C是A和B之间的城镇列表,D是距离。

所以我有

shortway(A,B,C,D):- 
     way(A,B,_,_) , (A,_,C,D). D<C.
     shortway(A,_,C).

我尽我所能,但我真的无法让它发挥作用!

2 个答案:

答案 0 :(得分:4)

你的代码有很多问题!首先,way/3有3个而不是4个,所以调用way(A,B,_,_,)显然不会按照你的想法去做。其次,我不知道你试图用(A,_,C,D)做什么。此后的时间段表示谓词的结束!所以下一行D<C.只是一个无法实现的自由浮动查询。然后shortway(A,_,C)基本上是一个事实,有三个单例,但是当前一个是shortway/3子句时它会定义一个shortway/4子句。

这里的正确轨道还不足以尝试恢复。看起来你甚至对Prolog的基础知识都非常困惑。我强烈建议你回到起点重新开始。你不能急于推销Prolog!而且这段代码看起来像是你试图通过撞在一起制造内燃机。

答案 1 :(得分:1)

我写了一些代码来帮助你,但正如https://stackoverflow.com/users/812818/daniel-lyons所说,它比你之前学到的东西更好。

为了解决您的问题,我建议您至少阅读本书的前三章:http://www.learnprolognow.org/lpnpage.php?pageid=online并在第3.4段进行实践会议。

然后,您可以查看我的代码(您可以在此处找到一些代码:Out of local stack error in Prolog route planner

这里是代码

way(madrid, barcelona, 4).
way(barcelona, paris, 5).
way(madrid, londres, 3).
way(londres,paris,1).


shortway(From, To):- findall(Journey, travel(From, To, Journey, _) , Travels_list),
                     findall(Total_distance, travel(From, To, _, Total_distance) , Distances_list),
                     min_member(Y, Distances_list), find_minimum_index(Y, Distance_list, 1, Distance_index), 
                     find_journey(Distance_index, Travels_list, 0, Shortest_path), 
                     format('The shortest path is ~w', [Shortest_path]).


travel(From, To, Journey, Total_distance) :- dif(From, To),
                                             AccDistance is 0,
                                             path(From, To, [From], Journey, AccDistance, Total_distance).


path(From, To, Passed_cities, go(From, To), AccDistance, Total_distance) :- way(From, To, Way_distance),                                                                          
                                                                            Total_distance is AccDistance + Way_distance.


path(From, To, Passed_cities, go(From, Intermediate, GO), AccDistance, Total_distance) :- way(From, Intermediate, Way_distance),
                                                          dif(Intermediate, To),
                                                          \+     member(Intermediate, Passed_cities),
                                                          NewAccDistance is AccDistance + Way_distance,
                                                          path(Intermediate, To, [Intermediate|Passed_cities], GO, NewAccDistance, Total_distance).


min_member(Min, [H|T]) :- min_member_(T, H, Min).
min_member_([], Min, Min).
min_member_([H|T], Min0, Min) :-
                            (   H >= Min0
                            ->  min_member_(T, Min0, Min)
                            ;   min_member_(T, H, Min)
                            ).

find_minimum_index(X, [], N, I) :- fail.
find_minimum_index(X, [X|T], N, I) :- I is N, !.
find_minimum_index(X, [H|T], N, I) :- H \= X, increment(N, N1),  find_minimum_index(X, T, N1, I).

find_journey(I, [H|T], N, Elemento) :- N = I, Elemento = H, !.
find_journey(I, [H|T], N, Elemento) :- N \= I, increment(N, N1), find_journey(I, T, N1, Elemento).

increment(X, X1) :- X1 is X+1.

然后你打电话,例如

?: - shortway(马德里,巴黎)。

它会返回

"The shortest path is go(madrid, londres, go(londres,paris))"

距离是4 而不是

go(madrid, barcelona, go(barcelona, madrid)

距离是9。

总结:呼叫短路/ 2,使用谓词 findall / 3 ,您将分别找到所有可能的路径及其相对距离的列表,然后您将浏览查找最小元素索引的距离列表,并使用它来查找之前找到的所有路径列表中的最短路径。