Самый быстрый путь между двумя городами

Мне нужно найти самый быстрый способ путешествовать из одного города в другой. У меня есть что-то вроде

 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).

Я изо всех сил стараюсь, но не могу заставить его работать!


person Veronica    schedule 14.12.2015    source источник
comment
Также ознакомьтесь с этими проблемами: stackoverflow.com/questions / 34257968 / и stackoverflow.com/questions/34251949/   -  person Daniel Lyons    schedule 14.12.2015


Ответы (2)


У вас куча проблем с вашим кодом! Прежде всего, way/3 имеет арность 3, а не 4, поэтому вызов way(A,B,_,_,) явно не приведет к тому, что вы думаете. Во-вторых, я понятия не имею, что вы пытаетесь сделать с (A,_,C,D). Точка после этого означает конец предиката! Итак, следующая строка D<C. - это просто плавающий запрос, который не может быть выполнен. И тогда shortway(A,_,C) - это, по сути, факт с тремя синглетонами, но он будет определять предложение shortway/3, когда предыдущее - предложение shortway/4.

Здесь действительно недостаточно того, что находится на правильном пути, чтобы попытаться восстановиться. Похоже, здесь вы очень запутались даже в основах Prolog. Я настоятельно рекомендую вам вернуться к началу и начать все сначала. Вы не можете спешить с Prolog! И этот код выглядит так, будто вы пытаетесь создать двигатель внутреннего сгорания, ударяя по камням вместе.

person Daniel Lyons    schedule 14.12.2015

Я написал несколько строк кода, чтобы помочь вам, но как https://stackoverflow.com/users/812818/daniel-lyons сказал, это лучше, чем ты выучил что-то более легкое раньше.

Чтобы решить вашу проблему, я советую вам прочитать, по крайней мере, первые 3 главы этой книги: http://www.learnprolognow.org/lpnpage.php?pageid=online и проведите практическое занятие по пункту 3.4.

Затем вы можете взглянуть на мой код (вы можете найти его объяснение здесь: Ошибка вне локального стека в планировщике маршрутов Prolog.

Вот код

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.

Тогда вы звоните, например

?: - шортвей (мадрид, париж).

и он вернется

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

какое расстояние, 4, а не

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

расстояние 9.

Подводя итог: вызывая shortway / 2, с предикатами findall / 3 вы найдете списки всех возможных путей и их относительные расстояния, соответственно, затем вы просмотрите список расстояний, чтобы найти индекс минимального элемента и, таким образом, используя его, чтобы найти кратчайший путь из списка всех ранее найденных путей.

person s.dallapalma    schedule 14.12.2015
comment
но проблема в том, что я должен использовать этот предикат как короткую дорогу (A, B, C, D): - где C - это список маршрутов между A и B, а расстояние D. Пожалуйста, помогите мне, я в отчаянии! - person Veronica; 15.12.2015
comment
просто отредактируйте правило shortway / 2 с помощью shortway (From, To, Shortest_path, Shortest_distance). Затем удалите формат предложения и вставьте find_journey (Distance_index, Distances_list, 0, Shortest_distance). Если вы предпочитаете что-то вроде [madrid, londres, paris], а не go (madrid, londres, go (londres, paris)), попробуйте лучше понять код и попробуйте отредактировать его самостоятельно, прежде чем обращаться за помощью;). - person s.dallapalma; 15.12.2015
comment
dallapalma ты самый лучший спасибо! Честно говоря, я изучаю право и не знаю, почему они заставляют нас делать это в этом семестре, но я больше не буду этого делать, поэтому я совсем не разбираюсь в компьютерах :( - person Veronica; 15.12.2015
comment
Есть много вещей, которые у меня нет шанса связаться с вами? [email protected] - person Veronica; 15.12.2015
comment
Я только что отправил вам сообщение. Я очень благодарен. - person Veronica; 15.12.2015