蒙特卡洛法求解“惯蛋”中“同花顺”出现的概率

背景知识

“惯蛋”

“惯蛋”使用两幅标准扑克牌 (4*13+2/副), 有4个玩家, 每个玩家轮流随机抽取27张牌.

“同花顺”

“同花顺”为玩家所持有的牌中花色相同且数字连续的五张牌的组合. 同时, 10 J Q K A 为一种特殊的同花顺组合.

思路

采用蒙特卡洛随机数值模拟方法

若采用枚举法, 有 108 C 27 = 2.10 × 1 0 25 ^{108} \mathrm{C}_{27} = 2.10 \times 10^{25} 108C27​=2.10×1025 种牌的组合, 无法在有限时间内完成运算.

分步骤解决问题

Step 1

只有相同花色才可能组同花顺. 因此先将牌区分花色. 同时大等于5张牌才可能, 因此移除 (不考虑) 小于5张牌的花色.

Step 2

对于每一种花色:(即一个数组):

分别用两种方法计算其中的同花顺个数,取二者最大值.

  • 方法一: 由10开始遍历,
    10 J Q K A 是否都有一张或一张以上的牌. 若有, n(即用这种方法计算的同花顺的数量)加一, 并这5张牌数量-1. 循环此步骤直到按这种方法计算没有同花顺了(用Flag变量实现判断还有没有).
    再看04, 15, …, 812是否有一张或一张牌以上. 若有, n +1, 有的五张牌牌数-1.
  • 方法二: 由A开始遍历. 其余同上. 开始方法二前须再次初始化牌数组,因为数组中的牌数量已在1中改变.

用两个方法的原因:
例如对于A 2 3 4 5 6 10 J Q K的序列, 由10开始遍历, 则得2组. 由A开始遍历,则得1组;
对于9 10 J Q K A 2 3 4 5的序列, 由10开始遍历, 则得1组. 由A开始遍历, 则得2组.


对于不同随机抽取的27张牌, 通过上述两个步骤, 计算出这27张牌中的同花顺的个数. 重复多次, 获得近似概率.


实验代码:

import randomclass Solve:  # Start with 0, Adef __init__(self):passdef update_card(self, cards):self.cards = cardsdef split_color_and_sort(self):self.splited = []color_0 = []color_1 = []color_3 = []color_2 = []for i in range(len(self.cards)):card = self.cards[i]if card[1] == 0:color_0.append(card[0])elif card[1] == 1:color_1.append(card[0])elif card[1] == 2:color_2.append(card[0])else:color_3.append(card[0])# color_0.sort()# color_1.sort()# color_2.sort()# color_3.sort()if len(color_0) > 4:self.splited.append(color_0)if len(color_1) > 4:self.splited.append(color_1)if len(color_2) > 4:self.splited.append(color_2)if len(color_3) > 4:self.splited.append(color_3)def has_n_in_splited(self):t_n = 0for splited_sub in self.splited:# Start with 1:n_start_with_1 = 0arr = [0 for i in range(13)]for card_no in splited_sub:arr[card_no] += 1arr.append(arr[0])while True:have_left = Falsefor i in range(10):flag = Truefor j in range(5):if arr[i + j] <= 0:flag = Falseif flag:have_left = Truen_start_with_1 += 1for j in range(5):arr[i + j] -= 1if i == 0:arr[-1] -= 1elif i == 9:arr[0] -= 1if not have_left:break# Start with 10n_start_with_10 = 0arr = [0 for i in range(13)]for card_no in splited_sub:arr[card_no] += 1for i in [9, 10, 11, 12, 0]:if arr[i] <= 0:  # No cardbreakelse:# Continousn_start_with_10 += 1for i in [9, 10, 11, 12, 0]:arr[i] -= 1while True:have_left = Falsefor i in range(9):flag = Truefor j in range(5):if arr[i + j] <= 0:flag = Falseif flag:have_left = Truen_start_with_10 += 1for j in range(5):arr[i + j] -= 1if not have_left:breakt_n += n_start_with_1 if n_start_with_1 >= n_start_with_10 else n_start_with_10return t_ndef random_select(cards, n=27):_cards = cards[:]selected = []for i in range(n):# print(_cards)index = random.randint(0, len(_cards) - 1)selected.append(_cards[index])_cards.pop(index)return selectedwhole = []
for color in range(4):for num in range(13):whole.append([num, color])
whole.append([-1, -1])
whole.append([-1, -1])
whole *= 2
print(whole)rst = {}S = Solve()for i in range(100000):# print("W", whole)selected = random_select(whole)S.update_card(selected)S.split_color_and_sort()n = S.has_n_in_splited()if n in rst:rst[n] += 1else:rst.update({n: 1})print(rst)

实验结果

重复 100 , 000 100,000 100,000次, 获得输出

{0: 67352, 1: 29454, 2: 3123, 3: 71}

同花顺个数 概率
0 67.35%
1 29.45%
2 3.12%
3 0.07%

蒙特卡洛法求解“惯蛋”中“同花顺”出现的概率相关推荐

  1. 技术图文:排序技术在求解算法题中的应用

    背景 前段时间,在知识星球立了一个Flag,这是总结Leetcode刷题的第五篇图文. 理论部分 C# 中的排序 对集合类的排序,我们通常使用位于 System.Core 程序集,System.Lin ...

  2. adams求微分方程c语言,ADAMS在求解微分方程组中的应用

    ADAMS 在求解微分方程组中的应用在求解微分方程组中的应用 众所周知 ADAMS 具有强大的结算功能,在求解动力学问题方面可谓得心应手.在此 我想介绍一下它在求解非线性微分方程组方面的应用. 在工程 ...

  3. 动态规划在求解传递闭包问题中的应用(JAVA)--Warshell算法

    动态规划在求解传递闭包问题中的应用: 传递闭包:对于n个顶点有向图来说,如果第i个顶点到第j个顶点之间存在一条有效的有向路径(即长度大于0的路径),那么T(i, j) = 1,否则T(i, j) = ...

  4. 分治法在求解凸包问题中的应用(JAVA)--快包算法

    分治法在求解凸包问题中的应用(JAVA) 之前写过一篇蛮力法在求解凸包问题中的应用(JAVA)还算简单易懂,没有基础的读者最好先去阅读以下. 这里用分治法来求解凸包问题,由于这个算法和快速排序十分相似 ...

  5. 蛮力法在求解最优解问题中的应用(JAVA)--旅行家问题、背包问题、分配问题

    蛮力法在求解最优解问题中的应用 1.TSP(旅行商问题)要求我们找出一条n个给定城市之间的最短路径,使我们再回到出发的城市之前,对欧每个城市都只访问一次.我们可以用赋权图来描述这个问题,那么算法的目的 ...

  6. 减治法在求解拓扑排序问题中的应用(JAVA)--有向无环图

    减治法在求解拓扑排序问题中的应用 拓扑排序:对于一个有向无环图来说,如果我们能够按照次序列出顶点,使得对于每条边来说,边的起始顶点总是排在边的结束顶点之前,那么这个过程就称为拓扑排序,拓扑排序有解是一 ...

  7. HDU 4622 求解区间字符串中的不同子串的个数

    题目大意: 给定一个长度<2000的串,再给最多可达10000的询问区间,求解区间字符串中的不同子串的个数 这里先考虑求解一整个字符串的所有不同子串的方法 对于后缀自动机来说,我们动态往里添加一 ...

  8. 多功能运算求解器_matlab中bsxfun函数

    多功能运算求解器----matlab中bsxfun函数 [学习背景] 在我学习高斯函数中,看到了out=bsxfun(@times, x, w )这么一句程序,这引起了我的好奇,因而查看了matlab ...

  9. 惯导运算中的常值国际单位制惯导中常用单位

    一.常值: (1)半长轴(Semi-major axis):半长轴是椭圆长轴的一半长,长轴是过焦点与椭圆相交的线段长.半长轴长即是行星离主星的平均距离.半长轴的长度与半短轴的关系可以经由离心率和半正焦 ...

最新文章

  1. 3行代码就能可视化Transformer的奥义 | 开源
  2. Linux服务器常见问题
  3. win32下PE文件分析之节表
  4. 7月17日云栖精选夜读:深度 | 两个案例,掌握AI在大数据领域的前沿应用
  5. 汇编中的DW:DW 定义一个字
  6. python for in循环_Python傻瓜教程:跟我学for循环
  7. 【学习笔记】JS进阶语法一document对象
  8. 如何在群晖服务器上启用plex远程访问,如何在Synology NAS上更新Plex | MOS86
  9. 5G工业路由器 物联网终端应用
  10. Markdown MarkdownPad2 win10上显示awesomium
  11. macOS Big Sur中雷蛇鼠标驱动 雷云2.0无法正常使用解决办法与mac雷蛇卸载
  12. 外语学习的真实方法及误区
  13. matlab传递函数状态方程转换,利用matlab对状态方程与传递函数转换
  14. 使用协同过滤推荐算法进行电影推荐
  15. 因为计算机中丢失lua.dll,lua51.dll丢失修复
  16. java-工作时突发的一个天马行空的想法
  17. KEIL MDK5 更好用 更简洁 的ARM开发环境
  18. 20230225在WIN10下安装PR2023失败的解决
  19. c语言服务器制作,C语言写的简易实用的web服务器
  20. 短视频批量伪原创 视频md5修改手机版

热门文章

  1. 见证历史!数学家张益唐北大讲座:本质上已证明“零点猜想”,111页论文已公开...
  2. 一直按键的44444又来了
  3. python中的浮点数类型
  4. 特许权使用费(Royalty Fee)
  5. stemwin 19264单色屏移植
  6. 疑难技术点汇总(一)---手机号正则匹配
  7. 计算机组成原理移位运算实验报告,移位运算器实验报告.doc
  8. 在「生机」与「升级」持续的化学反应之中,科技企业走向新生
  9. 设计模式之外观模式php,PHP设计模式:外观模式
  10. Redis缓存穿透解决方案