Как обработать путь в обходе графа Пролога
Я написал в Прологе:
edge(x, y).
edge(y, t).
edge(t, z).
edge(y, z).
edge(x, z).
edge(z, x).
path(Start, End, Path) :-
path3(Start, End, [Start], Path).
path3(End, End, RPath, Path) :-
reverse(RPath, Path).
path3(A,B,Path,[B|Path]) :-
edge(A,B),
!.
path3(A, B, Done, Path) :-
edge(A, Next),
\+ memberchk(Next, Done),
path3(Next, B, [Next|Done], Path).
Он также заботится о циклических графах, я получаю нерегулярный вывод, когда пытаюсь пройти тот же узел с того же узла.
например: path(x,x,P).
ожидаемый результат должен быть:
P = [x, z, t, y, x]
P = [x, z, y, x]
P = [x, z, x]
Тем не менее, я получаю вывод:
p = [x] ------------> wrong case
P = [x, z, t, y, x]
P = [x, z, y, x]
P = [x, z, x]
Как я могу избавиться от этого нежелательного случая. Спасибо
2 ответа
Мы используем мета-предикат path/4
вместе с edge/2
:
? - путь (ребро, путь, х, последний), ребро (последний, х). Последний = z, путь = [x,y,t,z]; Последний = z, путь = [x,y,z]; Последний = z, путь = [x,z]; ложный.
Хорошо! Выше три ответа - именно то, чего желал ФП в этом вопросе.
Просто для удовольствия давайте рассмотрим все возможные пути, основанные на edge/2
!
?- path(edge,Path,From,To).
From = To , Path = [To]
; From = x, To = y, Path = [x,y]
; From = x, To = t, Path = [x,y,t]
; From = x, To = z, Path = [x,y,t,z]
; From = x, To = z, Path = [x,y,z]
; From = y, To = t, Path = [y,t]
; From = y, To = z, Path = [y,t,z]
; From = y, To = x, Path = [y,t,z,x]
; From = t, To = z, Path = [t,z]
; From = t, To = x, Path = [t,z,x]
; From = t, To = y, Path = [t,z,x,y]
; From = y, To = z, Path = [y,z]
; From = y, To = x, Path = [y,z,x]
; From = x, To = z, Path = [x,z]
; From = z, To = x, Path = [z,x]
; From = z, To = y, Path = [z,x,y]
; From = z, To = t, Path = [z,x,y,t]
; false.
path(Start, End, Path) :-
edge(Start,First),
path3(Start, End, [Start,First], Path).
должно сработать