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中使用itertools模块中的组合函数的教程
Apr 13 Python
python放大图片和画方格实现算法
Mar 30 Python
Sanic框架蓝图用法实例分析
Jul 17 Python
在Pytorch中计算自己模型的FLOPs方式
Dec 30 Python
浅析Django 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求
Mar 09 Python
使用python处理题库表格并转化为word形式的实现
Apr 14 Python
python argparse模块通过后台传递参数实例
Apr 20 Python
详解python 内存优化
Aug 17 Python
详解scrapy内置中间件的顺序
Sep 28 Python
编写python代码实现简单抽奖器
Oct 20 Python
python 批量压缩图片的脚本
Jun 02 Python
Python matplotlib可视化之绘制韦恩图
Feb 24 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,不用COM,生成excel文件
2006/10/09 PHP
利用PHP+JS实现搜索自动提示(实例)
2013/06/09 PHP
采用ThinkPHP中F方法实现快速缓存实例
2014/06/13 PHP
Windows下编译PHP5.4和xdebug全记录
2015/04/03 PHP
php获取网页上所有链接的方法
2015/04/03 PHP
php和html的区别点详细总结
2019/09/24 PHP
Laravel 登录后清空COOKIE的操作方法
2019/10/14 PHP
HTML IMG标签 onload 内存溢出导致浏览器CPU占用过高
2021/03/09 Javascript
jquery autocomplete自动完成插件的的使用方法
2010/08/07 Javascript
封装了一个js图片轮换效果的函数
2011/09/28 Javascript
鼠标滚轮改变图片大小的示例代码
2013/11/20 Javascript
javascipt匹配单行和多行注释的正则表达式
2013/11/20 Javascript
修改js confirm alert 提示框文字的简单实例
2016/06/10 Javascript
详谈Angular 2+ 的表单(一)之模板驱动型表单
2017/04/25 Javascript
详解Vue中状态管理Vuex
2017/05/11 Javascript
ReactNative实现图片上传功能的示例代码
2017/07/11 Javascript
jQuery实现的页面弹幕效果【测试可用】
2018/08/17 jQuery
关于微信公众号开发无法支付的问题解决
2018/12/28 Javascript
vscode下vue项目中eslint的使用方法
2019/01/13 Javascript
Vue框架TypeScript装饰器使用指南小结
2019/02/18 Javascript
json 带斜杠时如何解析的实现
2019/08/12 Javascript
三步实现ionic3点击退出app程序
2019/09/17 Javascript
浅谈Vue SSR中的Bundle的具有使用
2019/11/21 Javascript
JS 数组和对象的深拷贝操作示例
2020/06/06 Javascript
python根据出生日期获得年龄的方法
2015/03/31 Python
ubuntu 安装pyqt5和卸载pyQt5的方法
2020/03/24 Python
Python爬取某平台短视频的方法
2021/02/08 Python
安纳塔拉酒店度假村及水疗官方网站:Anantara Hotel
2016/08/25 全球购物
美国婚礼和派对礼品网站:Kate Aspen(新娘送礼会、迎婴派对)
2018/03/28 全球购物
班级德育工作实施方案
2014/02/21 职场文书
《望庐山瀑布》教学反思
2014/04/22 职场文书
党的群众路线教育实践活动个人整改措施
2014/10/27 职场文书
企业整改报告范文
2014/11/08 职场文书
高三语文教学反思
2016/02/16 职场文书
2019经典广告词集锦!
2019/07/02 职场文书
新学期新寄语,献给新生们!
2019/11/15 职场文书