微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我怎样才能返回 alpha-beta 算法的下一步?

如何解决我怎样才能返回 alpha-beta 算法的下一步?

我正在实现一个人工智能来玩井字游戏,我正在使用 alpha-beta 算法来搜索最佳移动。下面是我到目前为止的代码。我设法使算法起作用——状态的值似乎是正确的,但我无法返回正确的下一步/棋盘。

当我执行目标 Board = ['-','-','o','-'],alpha_beta(max,Board,V,NB). 时,这是输出

?- Board = ['-',NB).

Board = [-,-,o,-],V = 0,NB = [-,x].

V 是正确的(它表示比赛的结果将是平局),但 NB,代表 'x' 玩家的下一步行动,不是。强>

测试,我击败了 AI,这不应该发生什么。在图像中,我多次执行目标,模拟 Tic Tac Toe 比赛。 AI 播放“x”符号。关于输出:第一个棋盘是当前棋盘,作为输入提供的棋盘,第二个棋盘是NextBoard,AI 做出的移动:

Testing the AI

我尝试了一些东西。我尝试使用 guitracer,我尝试阅读其他实现,但找不到适合我的实现的解决方案。谁能告诉我我做错了什么?

alpha_beta(max,Value,NextBoard):-
    ab_minimax(max,-inf,inf,NextBoard).
    
ab_minimax(max,_,-1,NextBoard):-
    is_winning_state_o(Board),!.
ab_minimax(min,1,NextBoard):-
    is_winning_state_x(Board),!. 
ab_minimax(_,NextBoard):-
    is_a_draw(Board),!.
ab_minimax(max,Alfa,Beta,NextBoard):-
    children(Board,max,Children),ab_max_children(Children,NB,NextBoard).
ab_minimax(min,min,ab_min_children(Children,NextBoard).

ab_max_children([],Max,NextBoard,NextBoard).
ab_max_children([H|T],Max1,NextBoard):-
    ab_minimax(min,H,NextBoardX),( 
        Value > Beta -> % Beta cut
            Max = Beta,NextBoard = H
        ; (
            max(Value,Alfa1),% updates Alpha
            max(Value,Max2),(Max2 == Value -> NB1 = H; NB1 = NB),ab_max_children(T,Alfa1,Max2,NB1,NextBoard)
        )
    ).

ab_min_children([],Min,NextBoard).
ab_min_children([H|T],Min1,(
        Alfa > Value -> % Alpha cut
            Min = Alfa,NextBoard = H
        ; (
            min(Value,Beta1),% updates Beta
            min(Value,Min2),(Min2 == Value -> NB1 = H; NB1 = NB),ab_min_children(T,Beta1,Min2,NextBoard)
        )
    ).

is_winning_state_x(S) :-
    winning_state_x(S),!.

winning_state_x(['x','x',_]). % [1,2,3]
winning_state_x([_,_]). % [4,5,6]
winning_state_x([_,'x']). % [7,8,9]
winning_state_x(['x',4,7]
winning_state_x([_,_]). % [2,8]
winning_state_x([_,'x']). % [3,6,'x']). % [1,9]
winning_state_x([_,_]). % [3,7]

is_winning_state_o(S) :-
    winning_state_o(S),!.

winning_state_o(['o',3]
winning_state_o([_,6]
winning_state_o([_,'o']). % [7,9]
winning_state_o(['o',7]
winning_state_o([_,8]
winning_state_o([_,'o']). % [3,'o']). % [1,9]
winning_state_o([_,7]

has_empty_position(['-'|_]) :- !.
has_empty_position([_|T]) :- has_empty_position(T).

is_a_draw(S) :-
    not(has_empty_position(S)).

children(Board,Player,Children) :-
    findall(NewBoard,make_move(Player,NewBoard),Children).

make_move(max,['-'|T],['x'|T]).
make_move(min,['o'|T]).
make_move(Player,[H|T1],[H|T2]) :- make_move(Player,T1,T2).

解决方法

问题是,下一步的“正确”移动是什么,因为通常有多个最佳移动。

您正在做的是评估您董事会的孩子。上表显示了每个孩子的价值、当前的 Alpha 和当前的 Beta:

  [[x,-,o,-],-inf,inf]
  [[-,x,x],inf]

既然所有的孩子都有相同的价值,那么下一个板当然是最后一个孩子。

有两个问题:

  1. 您以这样一种方式实施它,即对于每个 Board,您最多有一个 Nextboard,而可能有多个最佳 Nextboard。

  2. 我认为您对孩子的评价是错误的。当我运行良好的旧极小极大时,我得到:

[x,-]  0
[-,-] -1
[-,-] 0
[-,x] -1

Alpha-beta 剪枝不应该只考虑某些替代方案,从而加快搜索速度,但产生相同的结果吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。