极小化极大算法及Alpha-beta剪枝

初学者的个人笔记,不足之处还请指正,谢谢


极小化极大算法(minimax) L'algorithm minimax

极小化极大算法是一个深度优先的搜索算法,树形结构递归,一般在棋类等两方较量的游戏和程序中运用较多,如tic-tac-toe

它需要满足零总和博弈,比如在一场棋类比赛中,我方得分,对方失分,总分值永远为0或者某一常数

因此,我们为了获胜,即需要最大化我方利益(Max),最小化对方利益(Min)

伪代码如下(来自Wikipedia):

function minimax(node, depth)
    if node is a terminal node or depth = 0
        return the heuristic value of node
    if the adversary is to play at node
        let α := +foreach child of node
            α := min(α, minimax(child, depth-1))
    else {we are to play at node}
        let α := -foreach child of node
            α := max(α, minimax(child, depth-1))
    return α

第一个if伪代码块指出了函数递归的两个出口,一是depth=0即到达了层数顶点,游戏结束,二是递归到了某一节点,程序无法再进行,或者已经有一方获胜。

第二个if伪代码块指出,当处于对方节点时,取最小值

否则else 位于我方节点时,取最大值

由于minimax算法是一个树形结构,所以总共需要计算n的x次方个结果,对于棋盘比较大的游戏来说,计算量成几何倍数增长,于是我们需要用到Alpha-beta剪枝,来优化这个算法


Alpha-beta剪枝 L'algorithme Alpha-beta

根据上文提到的,alpha-beta剪枝实际上就是minimax的升级版本

将minimax的搜索树,剪裁掉无意义无需搜索的枝干以提升搜索效率,减少工作量

伪代码如下(来自Wikipedia):

01 function alphabeta(node, depth, α, β, maximizingPlayer) // node = 节点,depth = 深度,maximizingPlayer = 大分玩家
02      if depth = 0 or node是终端节点
03          return 节点的启发值
04      if maximizingPlayer
05          v := -∞
06          for 每个子节点
07              v := max(v, alphabeta(child, depth - 1, α, β, FALSE)) // child = 子节点
08              α := max(α, v)
09              if β ≤ α
10                  break // β裁剪
11          return v
12      else
13          v := ∞
14          for each 每个子节点
15              v := min(v, alphabeta(child, depth - 1, α, β, TRUE))
16              β := min(β, v)
17              if β ≤ α
18                  break // α裁剪
19          return v

由于我们的每一步都是为了预测上一层的走向,每一层自己为(max)α ,对手为(min)β
当树形结构到达 α >= β 的时候,无论接下来的子节点为几,都会小于等于β,因为子节点为对手取最小值min
而自己要取的是max,所以无论接下来出现的是几都不重要了
至此,我们就可以将右侧的树枝精减掉,不需要再耗费时间去计算

后续会补充python代码及手画推导








你可能感兴趣的:(机器学习算法)