24点扑克游戏详细解析附代码
24点扑克游戏详细解析附代码
题目要求:
52张牌里面选4张,可以重复,任意使用±/*和括号,使得最后运算结果为24.
多少种排列组合:
有131313*13种排列,但是这些排列的牌会有重复的,比如(1,1,2,3)和(1,3,2,1)就算是重复,把不重复的叫做一个组合,那么实际上有1820种组合。
成功的组合:
这1820种组合里面有1362种组合是成功解的。
成功的概率:
但是因为每个组合出现的概率不一样,不能使用1362/1820来做成功概率。比如组合123包含排列123,132,213,231,312,321.而组合221只包含排列122,212,221.所以最后的成功概率是要加权计算的,最后的成功概率为80.0%左右
优化求概率算法:
实际上,推广到广义更多牌(非4张),更多点数(非13点),可能使用完全逐一验证排列的算法会很耗时。例如变形为从无数副扑克里面挑10张牌出来算24点,复杂度变为13的10次方,如果使用逐一验证每个排列是否有解,会很耗性能。另外一种思路是随机抽样调查,随机产生适当数量的排列,验证是否有解,然后统计概率。
代码:
本算法的get_math_probability是逐个验证解,get_sim_probability是模拟统计解,对于一种组合,使用遍历换位,括号,运算符的方式来生成表达式。使用eval函数来计算表达式。
算法的坑:
对于(3,3,8,8)组合,有解"8/(3-8/3)"=24,但是如果直接计算会得到23.99999999999.所以解决方案是把eval(expr)==24改为abs(eval(expr)-24)<0.000001。限制精确度范围。
为什么是24:
因为24有1,2,3,4,6,8,12,24。总共8乘法个因子,并且24/4=6,6这个数字在[1,13]点里面是中间位置。所以24无论是乘除法,还是加减法都比较容易拼凑,使用其它数字会降低成功概率。
源代码:
#怎么模拟排列组合
import itertools as it
import random#permutations('ABCD', 2)排列 A42
#combinations('ABCD', 2)组合 C42def get_tu_res(tu):''':param tu: 整数元组:return: 能成功做出24点的字符串的集合'''situation = it.permutations(tu, 4)res=set()for si in situation:a,b,c,d=sifor o1 in "+-*/":for o2 in "+-*/":for o3 in "+-*/":# 那么三个符号根据运算顺序有6种顺序123,132,213,231,321,例如123是先算o1,再o2,再o3,其中312和132重复了e1=f"(({a}{o1}{b}){o2}{c}){o3}{d}"e2= f"({a}{o1}{b}){o2}({c}{o3}{d})"e3= f"({a}{o1}({b}{o2}{c})){o3}{d}"e4 = f"{a}{o1}(({b}{o2}{c}){o3}{d})"e5 = f"{a}{o1}({b}{o2}({c}{o3}{d}))"for expr in (e1,e2,e3,e4,e5):try:t=eval(expr)except:continueif t==24:res.add(expr)return resdef is_ok_tu(tu):'''性能提高在如果找到第一个解的时候就跳出了,节省计算:param tu: 整数元组:return: 布尔值,能否运算成24点'''situation = it.permutations(tu, 4)for si in situation:a, b, c, d = sifor o1 in "+-*/":for o2 in "+-*/":for o3 in "+-*/":# 那么三个符号根据运算顺序有6种顺序123,132,213,231,321,例如123是先算o1,再o2,再o3,其中312和132重复了e1 = f"(({a}{o1}{b}){o2}{c}){o3}{d}"e2 = f"({a}{o1}{b}){o2}({c}{o3}{d})"e3 = f"({a}{o1}({b}{o2}{c})){o3}{d}"e4 = f"{a}{o1}(({b}{o2}{c}){o3}{d})"e5 = f"{a}{o1}({b}{o2}({c}{o3}{d}))"for expr in (e1, e2, e3, e4, e5):try:t = eval(expr)except:continueif abs(t-24)<0.00000001:#防止恶心的"8/(3-8/3)"之类的发生return Truereturn Falsedef get_defeat_com():all_com=get_all_com()defeat_com = set() # 失败的组合for tu in all_com:if not is_ok_tu(tu):defeat_com.add(tu)return defeat_comdef get_all_com():#包括重复数字的所有组合#实际上是有1820种组合com = set() # 所有的组合for a in range(1, 14):for b in range(a, 14):for c in range(b, 14):for d in range(c, 14):# 保证了(a,b,c,d)本身就是非降序的tu = (a, b, c, d)com.add(tu)return comdef get_math_probability(defeat_com):#小数据用数学法,大数据用模蒙特卡洛拟法cnt_defeat=0for a in range(1,14):for b in range(1,14):for c in range(1,14):for d in range(1,14):arr=[a,b,c,d]arr.sort()tu=tuple(arr)if tu in defeat_com:cnt_defeat+=1probability=1-(cnt_defeat/28561)#13*13*13*13=28561return probabilitydef get_sim_probability(defeat_com):times=1000#模拟次数cnt_defeat=0for t in range(times):arr=[random.randint(1,13),random.randint(1,13),random.randint(1,13),random.randint(1,13)]arr.sort()tu=tuple(arr)if tu in defeat_com:cnt_defeat+=1return (times-cnt_defeat)/times# print(len(get_all_com()))#1820
# print(len(get_defeat_com()))#失败组合458,成功组合1362defeat_com=get_defeat_com()#最后大概得到0.80的成功率吧
print(get_math_probability(defeat_com))#0.7918140121144217
print(get_sim_probability(defeat_com))#0.807
24点扑克游戏详细解析附代码相关推荐
- php 运营商授权,PHP判断手机号运营商(详细介绍附代码)
道理很简单,知道手机号规则 进行正则判断就可以 移动:134.135.136.137.138.139.150.151.157(TD).158.159.187.188 联通:130.131.132.15 ...
- uniapp获取手机号(详细教程附代码)
uniapp获取手机号(详细教程附代码) 一.获取code 二.通过code获取获取openId 和 session_key 三.让用户授权(同意后需要对数据解密) 个人小程序不能使用这个功能,必须是 ...
- Java对象,Map,List,Set数组等相互转换大全(详细讲解,附代码,讲解案例)
Java对象,Map,List,Set数组等相互转换大全(详细讲解,附代码,讲解案例) Java对象 转 JSON字符串 JAVA对象转MAP Map转java对象 List转map List和Map ...
- HDMI EDID详细解析——C代码实现
继上一篇<HDMI EDID详细解析> https://blog.csdn.net/cfl927096306/article/details/108017501 现在用C代码来实现解析HD ...
- Java【冒泡排序】算法, 大白话式图文解析(附代码)
文章目录 前言 一.排序相关概念 1, 什么是排序 2, 什么是排序的稳定性 3, 七大排序分类 二.冒泡排序 1, 图文解析 2, 代码实现 3, 冒泡排序的优化 三.性能分析 四.七大排序算法总体 ...
- Python关于strftime函数详细解析 附实战代码
目录 前言 1. strftime函数 2. 实战 前言 项目中的python web中,时间都用到了这个函数 深挖了一下基本的知识点以及实战中的书写 主要参考的知识点有: Python time s ...
- 游戏服务端开发-AOI-九宫格法解析(附代码)
1-啥是AOI AOI全称Area Of Interest,中文就是感兴趣的区域,个人理解就是玩家关注的并且可视的地图区域. 在RPG游戏中,玩家角色移动,攻击,放技能等操作都需要向其他玩家广播,但服 ...
- 【智能算法】粒子群算法(Particle Swarm Optimization)超详细解析+入门代码实例讲解...
喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 算法起源 粒子群优化算法(PSO)是一种进化计算技术(evolutionary computation),1995 年由E ...
- labview2048小游戏详细解析+改进
这个账号我的新开的一个CSDN账号,以后就要坚持在这里把自己平时用到的学到的都更新到这里,这次先把我另一个账号中的文章转载过来.反正都是我原创的. _____________ 最近因为实验室需要,需要 ...
- python爬虫案例-python爬虫详细解析附案例
什么是爬虫框架 说这个之前,得先说说什么是框架: 是实现业界标准的组件规范:比如众所周知的MVC开发规范 提供规范所要求之基础功能的软件产品:比如Django框架就是MVC的开发框架,但它还提供了其他 ...
最新文章
- php定时执行代码漏洞_【漏洞风险提示】Drupal任意PHP代码执行漏洞通告
- node.js安装模式 的区别_如何使用nodejs写一个接口
- phoenix 开发API系列 目录
- html中调用flex中的函数
- ant+jmeter
- 【Python】Matplotlib绘制散点图
- Unity Occlusion Culling 遮挡剔除研究
- testng_TestNG超时示例
- [梦]2005.2.10
- [转].net中的认证(authentication)与授权(authorization)
- flex bison 下载
- 用vscode创建一个c项目_vscode怎么创建C语言项目
- eclipse汉化.设置为中文 简单好操作 java初学者看过来
- excel如何使用函数判断包含某值
- Android之按钮点击事件(单击、双击、长按等)
- 我崩溃了!Java大厂74道高级面试合集,面试心得体会
- TOEFL wordlist 35
- 数据中心安全域的设计和划分
- 通过nginx实现线上页面访问本地接口
- 输入商品显示商品名称和价格
热门文章
- 黑莓刷机及情景设置来电和短信等没有声音的解决办法
- 刷机必备:BlackBerry ROM,桌面管理器下载
- RPG类游戏开发方法
- Unix网络编程之epoll函数模拟10万客户端链接服务器
- Python实现QQ游戏连连看外挂秒杀
- 打开我的收藏夹 -- Python篇
- 从零搭建与好友“一起看王心凌《爱你》MV”功能
- 视频截取软件哪个好用?免费的视频截取软件分享
- 苹果平板计算机音乐,iphone、ipad上传照片、视频、音乐到电脑中 手机电脑互传文件...
- HTML+CSS静态页面网页设计作业 仿天猫购物商城(7页) 网页设计作业,网页制作作业, 学生网页作业, 网页作业成品, 网页作业模板