Python实现博弈树minmax补全与α-β剪枝算法脚本简介

article/2025/9/28 22:08:03

文章目录

  • 前言
  • 一、题目
  • 二、使用步骤
    • 1.递归构建博弈树
    • 2.α-β剪枝算法
    • 3.博弈树可视化
    • 4.测试实例
    • 5.结果展示
    • 6.全部代码
  • 总结


前言

使用Python编程实现博弈树的构建,实现利用MinMax方法补全博弈树缺失值,并结合α-β剪枝算法,实现博弈树的剪枝。实现了整体算法与博弈树的可视化。


一、题目

博弈树初始结构如下
博弈树

二、使用步骤

1.递归构建博弈树

代码如下:

class Node(object):def __init__(self, val: int=0, max: bool=True) -> None:'''val: 节点值max: 是否为max层childern: 子节点列表'''self.val = val	# 该节点的值self.max = max	# 该层是否为max层,默认顶层节点为max层self.children : list = []	# 该节点的子节点class Tree(object):def __init__(self) -> None:'''data_list: 数据列表上图所示列表示例:[[[4,13],[[5,10],11],16],[[[1,8],9,[6,12]],12],[[10,8,[2,5,7]],[7,4]]]其中节点值为一个int型数值,含有其他子节点的构建为列表'''self.root = Node()    # Node(),根节点def build_tree(self, data_list, root) -> None:# 递归构建博弈树for i in range(len(data_list)):is_max = root.maxif is_max == True:is_max = False  # min层else:   is_max = True   # max层if type(data_list[i]) is tuple:# 该节点为叶节点,直接添加节点值for val in data_list[i]:root.children.append(Node(val, is_max))elif type(data_list[i]) is int:# 该节点为叶节点,直接添加节点值root.children.append(Node(data_list[i], is_max))elif type(data_list[i]) is list:# 该节点含有子节点,递归创建if type(data_list[i]) is int:# 该节点为叶节点,直接添加节点值root.children.append(Node(data, is_max))elif type(data_list[i]) is list:# 该节点含有子节点,递归创建root.children.append(Node(max=is_max))      # 添加子节点self.build_tree(data_list[i], root.children[i])

2.α-β剪枝算法

代码如下:

class AlphaBeta(object):def __init__(self, tree, auto=False) -> None:'''tree: 博弈树auto: 补全全部节点值,默认不补全选择不补全时,可视化过程为剪枝过程,节点为0的子节点为剪掉的节点'''self.tree = tree	# 博弈树self.auto = auto    # 补全全部节点值,可选参数,默认不补全self.deep = 0		# 节点深度self.alpha = -float('inf')self.beta = float('inf')if self.auto:# 补全博弈树self.complement_value(self.tree.root)def get_value(self, node) -> int:# 获取节点值return node.valdef is_leaf(self, node) -> bool:# 判断是否为叶节点if len(node.children) == 0:return Trueelse:return Falsedef complement_value(self, node):	# 补全博弈树,可选# 根据MinMax规则补全博弈树if self.is_leaf(node):return self.get_value(node)if self.get_value(node) != 0:return self.get_value(node)val_list = []for child in node.children:temp = self.complement_value(child)val_list.append(temp if temp is not None else child.val)if node.max:node.val = max(val_list)else:node.val = min(val_list)def max_value(self, node, alpha, beta):if self.is_leaf(node):# 当前节点为叶节点return self.get_value(node)best = -float('inf')     # 初始化无穷小for child in node.children:best = max(best, self.min_value(child, alpha, beta))if best >= beta:return bestalpha = max(alpha, best)node.val = bestreturn bestdef min_value(self, node, alpha, beta):if self.is_leaf(node):# 当前节点为叶节点return self.get_value(node)best = float('inf')     # 初始化无穷大for child in node.children:best = min(best, self.max_value(child, alpha, beta))if best <= alpha:return bestbeta = min(beta, best)node.val = bestreturn bestdef alpha_beta(self):	best = self.max_value(self.tree.root, self.alpha, self.beta)# return bestfor child in self.tree.root.children:if best == child.val:return child

3.博弈树可视化

代码如下:

import matplotlib.pyplot as pltclass ShowTree(object):def __init__(self, tree) -> None:'''tree: 博弈树'''self.tree = tree	# 博弈树self.__num_of_leafs = self.get_num_of_leaf(self.tree.root)    # 叶节点数量self.__tree_depth = self.get_tree_depth(self.tree.root)       # 树深度# 初始化箭头格式self.arrow_args = dict(arrowstyle="<-")@propertydef num_of_leafs(self):return self.__num_of_leafs@propertydef tree_depth(self):return self.__tree_depthdef get_num_of_leaf(self, node):# 获取叶节点数量num_of_leafs = 0if len(node.children) == 0:# 该节点为叶节点,叶节点数量+1num_of_leafs += 1else:for child in node.children:num_of_leafs += self.get_num_of_leaf(child)return num_of_leafsdef get_tree_depth(self, node):# 获取树的最大深度max_tree_depth = 0if len(node.children) == 0:# 该节点为叶节点,深度为1max_tree_depth += 1else:for child in node.children:this_depth = 1 + self.get_tree_depth(child)if this_depth > max_tree_depth:max_tree_depth = this_depthreturn max_tree_depthdef box(self, node):# 设置文本框样式if node.max:boxstyle = "square"else:boxstyle = "circle"return dict(boxstyle=boxstyle,fc="0.8")def plot_node(self, node, centerPt, parentPt):node_type = self.box(node)# node_type = dict(boxstyle="round4",fc="0.8")ShowTree.plot.ax1.annotate(node.val, xy=parentPt, \xycoords='axes fraction',xytext=centerPt, textcoords='axes fraction',\va="center",ha="center", bbox=node_type, arrowprops=self.arrow_args)@staticmethoddef plot_tree(tree, node, parentPt):numLeafs = ShowTree.get_num_of_leaf(tree, node) # 计算树的宽度depth = ShowTree.get_tree_depth(tree, node)     # 计算树的高度# 输入的第一个节点first_node = nodecntrPt = (ShowTree.plot_tree.xOff + (1.0 + float(numLeafs)) / 2.0 / ShowTree.plot_tree.totalW, ShowTree.plot_tree.yOff)# 叶子节点ShowTree.plot_node(tree, first_node, cntrPt, parentPt)# 减少y的便偏移ShowTree.plot_tree.yOff = ShowTree.plot_tree.yOff - 1.0 / ShowTree.plot_tree.totalD for child in node.children:if len(child.children) == 0:ShowTree.plot_tree.xOff = ShowTree.plot_tree.xOff + 1.0 / ShowTree.plot_tree.totalWShowTree.plot_node(tree, child, (ShowTree.plot_tree.xOff, ShowTree.plot_tree.yOff), cntrPt)else:ShowTree.plot_tree(tree, child, cntrPt)ShowTree.plot_tree.yOff = ShowTree.plot_tree.yOff + 1.0 / ShowTree.plot_tree.totalD@staticmethoddef plot(tree):'''tree: 需要绘制的树,类型为ShowTree()'''fig = plt.figure(1, facecolor='white')# Clear figure清除所有轴,但是窗口打开,这样它可以被重复使用fig.clf()axprops = dict(xticks=[], yticks=[])ShowTree.plot.ax1 = plt.subplot(111, frameon=False, **axprops)# ShowTree.plot_node(show_tree, show_tree.tree.root, (0.5,0.1),(0.1,0.5))ShowTree.plot_tree.totalW = float(ShowTree.get_num_of_leaf(tree, tree.tree.root))ShowTree.plot_tree.totalD = float(ShowTree.get_tree_depth(tree, tree.tree.root))ShowTree.plot_tree.xOff = -0.5 / ShowTree.plot_tree.totalWShowTree.plot_tree.yOff = 1.0ShowTree.plot_tree(tree, tree.tree.root,(0.5, 1.0))plt.show()

4.测试实例

代码如下:


if __name__ == '__main__':data = [[[4,13],[[5,10],11],16],[[[1,8],9,[6,12]],12],[[10,8,[2,5,7]],[7,4]]]	# 初始博弈树值列表tree = Tree()	# 实例化空树tree.build_tree(data, tree.root)	# 递归构建博弈树alpha_beta = AlphaBeta(tree, auto=True)	# α-β剪枝best = alpha_beta.alpha_beta()		# 获取结果print(best.val)from plot_tree import ShowTreeshow_tree = ShowTree(tree)	# 实例化博弈树可视化算法show_tree.plot(show_tree)	# 可视化博弈树

5.结果展示

博弈树可视化结果

6.全部代码

全部代码如下alpha_beta.zip


总结

利用Python编程实现了α-β剪枝算法,并利用matplotlib实现了博弈树的可视化。


http://chatgpt.dhexx.cn/article/APJHp90u.shtml

相关文章

CART的剪枝算法

CART剪枝算法从“完全生长”的决策树的底端减去一些子树&#xff0c;使决策树变小&#xff0c;从而能够对未知数据有更准确的预测。CART算法由两步组成&#xff1a;首先从生成算法产生的决策树 底端开始不断剪枝&#xff0c;直到 的根结点&#xff0c;形成一个子树序列 &#x…

α-β剪枝算法学习寄(蒟蒻向,巨佬勿入)

由于做某题时暴力分出来很低&#xff0c;但某巨佬告诉我α-β剪枝很好用于是本屑踏上了征途。作为一只屑屑在学习这个算法时到处看各种blog&#xff0c;于是乎被上界下界决策等一众本屑看不懂的词汇弄得晕头转向&#xff0c;这篇blog就用本屑的语言梳理一下α-β剪枝算法捏。 …

alpha-beta剪枝算法原理(附代码)

alpha-beta剪枝算法原理 背景Max-Min算法alpha-beta剪枝代码 背景 由于笔者最近要写人工智能课的大作业&#xff0c;所以这两天在学习博弈论相关的知识&#xff0c;但网上对alpha-beta剪枝的原理讲的都不是很清晰&#xff0c;很多细节都忽略了&#xff0c;让初学者会有一种脑子…

人工智能之AlphaBeta剪枝算法

任务描述 本关任务&#xff1a;学习人工智能博弈算法中的 AlphaBeta 剪枝技巧&#xff0c;并基于 MinMax 算法编程实现如下图博弈树最优值问题的求解。 博弈树的输入形式为字符串&#xff1a;[A, [B, (E, 3), (F, 12), (G, 8)], [C, (H, 2), (I, 4), (J, 6)], [D, (K, 14), (…

α-β剪枝算法

在写之前首先感谢&#xff1a;https://blog.csdn.net/wenjianmuran/article/details/90633418 这里主要介绍minmax算法和α-β剪枝,相当于对一下文章的翻译&#xff1a; α-β剪枝 Minmax算法 正文&#xff1a; 看了很多关于α-β剪枝算法&#xff0c;大致明白了其中的含义…

α-β剪枝算法简单原理说明

看了一大堆文章实在看不懂&#xff0c;看视频也看不懂&#xff0c;但是看着看着突然顿悟了。这篇文章只讲大概的原理&#xff0c;不讲具体过程。 好了既然会搜这个算法&#xff0c;想必已经知道最大值最小值算法了&#xff08;不知道就去搜吧&#xff09;。这里直接讲例子。 …

alpha-beta剪枝算法

实验报告 alpha-beta剪枝算法 姓名&#xff1a;张楚明 学号&#xff1a;18342125 日期&#xff1a;2021.01.15 摘要 本实验将搜索深度为4的Alpha-Beta剪枝算法应用于中国象棋中黑方走棋&#xff0c;实现了中国象棋的人机博弈。博弈过程中综合考虑了棋力、对敌方棋子的攻击力、…

透析极大极小搜索算法和α-β剪枝算法(有案例和完整代码)

文章目录 前言minimax算法完整代码算法思想代码实现算法优化 α-β剪枝算法完整代码算法思想代码实现算法对比更多案例 结语 前言 先做了一版五子棋的小项目&#xff0c;后面又做了一个功能更强大的中国象棋的项目&#xff0c;但是始终都没有实现一版“智能”AI。 明知道这类博…

决策树后剪枝算法(二)错误率降低剪枝REP

​  ​​ ​决策树后剪枝算法&#xff08;一&#xff09;代价复杂度剪枝CPP  ​​ ​决策树后剪枝算法&#xff08;二&#xff09;错误率降低剪枝REP  ​​ ​决策树后剪枝算法&#xff08;三&#xff09;悲观错误剪枝PEP  ​​ ​决策树后剪枝算法&#xff08;四&…

C++实现的基于αβ剪枝算法五子棋设计

资源下载地址&#xff1a;https://download.csdn.net/download/sheziqiong/85883881 资源下载地址&#xff1a;https://download.csdn.net/download/sheziqiong/85883881 基于αβ剪枝算法的五子棋 五子棋介绍 简介&#xff1a; 五子棋是世界智力运动会竞技项目之一&#x…

决策树后剪枝算法(四)最小错误剪枝MEP

​  ​​ ​决策树后剪枝算法&#xff08;一&#xff09;代价复杂度剪枝CPP  ​​ ​决策树后剪枝算法&#xff08;二&#xff09;错误率降低剪枝REP  ​​ ​决策树后剪枝算法&#xff08;三&#xff09;悲观错误剪枝PEP  ​​ ​决策树后剪枝算法&#xff08;四&…

计算机博弈 基础算法 阿尔法-贝塔剪枝算法 α-β剪枝算法

计算机博弈大赛中 α-β剪枝算法剪枝算法是极大极小算法的一种优化&#xff0c;可以更快的搜索博弈树 预备知识&#xff1a; 广度优先搜索(BFS) 深度优先搜索(DFS) 极大极小算法(MaxMin算法) 介绍 剪枝算法来源于极大极小算法&#xff0c;在博弈树分枝过多时可以使用这个方法…

卷积神经网络通道剪枝算法小结

一、剪枝分类 目前常见的模型剪枝算法主要分成两类&#xff0c;即非结构化剪枝与结构化剪枝&#xff1b;在不少的神经网络加速器中已经应用了这些剪枝算法&#xff0c;早期常见的是非结构化剪枝&#xff0c;例如MIT的韩松组的前几年的相关工作中就有此类应用&#xff0c;但是在…

最大最小法及α-β剪枝算法图解

&#xff08;网上讲的都不是很好理解&#xff0c;贡献一下之前听慕课做的笔记&#xff0c;适合初学者比较简洁明了。&#xff09; 要想理解α-β剪枝算法&#xff0c;必须从最大最小法的博弈问题讲起&#xff01;注意不懂的同学不要跳过这一节。 最大最小法 场景&#xff1a;…

剪枝算法实现一字棋-C++

博弈树 alpha & beta剪枝算法实现一字棋 剪枝算法首先就是要理解&#xff0c;把这个算法彻底弄清楚&#xff0c;我觉得这是一件非常有意义的事情&#xff01;为后续书写其它棋类的AI打下了坚实的基础 剪枝操作的实现&#xff0c;遍历下一步所有可能取到的点&#xff0c;…

模型压缩:剪枝算法

过参数化主要是指在训练阶段&#xff0c;在数学上需要进行大量的微分求解&#xff0c;去捕抓数据中的微小变化信息&#xff0c;一旦完成迭代式的训练之后&#xff0c;网络模型推理的时候就不需要这么多参数。而剪枝算法正是基于过参数化的理论基础而提出的。 剪枝算法核心思想…

人工智能算法模型--Alpha-Beta剪枝算法学习笔记

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; (*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &a…

理解Alpha-Beta 剪枝算法

Alpha-beta剪枝是一种搜索算法&#xff0c;用以减少极小化极大算法&#xff08;Minimax算法&#xff09;搜索树的节点数。裁剪搜索树中没有意义的不需要搜索的树枝&#xff0c;提高运算速度。 搜索中传递两个值。 第一个值是Alpha&#xff0c;即搜索到的最好值&#xff0c;任何…

组合总和(剪枝算法)

组合总和&#xff08;剪枝算法&#xff09; 题目 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取 示例 示例 1&#xff1a;输入: candidates [2,…

Alpha-Beta剪枝算法原理

1. 前言 前文&#xff1a;极小化极大&#xff08;Minimax&#xff09;算法原理 极小化极大算法在完全信息零和博弈中&#xff0c;基于己方努力使得在N步后优势最大化&#xff08;即评估函数输出值最大化&#xff09;和对方努力使得N步后己方优势最小化这两个出发点&#xff0c…