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连接mysql并提交mysql事务示例
Mar 05 Python
python实现在字符串中查找子字符串的方法
Jul 11 Python
Python爬虫实现爬取京东手机页面的图片(实例代码)
Nov 30 Python
python中sys.argv函数精简概括
Jul 08 Python
Python3.7实现中控考勤机自动连接
Aug 28 Python
OpenCV图像颜色反转算法详解
May 13 Python
Pytorch模型转onnx模型实例
Jan 15 Python
Python-opencv实现红绿两色识别操作
Jun 04 Python
python 安装移动复制第三方库操作
Jul 13 Python
python使用smtplib模块发送邮件
Dec 17 Python
python自然语言处理之字典树知识总结
Apr 25 Python
Python学习开发之图形用户界面详解
Aug 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
二次元帅气男生排行榜,只想悄悄收藏系列
2020/03/04 日漫
用PHP的ob_start();控制您的浏览器cache!
2007/02/14 PHP
发布一个用PHP fsockopen写的HTTP下载的类
2007/02/22 PHP
解析PHP生成静态html文件的三种方法
2013/06/18 PHP
PHP实现对站点内容外部链接的过滤方法
2014/09/10 PHP
js获取时间(本周、本季度、本月..)
2013/11/22 Javascript
常用jQuery选择器总结
2014/07/11 Javascript
元素绑定click点击事件方法
2015/06/08 Javascript
apply和call方法定义及apply和call方法的区别
2015/11/15 Javascript
JavaScript中Form表单技术汇总(推荐)
2016/06/26 Javascript
JS封装通过className获取元素的函数示例
2016/12/20 Javascript
关于JS Lodop打印插件打印Bootstrap样式错乱问题的解决方案
2016/12/23 Javascript
node.js连接MongoDB数据库的2种方法教程
2017/05/17 Javascript
vue  directive定义全局和局部指令及指令简写
2018/11/20 Javascript
微信小程序实现获取小程序码和二维码java接口开发
2019/03/29 Javascript
微信小程序页面上下滚动效果
2020/11/18 Javascript
从零撸一个pc端vue的ui组件库( 计数器组件 )
2019/08/08 Javascript
基于iview-admin实现动态路由的示例代码
2019/10/02 Javascript
微信小程序利用button控制条件标签的变量问题
2020/03/15 Javascript
Python实现生成简单的Makefile文件代码示例
2015/03/10 Python
Windows下实现Python2和Python3两个版共存的方法
2015/06/12 Python
Python实现冒泡排序的简单应用示例
2017/12/11 Python
pycharm重置设置,恢复默认设置的方法
2018/10/22 Python
python 判断txt每行内容中是否包含子串并重新写入保存的实例
2020/03/12 Python
CSS3实现10种Loading效果
2016/07/11 HTML / CSS
HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
2017/01/05 HTML / CSS
THE OUTNET英国官网:国际设计师品牌折扣网站
2016/08/14 全球购物
Lampegiganten丹麦:欧洲领先的照明网上商店
2018/04/25 全球购物
Molly Bracken法国电子商店:法国女性时尚品牌
2019/07/24 全球购物
静态成员和非静态成员的区别
2012/05/12 面试题
市场营销专科应届生求职信
2013/11/24 职场文书
出纳岗位职责模板
2013/11/27 职场文书
装饰施工员岗位职责
2015/04/11 职场文书
员工离职证明范本
2015/06/12 职场文书
解决numpy和torch数据类型转化的问题
2021/05/23 Python
解决SpringBoot文件上传临时目录找不到的问题
2021/07/01 Java/Android