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操作mongodb的9个步骤
Jun 04 Python
Python使用爬虫抓取美女图片并保存到本地的方法【测试可用】
Aug 30 Python
python 将列表中的字符串连接成一个长路径的方法
Oct 23 Python
python 同时运行多个程序的实例
Jan 07 Python
Python根据当前日期取去年同星期日期
Apr 14 Python
python 随机森林算法及其优化详解
Jul 11 Python
如何实现Django Rest framework版本控制
Jul 25 Python
对Pytorch中nn.ModuleList 和 nn.Sequential详解
Aug 18 Python
在django中实现choices字段获取对应字段值
Jul 12 Python
对python中list的五种查找方法说明
Jul 13 Python
Python可视化工具如何实现动态图表
Oct 23 Python
Python提取PDF指定内容并生成新文件
Jun 09 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 gd等比例缩放压缩图片函数
2016/06/12 PHP
php 的多进程操作实践案例分析
2020/02/28 PHP
JS 实现Json查询的方法实例
2013/04/12 Javascript
jQuery插件实现控制网页元素动态居中显示
2015/03/24 Javascript
js实现网页多级级联菜单代码
2015/08/20 Javascript
每天一篇javascript学习小结(String对象)
2015/11/18 Javascript
浅谈Sublime Text 3运行JavaScript控制台
2016/06/06 Javascript
JS实现鼠标滑过显示边框的菜单效果
2016/09/21 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
angularjs实现多张图片上传并预览功能
2017/02/24 Javascript
JavaSctit 利用FileReader和滤镜上传图片预览功能
2017/09/05 Javascript
angular写一个列表的选择全选交互组件的示例
2018/01/22 Javascript
详解vue项目中如何引入全局sass/less变量、function、mixin
2018/06/02 Javascript
JS 实现微信扫一扫功能
2018/09/14 Javascript
vue 移动端注入骨架屏的配置方法
2019/06/25 Javascript
稍微学一下Vue的数据响应式(Vue2及Vue3区别)
2019/11/21 Javascript
vue 计算属性和侦听器的使用小结
2021/01/25 Vue.js
[44:50]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 TNC vs VG
2018/04/02 DOTA
Pyinstaller打包.py生成.exe的方法和报错总结
2019/04/02 Python
python and or用法详解
2019/06/26 Python
Python爬取腾讯视频评论的思路详解
2019/12/19 Python
浅谈Html5页面打开app的一些思考
2020/03/30 HTML / CSS
新浪网技术部笔试题
2016/08/26 面试题
专业幼师实习生自我鉴定范文
2013/12/08 职场文书
数学检讨书1000字
2014/02/24 职场文书
2014年实习生工作总结
2014/11/27 职场文书
出纳岗位职责
2015/01/31 职场文书
任命书怎么写
2015/03/02 职场文书
最感人的道歉情书
2015/05/12 职场文书
2015年环保局工作总结
2015/05/22 职场文书
小兵张嘎观后感
2015/06/03 职场文书
MySQL快速插入一亿测试数据
2021/06/23 MySQL
MySQL数据库完全卸载的方法
2022/03/03 MySQL
Android Rxjava3 使用场景详解
2022/04/07 Java/Android
MySQL视图概念以及相关应用
2022/04/19 MySQL
Python自动操作神器PyAutoGUI的使用教程
2022/06/16 Python