Python利用带权重随机数解决抽奖和游戏爆装备问题


Posted in Python onJune 16, 2016

关于带权随机数
为了帮助理解,先来看三类随机问题的对比:
1.已有n条记录,从中选取m条记录,选取出来的记录前后顺序不管。
实现思路:按行遍历所有记录,约隔n/m条取一个数据即可
2.在1类情况下,还要求选取出来的m条记录是随机排序的
实现思路: 给n条记录,分别增加一列标记,值为随机选取的1至n之间的不重复数据。
3.区别于1,2类问题, 如果记录是有权重的,如何结合权重去随机选取。 比如A的权重为10, B的权重股为5, C的权重为1, 则随机选取4个时可能应该出现AABB。
第3类问题便是本文重点了。
实现思路: 以 A:10, B:5, C:1 三条记录上随机选取4条为例,(是否以权重排序这个无所谓)
    对于
    A 10
    B 5
    C 1
首先,将第n行的数值赋为第n行加第n-1行的,递归执行,如下:
    A 10
    B 15
    C 16
然后每次从[1,16]随机选取一个数,如果落在[1,10]之间,则选取A,如果落在(10,15]之间则选B,如果落在(16,16]之间则选取C, 图示如下,谁占的区间大(权重高),被选上的概率更大。

Python利用带权重随机数解决抽奖和游戏爆装备问题

在抽奖和游戏爆装备中的运用
带权随机在游戏开发中重度使用,各种抽奖和爆装备等.
运营根据需要来配置各个物品出现的概率.
今天要说的这个带权随机算法思想很简单,就是"把所有物品根据其权重构成一个个区间,权重大的区间大.可以想象成一个饼图.  然后,扔骰子,看落在哪个区间,"
举个栗子,有个年终抽奖,物品是iphone/ipad/itouch.
主办方配置的权重是[('iphone', 10), ('ipad', 40), ('itouch', 50)].
用一行代码即可说明其思想,即random.choice(['iphone']*10 + ['ipad']*40 + ['itouch']*50).
下面,我们写成一个通用函数.

#coding=utf-8 
import random 
def weighted_random(items): 
  total = sum(w for _,w in items) 
  n = random.uniform(0, total)#在饼图扔骰子 
  for x, w in items:#遍历找出骰子所在的区间 
    if n<w: 
      break 
    n -= w 
  return x 
 
print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)])

上面的代码够直观,不过细心的会发现,每次都会计算total,每次都会线性遍历区间进行减操作.其实我们可以先存起来,查表就行了.利用accumulate+bisect二分查找.
物品越多,二分查找提升的性能越明显.

#coding=utf-8 
class WeightRandom: 
  def __init__(self, items): 
    weights = [w for _,w in items] 
    self.goods = [x for x,_ in items] 
    self.total = sum(weights) 
    self.acc = list(self.accumulate(weights)) 
 
  def accumulate(self, weights):#累和.如accumulate([10,40,50])->[10,50,100] 
    cur = 0 
    for w in weights: 
      cur = cur+w 
      yield cur 
 
  def __call__(self): 
    return self.goods[bisect.bisect_right(self.acc , random.uniform(0, self.total))] 
 
wr = WeightRandom([('iphone', 10), ('ipad', 40), ('itouch', 50)]) 
print wr()
Python 相关文章推荐
用Python编写一个简单的FUSE文件系统的教程
Apr 02 Python
总结Python编程中三条常用的技巧
May 11 Python
详解Python中find()方法的使用
May 18 Python
Python脚本实现自动将数据库备份到 Dropbox
Feb 06 Python
在Python中使用AOP实现Redis缓存示例
Jul 11 Python
Python基于pygame模块播放MP3的方法示例
Sep 30 Python
Django通过dwebsocket实现websocket的例子
Nov 15 Python
Python MySQL 日期时间格式化作为参数的操作
Mar 02 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
Mar 20 Python
Python3 webservice接口测试代码详解
Jun 23 Python
Python Flask异步发送邮件实现方法解析
Aug 01 Python
matplotlib 画动态图以及plt.ion()和plt.ioff()的使用详解
Jan 05 Python
Python黑魔法@property装饰器的使用技巧解析
Jun 16 #Python
Python实现类似jQuery使用中的链式调用的示例
Jun 16 #Python
浅析Python中else语句块的使用技巧
Jun 16 #Python
python基础教程之分支、循环简单用法
Jun 16 #Python
python3音乐播放器简单实现代码
Apr 20 #Python
使用python3.5仿微软记事本notepad
Jun 15 #Python
python3.5仿微软计算器程序
Mar 30 #Python
You might like
Windows下部署Apache+PHP+MySQL运行环境实战
2012/08/31 PHP
php获取$_POST同名参数数组的实现介绍
2013/06/30 PHP
ThinkPHP 3.2.2实现事务操作的方法
2017/05/05 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
PHP中的Iterator迭代对象属性详解
2019/04/12 PHP
Thinkphp极验滑动验证码实现步骤解析
2020/11/24 PHP
javascript中的几个运算符
2007/06/29 Javascript
div拖拽插件——JQ.MoveBox.js(自制JQ插件)
2013/05/17 Javascript
用js的for循环获取radio选中的值
2013/10/21 Javascript
js控制输入框获得和失去焦点时状态显示的方法
2015/01/30 Javascript
Yii2使用Bootbox插件实现自定义弹窗
2015/04/02 Javascript
Backbone.js的一些使用技巧
2015/07/01 Javascript
jQuery使用$.ajax提交表单完整实例
2015/12/11 Javascript
JavaScript判断对象是否为数组
2015/12/22 Javascript
浅谈js常用内置方法和对象
2016/09/24 Javascript
微信小程序 数据绑定详解及实例
2016/10/25 Javascript
jquery.uploadView 实现图片预览上传功能
2017/08/10 jQuery
在vue中实现点击选择框阻止弹出层消失的方法
2018/09/15 Javascript
React+Antd+Redux实现待办事件的方法
2019/03/14 Javascript
Angular2实现的秒表及改良版示例
2019/05/10 Javascript
JQuery的加载和选择器用法简单示例
2019/05/13 jQuery
微信小程序自定义多列选择器使用详解
2019/06/21 Javascript
Vue 使用计时器实现跑马灯效果的实例代码
2019/07/11 Javascript
JavaScript中的连续赋值问题实例分析
2019/07/12 Javascript
[10:21]2018DOTA2国际邀请赛寻真——Winstrike
2018/08/11 DOTA
python 根据pid杀死相应进程的方法
2017/01/16 Python
对python数据切割归并算法的实例讲解
2018/12/12 Python
Python 微信爬虫完整实例【单线程与多线程】
2019/07/06 Python
Python3操作MongoDB增册改查等方法详解
2020/02/10 Python
css3 实现圆形旋转倒计时
2018/02/24 HTML / CSS
html5 canvas合成海报所遇问题及解决方案总结
2017/08/03 HTML / CSS
英国123鲜花网站:123 Flowers
2019/07/07 全球购物
自考毕业自我鉴定范文
2013/10/27 职场文书
大学生涯自我鉴定
2014/01/16 职场文书
法制教育观后感
2015/06/17 职场文书
python可视化分析绘制带趋势线的散点图和边缘直方图
2022/06/25 Python