我目前必须在SWI Prolog中进行某种Wumpus World的实现,并在大小为 NxN 的板上给出所有可能的路径,我已经完成了一些prolog教程,但我不知道该如何做。解决Prolog中的这一特殊任务。我正在设法为我的经纪人提供所有可能的途径,让他们获得金子,仅此而已。它必须从初始位置(X0,Y0)开始。
我附上了到目前为止我已经设法编写的代码。我试图做一个简单的DFS来完成这类工作,但是我在使用变量“ parsing”来完成代码方面很挣扎。
:- dynamic getAllPathsRec/2, agent/2, visited/2, visited/2.
gold(5,5).
worldSize(10).
agent(1,1).
getAllPaths :-
getAllPathsRec(1,1).
getAllPathsRec(X,Y) :-
format(X), format(Y), format('~n'),
gold(X1,Y1),
\+visited(X,Y),
assert(visited(X,Y)),
(X = X1, Y = Y1) -> print('Found GOLD');
move(_,X,Y).
move(right, X, Y) :-
X1 is X + 1,
X1 > 0 , X1 < 11,
getAllPathsRec(X1,Y).
move(left, X, Y) :-
X1 is X - 1,
X1 > 0 , X1 < 11,
getAllPathsRec(X1,Y).
move(up, X, Y) :-
Y1 is Y + 1,
Y1 > 0 , Y1 < 11,
getAllPathsRec(X,Y1).
move(down, X, Y) :-
Y1 is Y - 1,
Y1 > 0 , Y1 < 11,
getAllPathsRec(X,Y1).
我希望以任何可能的方式找到黄金,理想情况下会打印算法采用的每条路径。预先谢谢你。
答案 0 :(得分:2)
编辑:
我已经注意到,对于足够大的电路板,该解决方案存在一些效率问题。 here正在讨论中。当我们得出结果时,我将更新答案。
请谨慎使用#include <optional>
#include <boost/container/flat_set.hpp>
std::optional<boost::container::flat_set<int> > objects;
template<class T>
auto assure_contents(std::optional<T>& opt) -> T&
{
if (opt.has_value())
return *opt;
else
return opt.emplace();
}
void f(int _v)
{
assure_contents(objects).insert(_v);
}
谓词,因为它将永久性地将事实添加到知识库中,并且在尝试其他组合时不会撤消,因此您将无法两次访问同一单元格。
相反,我使用一个额外的参数assert/1
(代表已访问)来处理它,您可以在其中附加在每个探索步骤中处理过的元素。另外,我将每一步中选择的方向存储在列表V
中,以便在找到目标时将其打印出来。
或运算符L
允许在找到目标后不再继续探索同一条路径,然后返回以继续尝试其他组合。
注释:
如果遇到任何可以使用;
的用例,请多加注意,因为它是deprecated。
assert/1
变量在move函数中不是必需的,因为您可以简单地添加4个不同的“实现”并只需追加四个方向即可。
作为建议,请使用事实或知识(也称为“世界尺寸”,“目标位置”和“玩家位置”)作为变量,并且不要对其进行硬编码。调试和尝试不同的参数会更容易。
这里有工作代码和一些输出示例:
_
:- dynamic
getAllPathsRec/2,
agent/2,
visited/2.
gold(3, 3).
worldSize(5).
agent(1, 1).
getAllPaths :-
agent(X, Y),
getAllPathsRec(X, Y, [], []).
getAllPathsRec(X, Y, V, L) :-
hashPos(X, Y, H), \+member(H, V), append(V, [H], VP),
((gold(X, Y), print(L)) ; move(X, Y, VP, L)).
% Hash H from h(X, Y)
hashPos(X, Y, H) :- H is (X*100 + Y).
% Left
move(X, Y, V, L) :-
XP is X - 1, XP > 0,
append(L, [l], LP),
getAllPathsRec(XP, Y, V, LP).
% Right
move(X, Y, V, L) :-
XP is X + 1, worldSize(MS), XP =< MS,
append(L, [r], LP),
getAllPathsRec(XP, Y, V, LP).
% Up
move(X, Y, V, L) :-
YP is Y + 1, worldSize(MS), YP =< MS,
append(L, [u], LP),
getAllPathsRec(X, YP, V, LP).
% Down
move(X, Y, V, L) :-
YP is Y - 1, YP > 0,
append(L, [d], LP),
getAllPathsRec(X, YP, V, LP).