【问题标题】:Depth limited alpha-beta in prolog序言中的深度限制α-β
【发布时间】:2021-02-01 19:40:17
【问题描述】:

我正在 Prolog 中构建一个国际象棋引擎。 “人工智能序言编程”中的 alpha-beta 不受深度限制。 由于无法在国际象棋中搜索整棵树,我正在尝试修改书中的代码以限制深度,但它无法正常工作。

这是书的代码:

alphabeta(Pos, Alpha, Beta, GoodPos, Val) :-
   moves(Pos, PosList), !,
   boundedbest( PosList, Alpha, Beta, GoodPos, Val)
    ;
get_pos_value(Pos,Val).                             % static value of Pos

boundedbest([Pos | PosList], Alpha, Beta, GoodPos, GoodVal) :-
   alphabeta( Pos, Alpha, Beta, _, Val),
   goodenough(PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal).

goodenough([],_,_,Pos, Val, Pos, Val) :- !.               % no other candidate

goodenough(_, Alpha, Beta, Pos, Val, Pos, Val) :-
   min_to_move(Pos), Val > Beta, !;                  % Maximizer attained upper bound
   max_to_move(Pos), Val < Alpha, !.                     % Minimizer attained lower bound

goodenough( PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal) :-
   newbounds( Alpha, Beta, Pos, Val, NewAlpha, NewBeta),  % Refine bounds
   boundedbest(PosList, NewAlpha, NewBeta, Pos1, Val1),
   betterof( Pos, Val, Pos1, Val1, GoodPos, GoodVal).

newbounds(Alpha, Beta, Pos, Val, Val, Beta) :-
   min_to_move(Pos), Val > Alpha, !.                    % Mazximizer increased lower bound

newbounds(Alpha, Beta, Pos, Val, Alpha, Val):-
   max_to_move(Pos), Val < Beta, !.                     % Minimizer decreased upper bound

newbounds( Alpha, Beta, _,_,Alpha, Beta).                   % otherwise bounds unchanged.

betterof(Pos, Val, Pos1, Val1, Pos, Val) :-                 % Pos better than Pos1
   min_to_move(Pos), Val > Val1, !;
   max_to_move(Pos), Val < Val1, !.

betterof(_,_,Pos1,Val1,Pos1,Val1).                          % otherwise Pos 1 better

我尝试将其修改为深度限制是:

alphabeta(Pos, Alpha, Beta, Pos, Val, 0) :- % max depth of search recieved
   get_pos_value(Pos,Val).                      % static value of Pos


alphabeta(Pos, Alpha, Beta, GoodPos, Val, Depth) :-
   Depth > 0,
   moves(Pos, PosList), !,
   boundedbest( PosList, Alpha, Beta, GoodPos, Val,Depth).


alphabeta(Pos, Alpha, Beta, Pos, Val, Depth) :-
   Depth > 0,
   get_pos_value(Pos,Val).


boundedbest([Pos | PosList], Alpha, Beta, GoodPos, GoodVal,Depth) :-
   Depth is Depth - 1,
   alphabeta( Pos, Alpha, Beta, _, Val,Depth1),
   goodenough(PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal).

goodenough([],_,_,Pos, Val, Pos, Val) :- !.               % no other candidate

goodenough(_, Alpha, Beta, Pos, Val, Pos, Val) :-
   min_to_move(Pos), Val > Beta, !;                  % Maximizer attained upper bound
   max_to_move(Pos), Val < Alpha, !.                     % Minimizer attained lower bound

goodenough( PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal) :-
   newbounds( Alpha, Beta, Pos, Val, NewAlpha, NewBeta),  % Refine bounds
   boundedbest(PosList, NewAlpha, NewBeta, Pos1, Val1,_),
   betterof( Pos, Val, Pos1, Val1, GoodPos, GoodVal).

newbounds(Alpha, Beta, Pos, Val, Val, Beta) :-
   min_to_move(Pos), Val > Alpha, !.                % Mazximizer increased lower bound

newbounds(Alpha, Beta, Pos, Val, Alpha, Val):-
   max_to_move(Pos), Val < Beta, !.                     % Minimizer decreased upper bound

newbounds( Alpha, Beta, _,_,Alpha, Beta).                   % otherwise bounds unchanged.

betterof(Pos, Val, Pos1, Val1, Pos, Val) :-                 % Pos better than Pos1
   min_to_move(Pos), Val > Val1, !;
   max_to_move(Pos), Val < Val1, !.

betterof(_,_,Pos1,Val1,Pos1,Val1).                          % otherwise Pos 1 better

我将不胜感激。

【问题讨论】:

  • 仅供参考:Ivan Bratko 的“Prolog Programming for Artificial Intelligence”第 4 版,第 24.3 节 alpha-beat 算法:minimax 的有效实现,第 585 页
  • 是的,第 585 页上的代码没有深度限制,不适用于国际象棋游戏,它使用 alpha-beta 进行修剪,但搜索到树的底部。
  • 您使用的是哪个 Prolog?可能有类似“深度限制的调用”或类似的东西。喜欢这个:swi-prolog.org/pldoc/doc_for?object=call_with_depth_limit/3

标签: prolog chess minimax alpha-beta-pruning


【解决方案1】:

您的代码中有错字。更重要的是,SWI-Prolog 为您发现并诊断出您的代码中存在拼写错误。不要忽略它的警告。

看:

Warning: /home/isabelle/chess.pl:1:
    Singleton variables: [Alpha,Beta]
Warning: /home/isabelle/chess.pl:11:
    Singleton variables: [Alpha,Beta]
Warning: /home/isabelle/chess.pl:16:
    Singleton variables: [Depth1]
Warning: /home/isabelle/chess.pl:40:
    Singleton variables: [Pos1]

具体来说,在这个从第 16 行开始的子句中:

boundedbest([Pos | PosList], Alpha, Beta, GoodPos, GoodVal,Depth) :-
   Depth is Depth - 1,
   alphabeta( Pos, Alpha, Beta, _, Val,Depth1),
   goodenough(PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal).

您对Depth1 的使用表明您似乎理解需要计算一个新值并将其传递给递归。但是你忘了在前一行使用这个变量:

Depth is Depth - 1,

这应该在左侧使用Depth1

即使尝试测试具有单例警告的代码也是错误的,因为单例警告通常表明存在非常严重的错误。这里就是这种情况。当您看到单例警告时,您应该做的第一件事是理解并修复它——与程序的任何其他交互都可能毫无意义。

确实,其中一些警告是“良性的”:第一行子句的警告似乎并未表明该子句中的错误。也许您已经看到了其中的一些警告,并认为它们是无害的。情况恰恰相反:接受这种“虚假”的单例警告意味着您冒着严重警告的风险。

(我没有测试更正后的程序,因为它不完整是可以理解的。)

【讨论】:

  • 不错的答案。 Prolog 警告和错误的一个好处是我从来没有发现它们浪费时间来检查原因。 90% 的情况下,我所做的只是代码中的一些错误,例如拼写错误,或者遗漏了一个参数或一个参数在错误的位置。 8% 的时间变量只需要是一个无关变量,例如__info,有 2% 的时间我发现我的算法存在严重错误。
  • 谢谢,我修正了错字,但我仍然没有得到预期的结果
  • 如果没有所有代码、正在运行的查询、得到的结果以及预期的结果,很难判断。 如果这本书的代码以允许您在线共享的方式获得许可,您可以在swish.swi-prolog.org 提供一个完整的示例并将我们链接到它。否则,您可以在不侵犯版权的情况下添加到问题中的任何信息都可能会有所帮助。
  • 我只是想获取该书的代码并对其进行修改以限制深度
猜你喜欢
  • 2014-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多