C++抽象编程——回溯算法(7)——极小化极大算法

极小化极大算法(The minimax algorithm)

前面部分描述的技术适用于简单,完全可解决的游戏,如Nim(因为其所有的情况也不算大)。然而,随着游戏变得越来越复杂,很快就无法检查每一个可能的结果。例如,如果你试图通过一切可能的棋牌游戏,即使以现代电脑的速度,这个过程可能需要数十亿年的时间。 然而,不管怎样,尽管有这个限制,电脑在国际象棋方面仍然非常擅长。1997年,IBM的“深蓝色”(Deep Blue)超级计算机当时击败了世界冠军Garry Kasparov。 Deep Blue未不是通过对所有可能的游戏进行详尽的分析而获胜, 它反而只是针对有限数量的分析,以与人类完全相同的方式前进。
即使对于在计算上不可行的游戏,但是每一个动作都是在一个可能的动作序列中进行操作,来自Nim游戏的有利位置和不利位置的递归概念仍然派上用场。虽然可能无法确定一个肯定胜利的举动,但是在任何位置上的最佳举动是让对手处于最糟糕的位置。这个策略,其中包括找出让对手处于最差可能的最佳状态的位置(也就是说,这个时候你处于劣势,你要做的是最小化对手赢的机会) - 被称为极小化极大算法,因为目标是找到最小化对手赢的最大机会的动作。所以我们可以总结一下这个算法的基本特点:
- 在任何位置上的最佳举动是让对手处于最糟糕的位置。
- 当你处于劣势,你要做的是最小化对手赢的机会
- 你的目的是找出失败的最大可能性中的最小值的算法(即最小化对手的最大得益)

怕我自己解释的不够规范,我引用一段原文:

Although it may not be possible to identify a move as surefire winner, it is still true that the best move in any position is the one that leaves your opponent in the worst position. Similarly, the worst position is the one that offers the weakest best move. This strategy—which consists of finding the position that leaves your opponent with the worst possible best move—is called the minimax algorithm because the goal is to find the move that minimizes your opponent’s maximum opportunity.

游戏树(Game trees)

可视化最小化策略的操作的最佳方法是考虑在游戏中可能的未来移动,从而形成每轮转动的分支图。这种分支结构,这种图表被称为游戏树。初始状态由游戏树顶部的点表示。例如,假设存在来自这个位置的三个可能的移动,则会有三条线从当前状态向下发展到表示这些移动结果的三个新状态,如下图所示:

从这些新位置,您的对手也有选择权。 如果每个位置再次有三个选择,下一代的游戏树如下所示:

你在初始位置选择哪一个? 显然,你的目标是取得最好的结果。不幸的是,你只能控制一半的游戏(因为这是双人游戏)。如果你能够选择对手的举动以及自己的选择,那么您可以选择两次左右的路径,使你处于最佳位置(意味着你这个时候要考虑对手的选择)。考虑到你的对手也在努力争取,你最好的选择是选择一个最终的举动,让你的对手尽可能减少的获胜的机会。

对位置和动作进行评估(Rating positions and moves)

为了弄清楚你应该如何进行,添加一些定量数据的有助于我们分析。如果你为每个可能的移动分配数字分数,则决定某个特定动作是否比某些替代方法更好。数值越高越好。例如,得分为+ 7的举动胜过评级为-4的动作。除了评估每个可能的移动之外,对游戏中的每个位置分配类似的数字评级是都是有意义的。 因此,一个位置可能具有+9的等级,因此比具有+2分的位置更好。
从移动的玩家的角度来看,这两个位置和动作都是对应评估的。此外,评估系统被设计为在0左右对称,因为在玩家移动得分为+9的位置上,从对手的角度来看,得分为-9。 对评级数字的这种解释就是认为,对于一个玩家来说,一个对一个玩家有利的位置对于另一个玩家而言是不好的,就像Nim游戏一样。更重要的是,以这种方式定义评估系统,可以很容易地表达行动和位置的分数之间的关系。 任何举动的评级只有在对手评估时才会对得分位置的评级负数。类似地,任何位置的评级可以被定义为其最佳移动的评级。
为了使这个讨论更具体,它有助于考虑一个简单的例子。假设你已经看到了游戏中的两个步骤,包括你的一个举动和对手可能的回应。在计算机科学中,单个玩家的单一动作被称为ply,以避免与移动(move)和回合(turn)相关的歧义,这有时意味着两个玩家都有机会玩。 如果你在双层分析结束时评价位置,则游戏树可能如下所示:

因为这棵树底部的位置是你在树的顶部移动将会产生其他位置,这些位置的评级数字从你的角度分配。 如果考虑到这些潜在位置的评级,你应该从原始位置中做出什么动作?
为了方便理解,你可以说你负责选第二行的三个点,而第三行是第二行所产生的所有情况的评估
乍一看,你可能会被中心分支包含导致+9的路径所吸引,这对你来说是一个很好的结果。不幸的是,中心分支提供了如此美好的结果这一点并不是很重要。如果你的对手玩得很合理,你就没有办法可以达到+9的位置。即使,假设你选择了中心分支。给定可用的选项,你的对手将选择最左侧的分支,如以下游戏树中的彩色路径所示:

从你的角度来说你的初始选择让你有可能处于一个评级为-5这样的位置。但是如果你选择最右边的分支,你会做得更好,因为你的对手最好的策略只是让你处于-2级的位置而已。

如前面所述,当从对手的角度进行评估时,移动评级是对对方所得到的位置的评级的负数。游戏树的突出显示行中的最后一个移动的对手的评级为+2,因为它导致了我处于-2级的位置。负号表示角色的转变。 所以说,对我的对手不利的位置的移动对我有好处,反之亦然。 每个位置的评级只是其提供的最佳举措的评级。因此,在游戏树中突出显示的路径上的位置和移动的评分如下所示:

起始位置的等级为-2。虽然这个立场是不太理想的,但假如你的对手正在合理地运营,那么对于你而言,比其他可能的结果更好。
极小化极大算法的任何实现都要比较移动的等级以确定最佳的运动。因此,将每个移动的评级存储在相应的Move对象中是很方便的。实现此目标的最简单方法是向Move类添加一个称为评级的新实例变量,以使Nim游戏的定义现在如下所示:

class Move {
    int nTaken;
    int rating;
    friend class SimpleNim;
};

这一篇先讲原理,等晚上再把具体的实现补上,我理解这段也需要点时间的。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值