DeepStack算法笔记
Deep Stack 中游戏树介绍:
- Deep Stack 的re-solving需要保留自己的range和对手的遗憾值这两个值
- Deep Stack 的核心是不保留记忆,采用局部搜索,将游戏分成一个个的子博弈,这样是为了省空间且加速算法。
- 下面介绍该算法的游戏规则、核心算法、网络、伪代码。
游戏规则
- 蓝色结点表示玩家一的动作选择结点;
- 红色结点表示玩家二的动作选择结点;
- 绿色结点表示发牌者的机会结点(chance);
- 最后的筹码值表示执行该动作玩家的收益。
游戏开始时,玩家一(庄家)下注(small blind)¥50,玩家二下注(big blind)¥100。第一轮( pre-flop)每人发两张牌,玩家一先做决定。第二轮(flop)在桌面放三张公共牌,玩家一先做决定。第三轮(turn)桌面放一张,玩家二先做决定。第四轮(river)桌面放一张,玩家二先做决定。
整体算法
deepstack核心是subgame。subgame就是将不能拆解的非完美信息博弈安全的拆解为一个个小游戏,并且要保证小游戏求解的可利用度低于原来的策略(可利用度越低越好,如果不懂私聊我再解释)。sungame就是将游戏分成一个T和一个F,并保存对手的原来策略的遗憾值为RT,F是子博弈,对手的遗憾值为RF。每次更新子博弈后F会更新RF,如果RF的大于RF,则不更新;如果RF的小于RF,则将F的策略保存为T,然后继续改进F。这样能保证可利用度是一直降低的。
(A)当博弈进行时,它自己的range在它采取行动后计算更新。对手遗憾值按照“Continual re-solving”中的讨论进行更新。它使用其range和对手遗憾值 re-solving,计算最终采取行动时的行动概率。
(B) 评估函数由一个神经网络表示,该神经网络以公共状态和当前迭代的范围作为输入,并为两个参与者输出遗憾值(下图)。
(C) 神经网络在游戏前通过生成随机扑克情境(pot size,board cards,and ranges)进行训练,并解决它们以生成训练示例。
网络结构
Deep counterfactual value network:该网络的输入:池大小、公共牌、player ranges,这些首先会被处理成 hand clusters。来自这 7 层全连接隐藏层的输出还要经过后处理(post-processed),从而保证该值(values)满足零和约束(zero-sum constraint),然后这些值又会回过来被映射为遗憾值。
伪代码
其实有时候弄懂一个算法,看伪代码比看论文要简单。论文讲述的非常晦涩难懂,而伪代码则一目了然
- 主代码
DeepStack就是将整个游戏根据re-solving思想分解为子博弈(必须有自己的range和对手的遗憾值两个参量),根据子博弈的规则向下扩展,通过网络返回的V值根据CFR+算法更新遗憾值。
代码介绍:
假设自己是玩家一:
2:随机初始化双方策略(因为没有策略,所以只能随机初始化一个)
3:随机初始化对手的range
4:0初始化小游戏和子树参数
6:代码2value:就是拿当前的状态,自己的range(第1行),之前的双方策略和上一次的对手range 来更新自己和对手的遗憾值
7:代码3:根据遗憾匹配公式,利用v值更新双方策略和遗憾值
8:更新对手的range和小游戏参数
10:取平均策略
11:根据策略采样执行动作a(return)
12-13:根据执行的动作a的收益来更新自己的range(return)
14:更新自己的value值(return)
代码2
VALUE函数利用CFR+算法迭代计算当前状态S和后续状态S’下双方各手牌的V值,
S的value是后续状态value的数学期望
If s是终端结点
return V1,V2值
Else if 到了设置的搜索深度(设置了两个网络,分别为flop和turn轮)
网络return V1,V2值
中间正常拓展情况:
根据策略更新玩家的range
选择动作
VALUE = 向下扩展并返回得到的
return V1,V2值
计算每个状态的遗憾值并更新策略
代码3
利用CFR+算法运行过程中计算的v1,v2值累加入后悔值R中,并计算策略