蒙特卡洛法求解“惯蛋”中“同花顺”出现的概率
蒙特卡洛法求解“惯蛋”中“同花顺”出现的概率
背景知识
“惯蛋”
“惯蛋”使用两幅标准扑克牌 (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变量实现判断还有没有).
再看0
…4
,1
…5
, …,8
…12
是否有一张或一张牌以上. 若有, 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% |
蒙特卡洛法求解“惯蛋”中“同花顺”出现的概率相关推荐
- 技术图文:排序技术在求解算法题中的应用
背景 前段时间,在知识星球立了一个Flag,这是总结Leetcode刷题的第五篇图文. 理论部分 C# 中的排序 对集合类的排序,我们通常使用位于 System.Core 程序集,System.Lin ...
- adams求微分方程c语言,ADAMS在求解微分方程组中的应用
ADAMS 在求解微分方程组中的应用在求解微分方程组中的应用 众所周知 ADAMS 具有强大的结算功能,在求解动力学问题方面可谓得心应手.在此 我想介绍一下它在求解非线性微分方程组方面的应用. 在工程 ...
- 动态规划在求解传递闭包问题中的应用(JAVA)--Warshell算法
动态规划在求解传递闭包问题中的应用: 传递闭包:对于n个顶点有向图来说,如果第i个顶点到第j个顶点之间存在一条有效的有向路径(即长度大于0的路径),那么T(i, j) = 1,否则T(i, j) = ...
- 分治法在求解凸包问题中的应用(JAVA)--快包算法
分治法在求解凸包问题中的应用(JAVA) 之前写过一篇蛮力法在求解凸包问题中的应用(JAVA)还算简单易懂,没有基础的读者最好先去阅读以下. 这里用分治法来求解凸包问题,由于这个算法和快速排序十分相似 ...
- 蛮力法在求解最优解问题中的应用(JAVA)--旅行家问题、背包问题、分配问题
蛮力法在求解最优解问题中的应用 1.TSP(旅行商问题)要求我们找出一条n个给定城市之间的最短路径,使我们再回到出发的城市之前,对欧每个城市都只访问一次.我们可以用赋权图来描述这个问题,那么算法的目的 ...
- 减治法在求解拓扑排序问题中的应用(JAVA)--有向无环图
减治法在求解拓扑排序问题中的应用 拓扑排序:对于一个有向无环图来说,如果我们能够按照次序列出顶点,使得对于每条边来说,边的起始顶点总是排在边的结束顶点之前,那么这个过程就称为拓扑排序,拓扑排序有解是一 ...
- HDU 4622 求解区间字符串中的不同子串的个数
题目大意: 给定一个长度<2000的串,再给最多可达10000的询问区间,求解区间字符串中的不同子串的个数 这里先考虑求解一整个字符串的所有不同子串的方法 对于后缀自动机来说,我们动态往里添加一 ...
- 多功能运算求解器_matlab中bsxfun函数
多功能运算求解器----matlab中bsxfun函数 [学习背景] 在我学习高斯函数中,看到了out=bsxfun(@times, x, w )这么一句程序,这引起了我的好奇,因而查看了matlab ...
- 惯导运算中的常值国际单位制惯导中常用单位
一.常值: (1)半长轴(Semi-major axis):半长轴是椭圆长轴的一半长,长轴是过焦点与椭圆相交的线段长.半长轴长即是行星离主星的平均距离.半长轴的长度与半短轴的关系可以经由离心率和半正焦 ...
最新文章
- 3行代码就能可视化Transformer的奥义 | 开源
- Linux服务器常见问题
- win32下PE文件分析之节表
- 7月17日云栖精选夜读:深度 | 两个案例,掌握AI在大数据领域的前沿应用
- 汇编中的DW:DW 定义一个字
- python for in循环_Python傻瓜教程:跟我学for循环
- 【学习笔记】JS进阶语法一document对象
- 如何在群晖服务器上启用plex远程访问,如何在Synology NAS上更新Plex | MOS86
- 5G工业路由器 物联网终端应用
- Markdown MarkdownPad2 win10上显示awesomium
- macOS Big Sur中雷蛇鼠标驱动 雷云2.0无法正常使用解决办法与mac雷蛇卸载
- 外语学习的真实方法及误区
- matlab传递函数状态方程转换,利用matlab对状态方程与传递函数转换
- 使用协同过滤推荐算法进行电影推荐
- 因为计算机中丢失lua.dll,lua51.dll丢失修复
- java-工作时突发的一个天马行空的想法
- KEIL MDK5 更好用 更简洁 的ARM开发环境
- 20230225在WIN10下安装PR2023失败的解决
- c语言服务器制作,C语言写的简易实用的web服务器
- 短视频批量伪原创 视频md5修改手机版