我是一个巨大的粉丝杀死尖顶,我想分享一个小概率伎俩,我了解到,通过计算“贪婪”的几率来帮助我改善我的游戏。此技巧也可能在卡或概率基于卡或概率中受益,但是本帖子的示例将具体杀死尖顶。
我有一个甲板,其中包含N个可取的卡片。如果我从那个甲板上绘制H卡,我绘制的机会是什么(完全/至少/最多)的米望?
这种问题通常在纸牌游戏中出现,包括复杂的游戏(如杀死尖顶)或更简单的(如扑克)。以下是一些具体示例,涉及杀戮尖端的具体示例:
“下一页转我画5张牌。如果在甲板上留下7张牌,其中4张牌,其中4张是罢工的,那么我绘制了至少3次罢工的可能性是什么。
“一个霓虹灯奖金让我失去了7 Max HP,从3个随机稀有卡中选择。现在我只对17个可能的罕见卡中的6个感兴趣,所以我至少有1个中的那6岁时是什么机会?“
关于杀死尖顶的好事是它是一个基于转向的单人游戏,所以(与扑克不同)你可以在决定轮到你的时候,没有人急于赶快快点。这意味着我可以安全地盯着这些概率计算来增加我的获胜可能性。
在这篇文章中,我将首先向上述概率问题提供解决方案(既是数学公式和代码),然后解释为什么公式工作。
在提出解决方案到上述问题之前,我首先要使用更精确的设置表示法来重新抑制问题,以避免模糊性:
将U定义为甲板中的所有卡的通用集,然后定义那些卡的两个(潜在重叠)的子集:
最后,我们将使用∩表示设置的交叉点,我们将使用它来定义四个非重叠(即差别)集:
¬B│乙┌─────────┼─────────┐¬A│¬A∩¬B│¬A∩乙│────┼────── ────────────────────────────────────
如果设置A和B的大小是固定的,则它们重叠的概率是什么(即设置A≠B)具有给定的大小?
问题并不具体到卡。它将适用于任意集
问题不具体到绘制卡或可取的卡。它适用于任何两个卡片
问题是关于A和B对称的。如果我们换交一张卡的两个子集的大小,我们希望得到相同的答案
使用| S |表示集合和使用的大小(即基数)!要表示因子,那么通过给定尺寸重叠的两个固定大小亚组的概率是:
| A |! ×|¬a|! ×| B |! ×|¬b|!p =───────────────────────────────── ──────────────── ×| a∩¬b|! ×|¬a∩b |! ×|¬a∩¬b|! ×|你|!
通过这种解决方案,我们可以通过重命名变量来解决我们的原始问题:
我有一个甲板包含| b |理想的卡片| U |总卡。如果我绘制| A |来自那个甲板的卡,我绘制的机会是什么(完全/至少/最多)| A∩b |可取的卡?
我们已经拥有了我们绘制的案例的解决方案A∩B |可取的卡片。从中,我们可以最多或至少计算绘图的解决方案a∩b |可取的卡片。
如果您仍然不遵循,我将上述解决方案转换为哈斯克尔代码。
......只有四个自由度,因为以下四个不相交的大小的大小:
| a | = | a∩b | + | a∩¬b||¬a| = |¬a∩b | + |¬a∩¬b|| B | = | a∩b | + |¬a∩b ||¬b| = | a∩¬b| + |¬a∩¬b|| U | = | a∩b | + | a∩¬b| + |¬a∩b | + |¬a∩¬b|
...因此,我们API中的每个函数都只需要四个函数参数,对应于那些四个不相交集的大小。还有其他方式可以定义使用不同四个自由度的API,但我发现这个接口是最简单且最对称的。
模块概率导入数字.Natural(自然) - 使用默认情况下使用精确的Rational算法而不是浮点算术默认(自然,理性) - 强制性:http://www.willamette.edu/~fruehr/haskell/evolution。 HTML?因子::(枚举n,num n)=> n - > n因子n =产品[1 ..n] { - |两组尺寸@ | a | @和@ | b | @ hignap by一组完全尺寸@ | @ prop>恰好1 0 A === 1%(A + 1)PROP>恰好A B 0 0 === 1 PROP>恰好A 0 B 0 === 1 PROP>完全是一个b c d ===完全是c b d - }完全::(enum n,fractional n)=>自然 - ^ @ | a∩b | @ - >自然 - ^ @ | a∩¬b| @ - >自然 - ^ @ |¬a∩b| @ - >自然 - ^ @ |¬a¬b| @ - > n恰好_ab _anotb _bnota notab =从integralutor / ulfinteglal致偏执符,其中_a = _ab + _anotb _b = _ab + nota nota = _bnotb + notab = _bnota + notab _u = _bnota + notab _u = _bn + _anotb + _bnota + notab numerator = product(map argetorial [_a ,nota,_b,notb])分母=产品(地图阶段[_ab,_anotb,_bnota,notab,notab,_u]){ - |两组大小@ | a | a | @和@ | b | @ oype of tase @ | @ prop>至少0 a b c === 1 prop>至少a b c d ===最多的a c b d-}至少::(enum n,fractional n)=>自然 - ^ @ | a∩b | @ - >自然 - ^ @ | a∩¬b| @ - >自然 - ^最大尺寸@ |¬a∩b| @ - >自然 - ^ @ |@∩¬b| @ - > n至少_ab _anotb _bnota notab = sum(map superhootby [0 ..(min _anotb _bnota)),其中超管x =完全(_ab + x)(_bnotb-x)(_bnota-x)(notab + x){ - |两组尺寸@ | a | @和@ | b | @ oderap of moly size @ | @ prop>最多0 A B C ===完全是0 a b c prop>最多一个0 b c === 1 prop>最多A B 0 C === 1 Prop>最多A B C D ===最多的C B D Prop≫最多一个b c d +至少a b c d === 1 +完全a b c d-}最高:( enum n,fractional n)=>自然 - ^ @ | a∩b | @ - >自然 - ^ @ | a∩¬b| @ - >自然 - ^ @ | @∩b | @ - >自然 - ^最大尺寸@ |¬a∩¬b| @ - > n最多_ab _anotb _bnota notab = sum(映射下划线[0 ..(min _ab notab)]其中下鼻x =完全(_ab-x)(_anotb + x)(_bnota + x)(notab-x)
练习:如果您不使用Haskell,请尝试将上面的功能移植到您喜欢的编程语言中。
让我们在Slay The Spire中测试在示例场景上驱动上述实用程序。
“下一页转我画5张牌。如果在甲板上留下7张牌,其中4张牌,其中4张是罢工的,那么我绘制了至少3次罢工的可能性是什么。
在这里,我们将使用eAtleast函数具有以下每个不相交集合的以下输入大小: | a∩b | = 3 - 我们希望绘制至少3张罢工卡 | a∩¬b| = 2 - 我们希望绘制最多2张非罢工卡 |¬a∩b| = 1 - 我们希望在甲板上最多留出1张罢工卡 |¬a∩¬b| = 1 - 我们希望在甲板中留下至少1个非触发卡 锻炼:使用最高功能来计算最多2次罢工的缩短机会。 “一个霓虹灯奖金让我失去了7 Max HP,从3个随机稀有卡中选择。 现在我只对17个可能的罕见卡中的6个感兴趣,所以我至少有1个中的那6岁时是什么机会?“
这也将使用与每个不相交集合的以下输入大小的eAtleast函数: | a∩b | = 1 - 我们希望绘制至少1个所需的稀有卡 | a∩¬b| = 2 - 我们希望绘制最多2个不合需要的珍稀卡片 |¬a∩b| = 5 - 我们希望在游泳池中最多留下5个可取的卡片 |¬a∩¬b| = 9 - 我们希望在游泳池中留下至少9个不受欢迎的卡片 本节提供了一个半严格的解释,为什么公式工作,虽然可能不足以被称为证明。 {正确的双手的数量} p =──────────────────────────可能的手数}
可能的手数是我们可以画出尺寸的方式的数量A | (无需替换)来自|池| U |卡片(我们的甲板):
绘制的方式的数量| a∩b |来自池的理想卡| B |可取的卡片和
绘制的方法的数量| a∩¬b|来自池的不良卡|¬B|不受欢迎的卡片
{正确的双手的数量} =(| b |选择| a∩b |)×(|¬b|选择| a∩¬b|)
(| B |选择| A∩B|)×(|¬B| ────────────────────选择| A |
然后,我们可以使用“n选择k”公式来计算从K卡池中选择N卡的方法数而无需更换,这使我们提供:
| B |! |¬b|! ────────────────────×──────────────────────|一个∩C |! ×|¬a∩b |! | A∩¬B|! ×|¬A∩¬B|!P =─────────────────────────────────────── ───────你|! ───────────── ×|¬a|
| A |! ×|¬a|! ×| B |! ×|¬b|!p =───────────────────────────────── ──────────────── ×| a∩¬b|! ×|¬a∩b |! ×|¬a∩¬b|! ×|你|! 不幸的是,这个配方在一个人的头上很难做到,所以我经常将这些实用程序函数加载到Haskell Rept中,以便在棘手的转弯上进行数学。 我尚未对这种概率计算获得快速和近似答案的容易启发式。 但是,如果您愿意花时间计算这种计算的可能性,可以快速增加,从而提高赢得尖顶运行的速度。 我经常使用这个技巧来计算贪婪戏剧的期望值,这可以在运行过程中拯救相当多的健康或药水。