Вопрос

Я просмотрел подобные вопросы, но не могу найти ничего, что имеет отношение к моей проблеме. Я изо всех сил пытаюсь найти алгоритм или набор «петлей», которые найдут путь от CityA к CityB, используя базу данных

distance(City1,City2,Distance)

факты Что мне удалось сделать до сих пор, но это всегда возвращается write(X), А затем завершается с последней итерацией, что я хочу, чтобы это было делать, но только в определенной степени.

Например, я не хочу, чтобы он распечатал любые имена городов, которые являются мертвыми, или для использования окончательной итерации. Я хочу, чтобы он в основном прошел путь от CityA к CityB, написание названия городов, на которых он идет на пути.

Надеюсь, кто -нибудь может мне помочь!

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).
Это было полезно?

Решение

Я попытался продемонстрировать, как вы можете достичь того, над чем вы работаете, чтобы вы могли лучше понять, как это работает. Так что, поскольку ваш 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 ( +start, +end, +waypoints, +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.

Я надеюсь, что это будет полезно для вас.

Другие советы

Пожалуйста, отделить чистую часть от нечисто write/1, nl/0 но и (==)/2 а также (\==)/2) Пока они полностью переплетаются с вашим чистым кодом, вы не можете ожидать многого.

Вероятно, вам нужна связь между отправной точкой, конечной точкой и пути между ними.

Если этот путь будет ациклическим или вы разрешаете циклы?

Чтобы гарантировать, что элемент X не происходит в списке Xs Используйте цель maplist(dif(X),Xs).Вам не нужны дополнительные вспомогательные предикаты, чтобы сделать это хорошим отношением!

Вы должны вернуть успешный список в качестве переменной Out в all_possible_paths. Затем напишите этот список. Не делайте оба в одной и той же процедуре.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top