极大极小算法和AlphaBeta剪枝算法

作为菜鸟,先贴上参考博文:

1.极小极大算法

2.<<CS 161 Recitation Notes - The Minimax Algorithm>>

3.《PC游戏编程-人机博弈》-作者陈其,王小春

本文目录:

直观图解
    伪代码
    习题实战
适用范围:极小极大算法常用于零和博弈游戏中,零和博弈指参与博弈的各方,在严格竞争下,一方的收益必然意味着另一方的损失,博弈各方的收益和损失相加总和永远为“零”,双方不存在合作的可能。博弈游戏,目的是寻找最优的方案使得自己能够利益最大化。

先来个直观理解

极大极小算法:

基本思想就是假设自己足够聪明,总是选择最利于自己(A)的方案,而对手同样聪明,总是选择最不利与对方即A方的方案。

设:正方形代表自己(A),圆代表对手(B),节点的每个孩子节点代表一个候选方案。

                        

上图中显示了所有候选方案。让我们如下分析:(注意:根节点为当前局面,某一结点的子节点为下一步走法产生的局面。图中的所有数字都是A的利益值,可以由估值函数得出,越大越有利于A)

                                            

假设A选择第一个方案,B有两个候选方案,B为了使得A利益最小化,所有在7和3中选择了3,所以A只能获得3。  

                                               

假设A选择第二个方案,B只有一个选择,A最终可以获得15。

                     

假设A选择第三个方案,B有4个可选方案,为了使得A利益最小,B选择第一个方案,则A只能获得利益1。

                        

 

A为了使得自己利益最大,所以A会选择第二个方案,即获得利益15。

从上图可以看出,B总是选择候选方案中的最小值,而A总是选择候选方案中的最大值,极小极大的名字也就源于此。该算法使用深度优先搜索(Depth First Search)遍历决策树来填充树中间节点的利益值,叶子节点的利益值通常是通过一个利益评估函数算

有时候为了得到较好的效果不得不增加搜索树的深度,这样就增加了大量的计算。为了加快计算速度,减少计算量,可以使用Alpha-Beta剪枝算法(Alpha Beta Pruning)对搜索树进行剪枝。因为搜索树中有很多分支不需要遍历。

Alpha-Beta剪枝算法(Alpha Beta Pruning) 

Alpha-Beta剪枝用于裁剪搜索树中没有意义的不需要搜索的树枝,以提高运算速度。

假设α为下界,β为上界,对于α ≤ N ≤ β:

若 α ≤ β  则N有解。

 若 α > β 则N无解。

 下面通过一个例子来说明Alpha-Beta剪枝算法。

                   

上图为整颗搜索树。这里使用极小极大算法配合Alpha-Beta剪枝算法,正方形为自己(A),圆为对手(B)。

初始设置α为负无穷大,β为正无穷大。 

                                  

对于B(第四层)而已,尽量使得A获利最小,因此当遇到使得A获利更小的情况,则需要修改β。这里3小于正无穷大,所以β修改为3。

                                  

(第四层)这里17大于3,不用修改β。

                                  

对于A(第三层)而言,自己获利越大越好,因此遇到利益值大于α的时候,需要α进行修改,这里3大于负无穷大,所以α修改为3

                                   

B(第四层)拥有一个方案使得A获利只有2,α=3,  β=2, α > β, 说明A(第三层)只要选择第二个方案, 则B必然可以使得A的获利少于A(第三层)的第一个方案,这样就不再需要考虑B(第四层)的其他候选方案了,因为A(第三层)根本不会选取第二个方案,多考虑也是浪费.

                                        

B(第二层)要使得A利益最小,则B(第二层)的第二个方案不能使得A的获利大于β, 也就是3. 但是若B(第二层)选择第二个方案, A(第三层)可以选择第一个方案使得A获利为15, α=15,  β=3, α > β, 故不需要再考虑A(第三层)的第二个方案, 因为B(第二层)不会选择第二个方案.

A(第一层)使自己利益最大,也就是A(第一层)的第二个方案不能差于第一个方案, 但是A(第三层)的一个方案会导致利益为2, 小于3, 所以A(第三层)不会选择第一个方案, 因此B(第四层)也不用考虑第二个方案.

 

当A(第三层)考虑第二个方案时,发现获得利益为3,和A(第一层)使用第一个方案利益一样.如果根据上面的分析A(第一层)优先选择了第一个方案,那么B不再需要考虑第二种方案,如果A(第一层)还想进一步评估两个方案的优劣的话, B(第二层)则还需要考虑第二个方案,若B(第二层)的第二个方案使得A获利小于3,则A(第一层)只能选择第一个方案,若B(第二层)的第二个方案使得A获利大于3,则A(第一层)还需要根据其他因素来考虑最终选取哪种方案.

 再来看看伪代码

极大极小算法伪代码:


int MaxMin(position p,int d)

{

    int bestvalue,value;

    if(game over)   //检查游戏是否结束 

        return evaluation(p);// 游戏结束,返回估值 

    if(depth<=0)    //检查是否是叶子节点 

        return evaluation(p);//叶子节点,返回估值 

    if(max)         //极大值点 

        bestvalue=-INFINTY;

    else            //极小值点 

        bestvalue=INFINTY;

    for(each possibly move m)

    {

        MakeMove(m);    //走棋 

        value=MaxMin(p,d-1);

        UnMakeMove(m);  //恢复当前局面 

        if(max)

            bestvalue=max(value,bestvalue);//取最大值 

        else

            bestvalue=min(value,bestvalue);//取最小值 

    }

    return bestvalue;

}

//  end of MaxMin algorithm
 

 

 

 

将Alpha剪枝和Beta剪枝加入MaxMin搜索就得到AlphaBeta搜索,AlphaBeta搜索的伪代码如下:


//伪代码,Alpha剪枝和Beta剪枝+MaxMin搜索

int AlphaBeta(nPlay,nAlpha,nBeta)

{

    if(game over)

        return Eveluation;   //胜负已分,返回估值

    if(nPly==0)

        return  Eveluation;  //叶子节点返回估值

    if(Is Min Node)          //判断 节点类型 

    {        // 极小值节点

        for(each possible move m)

        {

            make move m;      //生成新节点

            score=AlphaBeta(nPly-1,nAlpha,nBeta)//递归搜索子节点

            unmake move m;//撤销搜索过的节点

            if(score<nBeta)

            {

                nBeta=score;//取极小值

                if(nAlpha>=nBeta)

                    return nAlpha;//alpha剪枝,抛弃后继节点 

             } 

        }

        return nBeta;//返回最小值 

    }

    else

    {//取极大值的节点 

        for(each possible move m)

        {

            make move m;      //生成新节点

            score=AlphaBeta(nPly-1,nAlpha,nBeta)//递归搜索子节点

            unmake move m;//撤销搜索过的节点

            if(score>nAlpha)

            {

                nAlpha=score;//取极小值

                if(nAlpha>=nBeta)

                    return nBeta;//nBeta剪枝,抛弃后继节点 

             } 

        }

        return nAlpha;//返回最小值 

    } 

//end of AlphaBeta pseudocode
 

来点真的

习题链接,真枪实战

1.三角点格棋

2.Stake Your Claim

 

3.Find the Winning Move
 

 

很抱歉,根据您提供的引用内容,我无法确定您所指的“极大极小值算法”具体是哪一种算法。不过,我可以为您介绍一下常见的极值点检测算法——Harris角点检测算法。 Harris角点检测算法是一种经典的计算机视觉算法,用于检测图像中的角点。其基本思想是通过计算图像中每个像素点的局部自相关矩阵,来判断该点是否为角点。具体来说,该算法通过以下步骤实现: 1.计算图像中每个像素点的梯度值和梯度方向。 2.对于每个像素点,计算其周围像素的梯度值和梯度方向,并根据这些值构建一个局部自相关矩阵。 3.对于每个局部自相关矩阵,计算其特征值,判断该点是否为角点。如果该点的两个特征值都比较大,则说明该点是角点。 4.为了避免检测到重复的角点,可以使用非极大值抑制算法对角点进行筛选。 下面是一个简单的Python实现示例: ```python import cv2 import numpy as np # 读取图像 img = cv2.imread('image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 计算梯度 dx = cv2.Sobel(gray, cv2.CV_64F, 1, 0) dy = cv2.Sobel(gray, cv2.CV_64F, 0, 1) # 计算局部自相关矩阵 w = 5 # 窗口大小 k = 0.04 # Harris响应函数参数 h, w = gray.shape R = np.zeros((h, w)) for i in range(w): for j in range(h): M = np.zeros((2, 2)) for u in range(i - w // 2, i + w // 2 + 1): for v in range(j - w // 2, j + w // 2 + 1): if u < 0 or u >= w or v < 0 or v >= h: continue dx2 = dx[v, u] ** 2 dy2 = dy[v, u] ** 2 dxy = dx[v, u] * dy[v, u] M[0, 0] += dx2 M[0, 1] += dxy M[1, 0] += dxy M[1, 1] += dy2 det = np.linalg.det(M) trace = np.trace(M) R[j, i] = det - k * trace ** 2 # 非极大值抑制 corners = [] for i in range(w): for j in range(h): if R[j, i] > 0.01 * R.max() and R[j, i] == np.max(R[max(0, j - 1):min(j + 2, h), max(0, i - 1):min(i + 2, w)]): corners.append((i, j)) # 在图像中绘制角点 for x, y in corners: cv2.circle(img, (x, y), 3, (0, 0, 255), -1) # 显示图像 cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值