bupticybee / TexasSolver

🚀 A very efficient Texas Holdem GTO solver :spades::hearts::clubs::diamonds:
https://bupticybee.github.io/texassolver_page
GNU Affero General Public License v3.0
1.69k stars 301 forks source link

随机节点的概率 #95

Open yffbit opened 2 years ago

yffbit commented 2 years ago

https://github.com/bupticybee/TexasSolver/blob/02e52e4bb47473d2854626f8c19f26e698c73347/src/solver/PCfrSolver.cpp#L235-L236 https://github.com/bupticybee/TexasSolver/blob/02e52e4bb47473d2854626f8c19f26e698c73347/src/solver/PCfrSolver.cpp#L335 https://github.com/bupticybee/TexasSolver/blob/02e52e4bb47473d2854626f8c19f26e698c73347/src/solver/BestResponse.cpp#L120-L121 这里计算possible_deals应该要减去双方手牌张数之和,也就是减4,而不是减2 拿6张牌{A,B,C,D,E,F}举例,对于任意具体的节点,例如player1拿A,player2拿B,发公共牌时实际只有4个动作{C,D,E,F},也可以对齐到6个动作,其中2个动作概率为0,剩余4个动作概率均为1/4。对于向量形式,例如计算player1的信息集A的期望收益(或虚拟价值),player2拿{B,C,D,E,F},虽然发公共牌有5种情况,但是对5个子节点加权求和时,只有4个子节点的期望收益做出了贡献。 现在的计算方式乘上5/4才是真实值。这也不是什么大问题,真正出问题是在发牌节点的父节点处。假设父节点的fold动作进入叶子节点,call动作进入发牌节点,这两个子节点的期望收益一个是真实值,另一个乘上5/4才是真实值,两个值直接(加权)求和就有问题。

bupticybee commented 2 years ago
  1. 关于-4和-2。 我理解你的意思,我是有考虑你说的这种情况的,只不过这里确实是-2没错,对手的-2在其他地方被等价的减掉了,我证明过两种情况的等价性,所以应该是没有问题的
  2. 关于公共牌和 5/4。公共牌ban掉的组合也以其他形式影响ev,并不直接以概率乘的形式。你可以发现我程序里用的ev并不是绝对的ev(prob*收益),而是一种相对的ev形式。 我当时证明了一整个稿纸本,这种程序里用的相对ev可以等价于绝对ev的cfr算法,所以并不需要进行这种5/4乘法运算,我认为这里没有问题。
  3. 但是我并非神仙,所以依然可能证明出现问题,如果觉得这里有问题,有没有可能通过一些实验说明这一点,比如在某些场面下你修改后的算法cfr可以收敛,而我的“baseline”无法收敛?
yffbit commented 2 years ago

对于第一点,“对手的-2在其他地方被等价的减掉了”,我的意思是需要保证没有被ban的节点ev的概率的正确性,被ban的ev由于没有贡献,即使概率不正确也不会影响结果 对于第2点,不论是绝对ev还是相对ev都没有关系,我说的重点不是这个。重点在于,计算父节点ev时,fold子节点fold_ev和chance子节点chance_ev的差异,fold子节点不需要5/4,chance子节点需要5/4,也就是用fold_ev+chance_ev代替了fold_ev+5/4*chance_ev。用我说的方式计算,两个子节点ev都不需要5/4 对于第3点,从一些实验结果来看,当前版本也是收敛的

bupticybee commented 2 years ago

对于第2点,不论是绝对ev还是相对ev都没有关系,我说的重点不是这个。重点在于,计算父节点ev时,fold子节点fold_ev和chance子节点chance_ev的差异,fold子节点不需要5/4,chance子节点需要5/4,也就是用fold_ev+chance_ev代替了fold_ev+5/4*chance_ev。用我说的方式计算,两个子节点ev都不需要5/4

嗯嗯,了解,我短时间还没有理解你说的5/4,也就是 “另一个乘上5/4才是真实值” 我得找个时间证明一下,看看是不是这样。不知道是否方便做一些实验在当前代码上验证一下你的这个5/4的思路呢?主要关注收敛性/收敛速度等等。

yffbit commented 2 years ago

其实很好理解,将发牌动作看成上帝玩家的动作 例如,player1的信息集A,里面有6个具体的节点,分别对应player2拿A,B,C,D,E,F,信息集A的动作是发牌动作 对于其中的每个具体节点: AA:节点概率总是为0,对结果没有影响,发牌动作概率分布可以是任意分布,为了方便取[0,0,1/4,1/4,1/4,1/4] AB:发牌动作概率分布[0,0,1/4,1/4,1/4,1/4] AC:发牌动作概率分布[0,1/4,0,1/4,1/4,1/4] AD:发牌动作概率分布[0,1/4,1/4,0,1/4,1/4] AE:发牌动作概率分布[0,1/4,1/4,1/4,0,1/4] AF:发牌动作概率分布[0,1/4,1/4,1/4,1/4,0] 这样设置将很多实际不存在的节点的概率置为0,因为概率为0的节点的后代节点概率也为0,对ev没有影响。此时就不用考虑手牌之间,手牌和公共牌之间的冲突了。 可以看到发牌动作的概率不是0就是1/4,不会出现1/5。也就是我说的“需要保证没有被ban的节点的概率的正确性”。这样做看起来很复杂,但是只要理解了这句话的意思,就很简单了。

bupticybee commented 2 years ago

,call动作进入发牌节点,这两个子节点的期望收益一个是真实值,另一个乘上5/4才是真实值,两个值直接(加权)求和就有问题。

hi~我想了一下,总感觉哪里怪怪的,是否可以用实验证明一下呢~就是你说的这个方法的收敛性?这份代码我写了太久了,很多细节我都记不太清了,但是我记得possible_deals这个我当时是推了很久公式,而且做了很多收敛性实验的。

如果可以做几个实验,说明确实在使用你说的 -4 的情况下程序收敛性更好,我感觉就很能说明问题了~

yffbit commented 2 years ago

你先不要纠结收敛性,我指出的是ev计算方式的问题,举个不恰当的例子,博弈树中每个叶子节点的ev都返回0,不管哪种CFR算法肯定直接就收敛了。你先想清楚我说的-4对不对。 你可以看一下别人关于这一点的实现 https://github.com/happypepper/DeepHoldem/blob/68953137dd9d154eee9985284963eeecc58a311a/Source/Nn/next_round_value.lua#L76-L79

bupticybee commented 2 years ago

这里计算possible_deals应该要减去双方手牌张数之和,也就是减4,而不是减2 拿6张牌{A,B,C,D,E,F}举例,对于任意具体的节点,例如player1拿A,player2拿B,发公共牌时实际只有4个动作{C,D,E,F},也可以对齐到6个动作,其中2个动作概率为0,剩余4个动作概率均为1/4。对于向量形式,例如计算player1的信息集A的期望收益(或虚拟价值),player2拿{B,C,D,E,F},虽然发公共牌有5种情况,但是对5个子节点加权求和时,只有4个子节点的期望收益做出了贡献。 现在的计算方式乘上5/4才是真实值。这也不是什么大问题,真正出问题是在发牌节点的父节点处。假设父节点的fold动作进入叶子节点,call动作进入发牌节点,这两个子节点的期望收益一个是真实值,另一个乘上5/4才是真实值,两个值直接(加权)求和就有问题。

我知道你说的-4的意思了,我回忆了一下,我一开始写的是-4,后来推完公式这里才改成-2的,原因我还真忘了。。回头我做一下实验,如果改成-4收敛性变好那肯定说明你的理论是对的