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 实现链表实例代码
Apr 07 Python
python实现聊天小程序
Mar 13 Python
Python回文字符串及回文数字判定功能示例
Mar 20 Python
使用Python机器学习降低静态日志噪声
Sep 29 Python
GitHub 热门:Python 算法大全,Star 超过 2 万
Apr 29 Python
Django框架模板的使用方法示例
May 25 Python
Python vtk读取并显示dicom文件示例
Jan 13 Python
基于python 将列表作为参数传入函数时的测试与理解
Jun 05 Python
解决Keras TensorFlow 混编中 trainable=False设置无效问题
Jun 28 Python
python实现数字炸弹游戏
Jul 17 Python
python之随机数函数的实现示例
Dec 30 Python
python高温预警数据获取实例
Jul 23 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生成Flash动画的实现代码
2010/03/12 PHP
thinkphp控制器调度使用示例
2014/02/24 PHP
ThinkPHP3.1新特性之内容解析输出详解
2014/06/19 PHP
php绘制一个矩形的方法
2015/01/24 PHP
php实现paypal 授权登录
2015/05/28 PHP
php封装的page分页类完整实例
2016/10/18 PHP
JavaScript 学习笔记一些小技巧
2010/03/28 Javascript
javascript dom 基本操作小结
2010/04/11 Javascript
JavaScript高级程序设计 读书笔记之八 Function类及闭包
2012/02/27 Javascript
jquery实现滑动图片自己测试的例子
2013/11/05 Javascript
js实现俄罗斯方块小游戏分享
2014/01/31 Javascript
javascript 判断整数方法分享
2014/12/16 Javascript
JavaScript实现列表分页功能特效
2015/05/15 Javascript
jQuery hover事件简单实现同时绑定2个方法
2016/06/07 Javascript
JS如何判断json是否为空
2016/07/06 Javascript
Boostrap基础教程之JavaScript插件篇
2016/09/08 Javascript
vue.js中$watch的用法示例
2016/10/04 Javascript
React Native第三方平台分享的实例(Android,IOS双平台)
2017/08/04 Javascript
详解Vue用自定义指令完成一个下拉菜单(select组件)
2017/10/31 Javascript
VUE Elemen-ui之穿梭框使用方法详解
2021/01/19 Javascript
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
2015/04/16 Python
Python3指定路径寻找符合匹配模式文件
2015/05/22 Python
在MAC上搭建python数据分析开发环境
2016/01/26 Python
python简易远程控制单线程版
2018/06/20 Python
pandas去除重复列的实现方法
2019/01/29 Python
python适合人工智能的理由和优势
2019/06/28 Python
Python队列、进程间通信、线程案例
2019/10/25 Python
python实现自动化报表功能(Oracle/plsql/Excel/多线程)
2019/12/02 Python
Tensorflow全局设置可见GPU编号操作
2020/06/30 Python
澳大利亚领先的美容护肤品零售商之一:SkincareStore
2018/01/22 全球购物
Capitol Lighting的1800lighting.com:住宅和商业照明
2019/04/10 全球购物
物流管理专业毕业生求职信
2014/03/23 职场文书
高考寄语大全
2014/04/08 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
2015年幼儿园新年寄语
2014/12/08 职场文书
Redis读写分离搭建的完整步骤
2021/09/14 Redis