强化学习—— 蒙特卡洛树(Monte Carlo Tree Search, MCTS)
强化学习—— 蒙特卡洛树(Monte Carlo Tree Search, MCTS)
- 1. 单一状态蒙特卡洛规划
- 1.1 特点
- 1.2 数学模型
- 2. 上限置信区间策略
- 3. 蒙特卡洛树搜索
- 3.1 选择
- 3.2 扩展
- 3.3 模拟
- 3.4 反向传播
- 3.5 流程图
- 4. 代码实现
1. 单一状态蒙特卡洛规划
以 多臂赌博机(multi-armed bandits) 为例
1.1 特点
为序列决策问题,在利用(exploitation)和探索(exploration)之间保持平衡,利用为过去决策中的最佳汇报,探索为未来获得更大回报。
1.2 数学模型
- 设有k个赌博机,选择第I个赌博机后,获得的回报为:VItV_{I_t}VIt
- 经过n次操作后的悔值函数为(第一项为最大的奖赏):Qn=maxi=1,...,k∑t=1nVi,t−∑t=1nVIt,tQ_n=\displaystyle{max_{i=1,...,k}}\sum_{t=1}^n V_{i,t} - \sum_{t=1}^n V_{I_t,t}Qn=maxi=1,...,kt=1∑nVi,t−t=1∑nVIt,t
2. 上限置信区间策略
upper confidence bound, UCB
- 记录第i个赌博机过去t-1时刻的平均奖赏,在t时刻,选择具有最佳上限置信区间的赌博机:It=maxi=1,...,k{V^i,Ti(t−1)+2⋅log(t)s}I_t=max_{i=1,...,k}\{\hat{V}_{i,T_i(t-1)}+\sqrt{\frac{2\cdot log(t)}{s}}\}It=maxi=1,...,k{V^i,Ti(t−1)+s2⋅log(t)}
s为赌博机在过去被选中的次数。 - UCB的计算公式为:UCB=V^j+c⋅log(N)njUCB=\hat V_j + c\cdot \sqrt{\frac{log(N)}{n_j}}UCB=V^j+c⋅njlog(N)
3. 蒙特卡洛树搜索
3.1 选择
- 选择最大化UCB值的节点:UCB=V^i+c⋅log(N)nic=2UCB=\hat V_i + c\cdot \sqrt{\frac{log(N)}{n_i}}\\ c=2UCB=V^i+c⋅nilog(N)c=2
- 从根节点root开始,向下递归选择子节点,直至选择到叶子节点L,通常用UCB选择最具有潜力的后续结点。
3.2 扩展
如果叶子节点L不是终止节点,则随机创建一个未被访问节点,选择该节点作为后续节点C。
3.3 模拟
从节点C出发,对游戏进行模拟,直到博弈游戏结束。
3.4 反向传播
用模拟结果来回溯更新导致这个结果的每个节点中的获胜次数和访问次数。
3.5 流程图
此图来源
4. 代码实现
MCTS实际使用时可以根据任务进行细节调整,以下为五子棋的MCTS代码:
# -*- coding: utf-8 -*-
# @Time : 2022/4/4 14:55
# @Author : CyrusMay WJ
# @FileName: mcts.py
# @Software: PyCharm
# @Blog :https://blog.csdn.net/Cyrus_May
import numpy as np
import copy
import datetimeclass Agent:"""turn: 0 means black player, 1 means white player."""def __init__(self, width=15, height=15, logger=None):self.width = widthself.height = heightself.logger = Noneself.turn = 0self.__init_board()def __init_board(self):self.black_board = np.zeros([self.width, self.height])self.white_board = np.zeros([self.width, self.height])self.all_board = self.black_board + self.white_boarddef judge_terminal(self):if self.turn:return self.__judge(self.white_board)else:return self.__judge(self.black_board)def __judge(self, board):for i in range(self.width):for j in range(self.height):if self.width - i >= 5 and board[i, j:i + 5].sum() == 5:return 1if self.height - j >= 5 and board[i:i + 5, j].sum() == 5:return 1if self.width - i >= 5 and self.height - j >= 5 and sum(board[i, j], board[i + 1, j + 1], \board[i + 2, j + 2], board[i + 3, j + 3],board[i + 4, j + 4]) == 5:return 1if self.i >= 4 and self.height - j >= 5 and sum(board[i, j], board[i - 1, j + 1], \board[i - 2, j + 2], board[i - 3, j + 3],board[i - 4, j + 4]) == 5:return 1return 0def update_board(self, x, y):if self.turn:self.black_board[x, y] = 1else:self.white_board[x, y] = 1self.all_board[x, y] = 1def next_state(self):x, y = np.where(1 - self.all_board)if not x.shape[0]:return None, Noneidx = np.random.choice(np.arange(x.shape[0]))x = x[idx]y = y[idx]return x, ydef childs_state(self):x, y = np.where(1 - self.all_board)return x, yclass Node():def __init__(self, agent, childs=[], parent=None):self.agent = agentself.childs = childsself.parent = parentself.reward = 0self.n = 0def add_child(self, node):self.childs.append(node)class MCTS():def __init__(self, max_epochs=10000, max_time=5, logger=None):self.logger = loggerself.max_epochs = max_epochsself.c = 1/np.sqrt(2) # 平衡因子self.max_time = max_timedef search(self, board):board = np.array(board)black_state = (board == 1).astype(np.int32)white_state = (board == 2).astype(np.int32)turn = 0 if black_state.sum() <= white_state.sum() else 1self.agent = Agent(logger=self.logger)self.agent.white_board = white_stateself.agent.black_board = black_stateself.agent.all_board = white_state + black_stateself.agent.turn = turnself.turn = turnreturn self.run()def run(self):root = Node(copy.deepcopy(self.agent))start = datetime.datetime.now()for i in range(self.max_epochs):path = self.selection(root,self.max_epochs)path = self.expand(path)if not path:continuereward = self.simulation(path)self.backward(path,reward)if datetime.datetime.now() - start > self.max_time:breakscores = np.array([self.ucb(node, self.max_epochs) for node in root.childs])x,y = np.where(self.agent.all_board - root.childs[np.argmax(scores)].agent.all_board)return x[0],y[0]def ucb(self, node, epoch):if node.turn == self.turn:return (node.n - node.reward) / (node.n + 1e-8) + 2 * np.sqrt(2 * np.log(epoch) / ((node.n-node.reward) + 1e-8))return node.reward / (node.n + 1e-8) + 2 * np.sqrt(2 * np.log(epoch) / (node.n + 1e-8))def selection(self, root, epoch):path = [root]while 1:if not root.childs:return pathscores = np.array([self.ucb(node, epoch) for node in root.childs])path.append(root.childs[np.argmax(scores)])return pathdef expand(self, path):if path[-1].n > 0 or len(path) == 1:x, y = path[-1].agent.childs_state()if not x.shape[0]:return Nonefor row, col in zip(x, y):node = copy.deepcopy(path[-1])node.turn = 1 - path[-1].agent.turnnode.agent.update_board(row, col)path[-1].add_child(node)path.append(path[-1].childs[0])return pathdef simulation(self, path):root = copy.deepcopy(path[-1])while 1:if root.judge_terminal():return 1 if root.agent.turn != self.turn else 0x, y = root.agent.next_state()if not x.shape[0]:return 0else:root.agent.update_board(x,y)root.agent.turn = 1 - root.agent.turndef backward(self,path,reward):for node in path:node.n += 1node.reward += reward
by CyrusMay 2022 04 04
生命是华丽错觉
时间是贼偷走一切
————五月天(如烟)————
强化学习—— 蒙特卡洛树(Monte Carlo Tree Search, MCTS)相关推荐
- 蒙特卡洛方法、蒙特卡洛树搜索(Monte Carlo Tree Search, MCTS) 学习
文章目录 1. 从多臂赌博机说起 2. UCB 3. 蒙特卡洛树搜索 4. 伪代码 提出一个问题: 假设你当前有n个币,面前有k个赌博机.每个赌博机投一个币后摇动会产生随机的产出,你会怎么摇? 1. ...
- AI强度相关的研究:MCTS 蒙特卡洛树搜索 Monte Carlo Tree Search
提供具有挑战性的人工智能对手是使视频游戏令人愉悦和身临其境的重要方面. 太简单或反之太难的游戏可能会让玩家感到沮丧或无聊. 动态难度调整是一种方法,旨在通过为对手提供量身定制的挑战来改进传统的难度选择 ...
- 那么蒙特卡洛树搜索(Monte Calro Tree Search, MCTS)究竟是啥
同时发布于:http://www.longgaming.com/archives/214 Intro 最近阿法狗和李师师的人机大战着实火了一把,还顺带捧红了柯杰,古力等一干九段.虽然我从小学的是象棋, ...
- Monte Carlo tree search 学习
https://en.wikipedia.org/wiki/Monte_Carlo_tree_search 蒙特卡洛树搜索(MCTS)基础 http://mcts.ai/about/index.htm ...
- 读源码学算法之Monte Carlo Tree Search
最近研究新的算法有使用到Monte Carlo Tree Search,查了一些资料,参考几篇博客: 1.知乎:蒙特卡洛树搜索最通俗入门指南 2.知乎:AlphaGo背后的力量:蒙特卡洛树搜索入门指南 ...
- Monte Calro Tree Search (MCTS)
https://blog.csdn.net/natsu1211/article/details/50986810, 感谢分享! Intro 最近阿法狗和李师师的人机大战着实火了一把,还顺带捧红了柯杰, ...
- 蒙特卡洛积分(Monte Carlo Integration)应用:利用蒙特卡洛积分生成 McBeth表
蒙特卡洛积分(Monte Carlo Integration)应用 蒙特卡洛积分 通常函数f(x)的积分: 可以解释为计算函数曲线下方的面积: 而我们的蒙特卡洛积分则是通过近似的方式来获取一个函数的积 ...
- 蒙特卡洛(Monte Carlo)法求定积分
蒙特卡洛(Monte Carlo)法是一类随机算法的统称.随着二十世纪电子计算机的出现,蒙特卡洛法已经在诸多领域展现出了超强的能力.在机器学习和自然语言处理技术中,常常被用到的MCMC也是由此发展而来 ...
- 心得复述知识体系:《强化学习》中的蒙特卡洛方法 Monte Carlo Methods in Reinforcement Learning
前言: 刚刚读完 Sutton 的<强化学习(第二版)>第5章:蒙特卡洛方法.为了巩固本章收获,笔者将在本文中用尽量简单直白的语言复述本章的思想,各个知识点之间的关系.同时,这方便笔者日后 ...
最新文章
- 熟悉一下oncontextmenu事件的知识
- VMWare安装黑苹果Mac OS
- 详解C++17下的string_view
- Kubernetes:标签、选择器、注解、容忍度、亲和性
- 一个搜索框多个按钮_网站搜索栏设计指南:要不要?怎么设计?
- OpenShift 4 - 了解Secret
- 组合数学及其应用——polya计数
- 苹果春季发布会:绝不玩别人玩剩下的!
- Swoole MySQL 连接池的实现
- 如何查看自己的CSDN地址
- PTA 判断上三角矩阵
- astrolog php,如何在苹果MAC上使用Astrolog32 zet9等占星软件
- shell编程之awk(数据筛选与处理)
- audio_policy_configuration.xml文件解析
- 西瓜书-机器学习复习<HENU>
- Python 拓展之详解深拷贝和浅拷贝
- 基于 HTML5 WebGL 的高炉炉体三维热力图监控,展示“智慧工厂”十八般武艺
- 经纬度坐标转换到平面坐标
- 2023北京工业大学计算机考研信息汇总
- Android开发对内存管理的学习总结
热门文章
- 利用Comet4J 及时推送消息
- 14. 函数返回值为引用?
- 【Python】青少年蓝桥杯_每日一题_10.03_输出数据
- 数据结构-简单实现二叉树的先序、中序、后序遍历(java)
- 数据库分片教程mysql_简述MySQL分片中快速数据迁移
- 中国数据中心市场时评—简析全国数据中心布局情况
- 开关电源雷击浪涌整改_大佬多年经验总结,开关电源EMI整改策略
- 微服务发展的历史_Spring Cloud Alibaba#03. 微服务的发展史
- ML/DL之激活函数/求导函数:ML中常用的AF激活函数(step_function、sigmoid、softmax、ReLU等)求导函数等代码实现之详细攻略
- pip:成功解决pip下载时速度超慢(pip下载慢)的几种方法