人工智能:一种现代方法学习笔记(第五章)——对抗搜索

博弈概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

MinMax算法

极小极大算法常用于二人博弈游戏,目的是寻找最优的方案使得自己能够利益最大化。基本思想就是假设自己(A)足够聪明,总是能选择最有利于自己的方案,而对手(B)同样足够聪明,总会选择最不利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)对搜索树进行剪枝。因为搜索树中有很多分支不需要遍历。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
Max是要让自己的利益最大化,Min要让对手的利益最小化
零和博弈:参与博弈的双方,在严格竞争下,一方的收益必然对应另一方的损失,博弈双方的收益和损失相加和永远是零
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
5.2.1极小极大算法
递归算法自上而下一直前进到树的叶子节点,递归回溯通过搜索树把极小极大值回传。
每一步都是最小化敌方的最大收益。

5.2.2多人博弈时的最优决策
超过两个人的博弈利用MINIMAX算法,由于之前研究的两人博弈一方得分可以反应另一方得分,故仅用一个数值表示状态得分,对于多人游戏,应该使用向量值替换单一效用值。每个节点的回传至是该选手在节点的后继者效用值向量中选择的结果。多人博弈通常会涉及在游戏选手之间出现正式或非正式联盟的情况。

博弈搜索实验

class MinimaxAgent(MultiAgentSearchAgent):
    """
      Your minimax agent (question 2)
    """
    def getAction(self, gameState):
        "*** YOUR CODE HERE ***"
      #  util.raiseNotDefined()
        return self.MinMaxSearch(gameState,0,1)
    
    def MinMaxSearch(self,gameState,agentIndex,currentdepth):
        if currentdepth > self.depth or gameState.isWin() or gameState.isLose():
              return self.evaluationFunction(gameState)

        legalMoves = [action for action in gameState.getLegalActions(agentIndex) if action != 'Stop']

        # update next depth
        nextIndex = agentIndex + 1
        nextdepth = currentdepth 
        if nextIndex>=gameState.getNumAgents():
              nextIndex = 0
              nextdepth += 1
        results = [self.MinMaxSearch(gameState.generateSuccessor(agentIndex,action),nextIndex,nextdepth) for action in legalMoves]

        if agentIndex==0 and currentdepth==1:
              bestmove = max(results)
              bestIndex = [index for index in range(len(results)) if results[index]==bestmove]
              choose_index = random.choice(bestIndex)
              return legalMoves[choose_index]

        if agentIndex==0:
              bestmove = max(results)
              return bestmove
        else:             
              bestmove = min(results)
              return bestmove

α-β剪枝算法

α-β算法详解
算法详解另一个参考
在这里插入图片描述

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(第一层)还需要根据其他因素来考虑最终选取哪种方案.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
α值:Max节点目前可以得到的最高收益
β值:Min节点目前可以给对手的最小收益
α和β的初始化分别设置为 -∞和+∞
在这里插入图片描述

import sys
class AlphaBetaAgent(MultiAgentSearchAgent):
    """
      Your minimax agent with alpha-beta pruning (question 3)
    """

    def getAction(self, gameState):
        """
          Returns the minimax action using self.depth and self.evaluationFunction
        """
        "*** YOUR CODE HERE ***"
        #util.raiseNotDefined()
        return self.AlphaBeta(gameState,0,1,-sys.maxint,sys.maxint)
    
    def AlphaBeta(self,gameState,currentAgent,currentDepth,Alpha,Beta):
          if currentDepth > self.depth or gameState.isWin() or gameState.isLose():
                return self.evaluationFunction(gameState)
          
          legalMoves = [action for action in gameState.getLegalActions(currentAgent) if action!='Stop']
          nextAgent = currentAgent + 1
          nextDepth = currentDepth
          if nextAgent >= gameState.getNumAgents():
                nextAgent = 0
                nextDepth += 1
          

          if currentAgent == 0 and currentDepth == 1:
                results = [self.AlphaBeta(gameState.generateSuccessor(currentAgent,action),nextAgent,nextDepth,Alpha,Beta) for action in legalMoves]
                bestMove = max(results)
                bestIndex = [index for index in range(len(results)) if results[index]==bestMove]
                ultimate_index = random.choice(bestIndex)
                return legalMoves[ultimate_index]
          
          if currentAgent == 0:
                bestMove = -sys.maxint
                for action in legalMoves:
                      bestMove = max(bestMove,self.AlphaBeta(gameState.generateSuccessor(currentAgent,action),nextAgent,nextDepth,Alpha,Beta))
                      if bestMove >= Beta:
                            return bestMove
                      Alpha = max(Alpha,bestMove)
                      return bestMove
          else:
                bestMove = sys.maxint
                for action in legalMoves:
                      bestMove = min(bestMove,self.AlphaBeta(gameState.generateSuccessor(currentAgent,action),nextAgent,nextDepth,Alpha,Beta))
                      if bestMove <= Alpha:
                            return bestMove
                      Beta = min(bestMove,Beta)
                      return bestMove
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我知道了,下面是我的回答: 聚类算法是一种无监督学习算法,它可以将数据集中的数据按照某种规则进行分组,使得同一组内的数据相似度较高,不同组之间的数据相似度较低。聚类算法可以帮助我们对数据进行分类、分析和理解,同时也可以为其他机器学习任务提供数据预处理和特征提取的支持。 聚类算法的基本流程包括:确定聚类算法的目标函数、选择相似度度量方法、选择聚类算法、确定聚类的数量、进行聚类操作以及评估聚类效果。常见的聚类算法包括K-Means算法、层次聚类算法、密度聚类算法等。 K-Means算法是一种基于距离的聚类算法,它的基本思想是将数据集中的数据划分为K个簇,使得同一簇内的数据相似度较高,不同簇之间的数据相似度较低。K-Means算法的优点是计算复杂度较低,容易实现,但是需要预先指定簇的数量和初始聚类中心。 层次聚类算法是一种基于相似度的聚类算法,它的基本思想是不断合并数据集中相似度最高的数据,直到所有数据都被合并为一个簇或达到预先设定的簇的数量。层次聚类算法的优点是不需要预先指定簇的数量和初始聚类中心,但是计算复杂度较高。 密度聚类算法是一种基于密度的聚类算法,它的基本思想是将数据集中的数据划分为若干个密度相连的簇,不同簇之间的密度差距较大。密度聚类算法的优点是可以发现任意形状的簇,但是对于不同密度的簇分割效果不佳。 以上是聚类算法的基础知识,希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新城里的旧少年^_^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值