《算法的乐趣》——博弈树与棋类游戏

  从这一篇文章开始,笔者开始了对《算法的乐趣》一书的学习。与以往笔者看的面向竞赛的算法数和经典教材不同,这本书接介绍的算法多为在现实生活中或者已经应用在生产实践当中的算法,比如说这篇文章所介绍的博弈树,就是前段时间非常火的人与AI的围棋大战的基础。

  需要提前说明的一件事情是,由于本书当中的算法有非常好的应用与实践性,但是受笔者能力和经历所限,可能无法非常给出并分析算法的源代码,因此笔者在文章中介绍这些算法的时候,也主要以算法思想和伪代码为主,如果读者对某个算法的源代码感兴趣,可以留言笔者会将原作者所写的源码发送给你。

  那么我们开始正文。

 

  首先,我们来抛出一个问题,既IBM的深蓝打败国际象棋大师卡斯帕罗之后,也就在最近,Google的阿尔法狗又攻陷了人类智力的最后堡垒——围棋。那么我们一定会好奇,没有生命的计算机何以强大到如此地步能够在这些以智力称道的游戏中打败人类呢?那么接下来我们就要一一揭开棋类AI的神秘面纱。

  博弈:

  首先我们应该对我们要探讨的问题有充分的了解,不管是围棋还是国际象棋,他们本质上都能叫做“博弈”,那么什么是博弈呢?博弈可以理解为有限参与者进行有限策略选择的竞争性活动,比如下棋、打牌、竞技、战争等。而在这里我们将博弈更进一步简化,我们探讨一些简单的“二人零和、全信息、非偶然”的博弈。所谓零和,就是有输必有赢,最多出现平局,不会出现双赢的博弈;而“全信息”则指博弈过程双方对战局信息的了解是公开和透明的,即一种信息对称;而所谓“非偶然”,即规定博弈的参与者都是理性而聪明的。

 

  初步了解了博弈的定义,我们从一个最简单的博弈开始探讨。

  以井字棋游戏为例的极大极小值搜索算法:

  首先来介绍井字棋游戏,非常类似五子棋,在一个3x3的方格上,双方轮流填充“x”和“o”,先使得3个“x”或“o”相连的一方获胜。

  我们设玩家Max填充“x”,玩家Min填充“o”,Max先手。那么这里我们应该意识到的一个很重要的思想:计算机能够做出的一切看似“聪明”的策略,其实都是都是在较短时间内模拟出了所有棋局状态然后筛选出对AI最有利的状态。

  我们来看这样一个图。

 

  在这个图中,Player1其实就是上文中我们定义的Max,容易看到,这里是列出了前两步的所有状态的树结构,这种记录棋局状态的树状结构变叫做博弈树。

  那么容易看到,我们可以顺着这个博弈树,得到所有的棋局状态,那么现在的问题是,假设我们已经得到了一个完全的博弈树,我们如何优化AI的决策呢?

  这便是我们要介绍的极大极小值搜索算法,我们从Max即Player2的角度,设置一个权值w给博弈树中的每个节点,用来表征这个节点(某一种状态)对Max的有利程度,这个权值越大,表示这种状态对Max更有利。

  那么我们在模拟对弈的过程中,对于第一层树也就是Max填充“x”,由上面的定义,显然Max倾向选择节点权值较大的节点,即w[1] = max(w[2],w[2],w[3]),因此我们需要找到博弈树第二层三个节点的权值,这便需要继续拓展博弈树的第三层。

  而对于玩家Min来说,它显然倾向于选择对自己更有利的棋局状态,即w最小的节点,由此我们可知w[2] = min(w[5],w[6],w[7],w[8],w[9]),同时w[3]、w[4]也是类似的方法求解。

  是否找到了规律化的模式呢?容易看到,这是一个递归算法,对于第i层落子的策略,不论对于Max还是Min,它都要基于第i+1层的所有状态,只不过不同的是,对于玩家Max,他要选择该节点所有子节点的权值最大值,而Min则要选择最小值。

  最终,我们需要将博弈树拓展到叶节点,然后回溯回去得到应对各种情况的最有利策略。

 

 

  基于对这种思想理解,我们不难写出下面极大极小值算法的伪代码。

 

int MiniMax(node,depth,isMaxPlayer)
{
     if(depth == 0)
          return Evaluate(node);
     int score = isMaxPlayer ? -INF : INF;
     for_each(node的子节点child_node)
     {
         int value = MiniMax(child_node,depth-1,!isMaxPlayer);
         if(isMaxPlayer)
              score=max(score,value);
         else
              score=min(score,value);
     }
}

  其实我们能够看到,这种博弈树是基于搜索或者穷举或者dp的思想都可以,这不难理解,这是很基本的编程思维,虽然可以说这是设计棋类AI很核心的部分,但是这样就能打败人类了么?当然不能,这种算法设计模式面临的一个最大的问题是,博弈树的规模太过庞大,当时计算能力超强的计算机也无从招架,因此在真正的算法设计中,我们需要需要限制搜索深度和各种各样的剪枝如阿尔法贝塔剪枝、A*剪枝等算法来削减博弈树的规模,这便是我们下面要介绍的内容。

转载于:https://www.cnblogs.com/rhythmic/p/5543553.html

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值