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群发邮件实例代码
Jan 03 Python
Python中给List添加元素的4种方法分享
Nov 28 Python
django限制匿名用户访问及重定向的方法实例
Feb 07 Python
Django实现全文检索的方法(支持中文)
May 14 Python
python使用epoll实现服务端的方法
Oct 16 Python
详解Appium+Python之生成html测试报告
Jan 04 Python
selenium 多窗口切换的实现(windows)
Jan 18 Python
Python @property装饰器原理解析
Jan 22 Python
Python3如何判断三角形的类型
Apr 12 Python
PyQt5 文本输入框自动补全QLineEdit的实现示例
May 13 Python
Selenium Webdriver元素定位的八种常用方式(小结)
Jan 13 Python
详解Python爬虫爬取博客园问题列表所有的问题
Jan 18 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 curl 并发最佳实践代码分享
2012/09/05 PHP
PHP中的生成XML文件的4种方法分享
2012/10/06 PHP
PHP实现简单实用的验证码类
2015/07/29 PHP
PHP实现会员账号单唯一登录的方法分析
2019/03/07 PHP
在textarea文本域中显示HTML代码的方法
2007/03/06 Javascript
javascript学习笔记(六) Date 日期类型
2012/06/19 Javascript
jQuery中innerHeight()方法用法实例
2015/01/19 Javascript
JS+CSS实现下拉列表框美化效果(3款)
2015/08/15 Javascript
原生JS实现美图瀑布流布局赏析
2015/09/07 Javascript
jquery通过name属性取值的简单实现方法
2016/06/20 Javascript
js如何判断是否在iframe中及防止网页被别站用iframe嵌套
2017/01/11 Javascript
JS实现点击下拉菜单把选择的内容同步到input输入框内的实例
2018/01/23 Javascript
微信小程序动态添加view组件的实例代码
2019/05/23 Javascript
浅探express路由和中间件的实现
2019/09/30 Javascript
jQuery实现移动端图片上传预览组件的方法分析
2020/05/01 jQuery
js+css3实现炫酷时钟
2020/08/18 Javascript
[04:14]从西雅图到上海——玩家自制DOTA2主题歌曲应援TI9
2019/07/11 DOTA
Python的Bottle框架中返回静态文件和JSON对象的方法
2015/04/30 Python
Python基于最小二乘法实现曲线拟合示例
2018/06/14 Python
PyQt5的安装配置过程,将ui文件转为py文件后显示窗口的实例
2019/06/19 Python
对python 调用类属性的方法详解
2019/07/02 Python
python3 dict ndarray 存成json,并保留原数据精度的实例
2019/12/06 Python
Python测试线程应用程序过程解析
2019/12/31 Python
sklearn线性逻辑回归和非线性逻辑回归的实现
2020/06/09 Python
html5弹跳球示例代码
2013/07/23 HTML / CSS
HTML5通用接口详解
2016/06/12 HTML / CSS
Get The Label中文官网:英国运动时尚购物平台
2017/04/19 全球购物
有机童装:Toby Tiger
2018/05/23 全球购物
LODI女鞋在线商店:阿利坎特的鞋类品牌
2019/02/15 全球购物
《春雨》教学反思
2014/04/24 职场文书
加油口号大全
2014/06/13 职场文书
2014年四风问题自我剖析材料
2014/09/15 职场文书
2015年业务员工作总结范文
2015/04/07 职场文书
2015年司机年终工作总结
2015/05/14 职场文书
2016年企业先进员工事迹材料
2016/02/25 职场文书
Python实现灰色关联分析与结果可视化的详细代码
2022/03/25 Python