Пролог список пути и избегать определенного маршрута - PullRequest
3 голосов
/ 29 ноября 2011

У меня есть список данных

city(portsmouth,london).
city(london,bristol).
city(portsmouth,plymouth).
city(plymouth,london).
city(london,plymouth).
city(london,birmingham).
city(birmingham,bristol).

Я использую метод, который

 ?-op(150,xfy,pathto).
 ?-op(150,xfy,avoid).
 X pathto Y:- city(X,Y).

и не так уверен, можно использовать как

X pathto Y avoid Z:-
    findall(Path,avoid_country(X,Y,Z,Path),Paths),write(Paths),nl.  

avoid_path(Start, End, Avoid,[]) :- 
    country(Start, End).

avoid_path(Start,End,Avoid,[Path|Result]):-
    city(Start,Path),
    Path\== Avoid,
    avoid_path(Path, End,Avoid, Result).

на самом деле работает отлично, без всяких избеганий и пути \ == Avoid,

результат ошибки

   | ?- portsmouth to bristol avoid birmingham.
   Error 1, Backtrack Stack Full, Trying city/2

это должно быть [[Лондон], [Плимут, Лондон]].

Ответы [ 2 ]

1 голос
/ 29 ноября 2011

Хорошо, так: сначала у вас есть петля в ваших фактах: (Лондон, Плимут) и (Плимут, Лондон). Это означает, что любая попытка возврата никогда не закончится.
Тогда я не уверен, что вы можете использовать 2 оператора таким образом, но так как я не уверен, другие люди будут более проницательными в этом вопросе:)
Я взял это соглашение: «Портсмут в Бристоль» [Лондон, Бирмингем] означает «от Портсмута до Бристоля», избегая Лондона и Бирмингема (я принял это соглашение, чтобы не задавать вопросы операторам), вот рабочий код, который отслеживает посещенные города, чтобы избежать бесконечности возможности:

city(portsmouth,london).
city(london,bristol).
city(portsmouth,plymouth).
city(plymouth,london).
city(london,plymouth).
city(london,birmingham).
city(birmingham,bristol).

:- op(150, xfy, to).

Start to End-Avoid :-
    findall(Waypoint, get_waypoints(Start, End, [Start], Avoid, Waypoint), Waypoints),
    !,
    write(Waypoints).
Start to End :-
    findall(Waypoint, get_waypoints(Start, End, [Start], [], Waypoint), Waypoints),
    write(Waypoints).

get_waypoints(Start, End, _Visited, _Avoid, []) :- 
    city(Start, End).
get_waypoints(Start, End, Visited, Avoid, [Waypoint|Result]) :-
    city(Start, Waypoint),

не ходите по городам, чтобы избежать ...

    \+ member(Waypoint, Avoid),

эта проверка позволяет нам не зацикливаться. Таким образом, откат заканчивается.

    \+ member(Waypoint, Visited),
    get_waypoints(Waypoint, End, [Waypoint|Visited], Avoid, Result).
1 голос
/ 29 ноября 2011

Факты содержат эти два:

city(plymouth,london).
city(london,plymouth).

, и ваш код (который содержит некоторые несоответствия) не проверяет, был ли город уже посещен.Это заставит findall/3 собрать все возможные маршруты [Лондон], [Плимут, Лондон], [Плимут, Лондон, Плимут, Лондон], ..., которые рано или поздно приведут к истощению памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...