【问题标题】:Translating a tabled predicate from b-prolog to gprolog将表谓词从 b-prolog 转换为 gprolog
【发布时间】:2017-04-25 03:11:31
【问题描述】:

为了好玩,我一直在尝试使用 Warnsdorf 规则在 gprolog 中编写 Knight's Tour (https://en.wikipedia.org/wiki/Knight%27s_tour) 求解器。

我发现另一个 SO 帖子询问在 B-pr​​olog 中提供解决方案的效率: knight's tour efficient solution.

我的问题出现在以下部分:

:- table warnsdorff(+,+,+,+,+,-,-,min).
warnsdorff(R, C, X, Y, Visits, NewX, NewY, Score) :-
    possible_knight_moves(R, C, X, Y, Visits, NewX, NewY),
    possible_moves_count(R, C, NewX, NewY, [(NewX, NewY) | Visits], Score).

B-prolog 具有表格谓词,而 gprolog 没有。我在尝试将表格部分转换为 gprolog 时遇到了很大的困难。在实践中,该函数应该返回从当前位置开始的移动,该移动会导致从新位置移动最少次(随机选择平局)。

任何帮助将不胜感激。干杯!

【问题讨论】:

标签: prolog predicate declarative knights-tour


【解决方案1】:

对于这个问题,表格可能是多余的。由于Visits 列表已经在求解时进行,所以只需使用memberchk/2。我在 SWI-Prolog 中得到了这个解决方案(顺便说一句,实现了表格,但无法使用您链接到的原始编码解决难题):

?- time(knight(8, 8, 1, 1, [], Path))...
% 19,973 inferences, 0.019 CPU in 0.019 seconds (100% CPU, 1047591 Lips)
[(1,1),(2,3),(1,5),(2,7),(4,8),(6,7),(8,8),(7,6),(6,8),(8,7),(7,5),(8,3),(7,1),(5,2),(3,1),(1,2),(2,4),(1,6),(2,8),(3,6),(1,7),(3,8),(5,7),(7,8),(8,6),(7,4),(8,2),(6,1),(4,2),(2,1),(1,3),(3,2),(5,1),(6,3),(8,4),(7,2),(5,3),(4,1),(2,2),(1,4),(3,3),(2,5),(4,4),(6,5),(4,6),(3,4),(5,5),(4,3),(6,2),(8,1),(7,3),(5,4),(3,5),(4,7),(2,6),(1,8),(3,7),(4,5),(6,4),(5,6),(7,7),(5,8),(6,6),(8,5)]

如果你愿意,我可以向你展示 Warnsdorff 规则。我使用 setof/3 来获得最小计数,加入 possible_knight_moves/7possible_moves_count/6

编辑

根据需要:

warnsdorff(R, C, X, Y, Visits, NewX_, NewY_) :-
    setof((Count, NewX, NewY), (
              possible_knight_moves(R, C, X, Y, Visits, NewX, NewY),
              possible_moves_count(R, C, NewX, NewY, [(NewX, NewY) | Visits], Count)
          ), [(_, NewX_, NewY_)|_]).

为清楚起见,我已将输出变量 NewX_、NewY_ 重命名,但这无关紧要 - 它也适用于原始命名。

【讨论】:

  • 我同意,但它确实使代码更简单。如果你能展示你的 Warnsdorff 规则,那将不胜感激。我不太清楚你在 setoff/3 中使用什么作为目标。
  • 啊,这很简单。我想在凌晨 2 点尝试在 Prolog 中思考并不是要走的路。当 not 子句 (\+memberchk((NewX, NewY), Visits)) 被赋予一个已经在列表中的 NewX 和 NewY 时,我遇到了奇怪的问题,其中 possible_knight_moves/7 返回 'no'。在此发生之前,它进行了大约 15 次迭代。您是否修改了任何其他部分?
  • 更正:它失败了,因为它找不到另一个动作。反正我之前的评论没有任何意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多