Я работаю над решением проблемы классических миссионеров (M) и каннибалов (C), начальное состояние - 3 M и 3 C на левом берегу, а состояние цели - 3M, 3C на правом берегу. У меня есть основная функция в моей программе, и мне нужно реализовать стратегию поиска, такую как BFS и DFS.Решать каннибалов/миссионеров, используя поиск по ширине (BFS) в Prolog?
В основном мой код учится в Интернете. Пока я могу успешно запустить программу с помощью метода DFS, но я пытаюсь запустить с BFS, он всегда возвращает false. Это моя первая программа SWI-Prolog, я не могу найти, где проблема с моим кодом.
Вот часть моего кода, надеюсь, что вы можете помочь мне найти проблему его
solve2 :-
bfs([[[3,3,left]]],[0,0,right],[[3,3,left]],Solution),
printSolution(Solution).
bfs([[[A,B,C]]],[A,B,C],_,[]).
bfs([[[A,B,C]|Visisted]|RestPaths],[D,E,F],Visisted,Moves) :-
findall([[I,J,K],[A,B,C]|Visited]),
(
move([A,B,C],[I,J,K],Description),
safe([I,J,K]),
not(member([I,J,K],Visited)
),
NewPaths
),
append(RestPaths,NewPaths,CurrentPaths),
bfs(CurrentPaths,[D,E,F],[[I,J,K]|Visisted],MoreMoves),
Moves = [ [[A,B,C],[I,J,K],Description] | MoreMoves ].
move([A,B,left],[A1,B,right],'One missionary cross river') :-
A > 0, A1 is A - 1.
% Go this state if left M > 0. New left M is M-1
.
.
.
.
.
safe([A,B,_]) :-
(B =< A ; A = 0),
A1 is 3-A, B1 is 3-B,
(B1 =< A1; A1 =0).
Я использую FindAll найти все возможные пути, прежде чем перейти к следующему уровню. Только один проход safe() будет рассматриваться как возможное следующее состояние. Государство не будет использовать, если оно уже существует. Поскольку моя программа может работать с DFS, я думаю, что нет ничего плохого в предикате move() и safe(). Мой предикат BFS меняет базу на мой код DFS, но он не работает.
'' findall'/3' имеет Арность 3, но в использовании только один аргумент в коде. Вы также используете переменные 'Visisted' и' Посещенные'. Они должны быть одинаковыми? Попробуйте вставить свой код, чтобы сделать его более читаемым, и добавьте некоторые комментарии. В противном случае трудно понять, чего вы пытаетесь достичь с помощью вызова 'findall/3' и следующего блока. – twinterer