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中处理unchecked未捕获异常实例
Jan 17 Python
利用Python学习RabbitMQ消息队列
Nov 30 Python
Python实现二维数组输出为图片
Apr 03 Python
对Tensorflow中权值和feature map的可视化详解
Jun 14 Python
python图的深度优先和广度优先算法实例分析
Oct 26 Python
Django框架中间件定义与使用方法案例分析
Nov 28 Python
Python实现检测文件的MD5值来查找重复文件案例
Mar 12 Python
Python通过zookeeper实现分布式服务代码解析
Jul 22 Python
matplotlib.pyplot.plot()参数使用详解
Jul 28 Python
PyCharm安装PyQt5及其工具(Qt Designer、PyUIC、PyRcc)的步骤详解
Nov 02 Python
如何用PyPy让你的Python代码运行得更快
Dec 02 Python
Python中super().__init__()测试以及理解
Dec 06 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
PHP中的extract的作用分析
2008/04/09 PHP
PHP命名空间(Namespace)的使用详解
2013/05/04 PHP
php数组中删除元素之重新索引的方法
2014/09/16 PHP
Codeigniter购物车类不能添加中文的解决方法
2014/11/29 PHP
php 比较获取两个数组相同和不同元素的例子(交集和差集)
2019/10/18 PHP
javascript 进阶篇2 CSS XML学习
2012/03/14 Javascript
详谈jQuery操纵DOM元素属性 attr()和removeAtrr()方法
2015/01/22 Javascript
js制作简易年历完整实例
2015/01/28 Javascript
js与jquery回车提交的方法
2015/02/03 Javascript
Jquery解析json字符串及json数组的方法
2015/05/29 Javascript
jquery密码强度校验
2015/12/02 Javascript
详解Bootstrap插件
2016/04/25 Javascript
jQuery插件autocomplete使用详解
2017/02/04 Javascript
JavaScript模块化之使用requireJS按需加载
2017/04/12 Javascript
JavaScript仿微信打飞机游戏
2020/07/05 Javascript
nginx配置域名后的二级目录访问不同项目的配置操作
2020/11/06 Javascript
JS实现百度搜索框
2021/02/25 Javascript
pycharm 使用心得(三)Hello world!
2014/06/05 Python
Python实现快速多线程ping的方法
2015/07/15 Python
详解Python中的文件操作
2016/08/28 Python
Python编程把二叉树打印成多行代码
2018/01/04 Python
收藏!10个免费高清视频素材网站!【设计、视频剪辑必备】
2021/03/18 杂记
西班牙灯具网上商店:Lampara.es
2018/06/05 全球购物
sort命令的作用和用法
2012/11/04 面试题
学生实习自我鉴定
2013/10/11 职场文书
护理专业毕业生推荐信
2013/10/31 职场文书
工商管理专业应届生求职信
2013/11/04 职场文书
校本教研工作制度
2014/01/22 职场文书
大学生创业策划书
2014/02/02 职场文书
个人授权委托书范文
2014/09/21 职场文书
英语通知范文
2015/04/22 职场文书
西部计划志愿者工作总结
2015/08/11 职场文书
送给自己的励志语句:要安静的优秀,悄无声息的坚强
2019/11/26 职场文书
python基础之文件处理知识总结
2021/05/23 Python
js前端设计模式优化50%表单校验代码示例
2022/06/21 Javascript
hive数据仓库新增字段方法
2022/06/25 数据库