python的random模块及加权随机算法的python实现方法


Posted in Python onJanuary 04, 2017

random是用于生成随机数的,我们可以利用它随机生成数字或者选择字符串。

•random.seed(x)改变随机数生成器的种子seed。

一般不必特别去设定seed,Python会自动选择seed。

•random.random()    用于生成一个随机浮点数n,0 <= n < 1

•random.uniform(a,b)    用于生成一个指定范围内的随机浮点数,生成的随机整数a<=n<=b;

•random.randint(a,b)    用于生成一个指定范围内的整数,a为下限,b为上限,生成的随机整数a<=n<=b;若a=b,则n=a;若a>b,报错

•random.randrange([start], stop [,step])    从指定范围[start,stop)内,按指定基数递增的集合中获取一个随机数,基数缺省值为1

•random.choice(sequence)    从序列中获取一个随机元素,参数sequence表示一个有序类型,并不是一种特定类型,泛指list,tuple,字符串等

•random.shuffle(x[,random])    用于将一个列表中的元素打乱 (洗牌),会改变原始列表

•random.sample(sequence,k)    从指定序列中随机获取k个元素作为一个片段返回,不会改变原有序列

那么现在基础知识有了,我们来实现一个加权随机算法:

加权随机算法一般应用在以下场景:有一个集合S,里面比如有A,B,C,D这四项。这时我们想随机从中抽取一项,但是抽取的概率不同,比如我们希望抽到A的概率是50%,抽到B和C的概率是20%,D的概率是10%。一般来说,我们可以给各项附一个权重,抽取的概率正比于这个权重。那么上述集合就成了:

{A:5,B:2,C:2,D:1}

方法一:

最简单的方法可以这样:

把序列按权重值扩展成:lists=[A,A,A,A,A,B,B,C,C,D],然后random.choice(lists)随机选一个就行。虽然这样选取的时间复杂度是O(1),但是数据量一大,空间消耗就太大了。

# coding:utf-8
import random


def weight_choice(list, weight):
  """
  :param list: 待选取序列
  :param weight: list对应的权重序列
  :return:选取的值
  """
  new_list = []
  for i, val in enumerate(list):
    new_list.extend(val * weight[i])
  return random.choice(new_list)


if __name__ == "__main__":
  print(weight_choice(['A', 'B', 'C', 'D'], [5, 2, 2, 1]))

方法二:

比较常用的方法是这样:

计算权重总和sum,然后在1到sum之间随机选择一个数R,之后遍历整个集合,统计遍历的项的权重之和,如果大于等于R,就停止遍历,选择遇到的项。

还是以上面的集合为例,sum等于10,如果随机到1-5,则会在遍历第一个数字的时候就退出遍历。符合所选取的概率。

选取的时候要遍历集合,它的时间复杂度是O(n)。

# coding:utf-8
import random

list = ['A', 'B', 'C', 'D']


def weight_choice(weight):
  """
  :param weight: list对应的权重序列
  :return:选取的值在原列表里的索引
  """
  t = random.randint(0, sum(weight) - 1)
  for i, val in enumerate(weight):
    t -= val
    if t < 0:
      return i


if __name__ == "__main__":
  print(list[weight_choice([5, 2, 2, 1])])

方法三:

可以先对原始序列按照权重排序。这样遍历的时候,概率高的项可以很快遇到,减少遍历的项。(因为rnd递减的速度最快(先减去最大的数))

比较{A:5,B:2,C:2,D:1}和{B:2,C:2,A:5,D:1}

前者遍历步数的期望是5/10*1+2/10*2+2/10*3+1/10*4=19/10而后者是2/10*1+2/10*2+5/10*3+1/10*4=25/10。

这样提高了平均选取速度,但是原序列排序也需要时间。

先搞一个权重值的前缀和序列,然后在生成一个随机数t后,可以用二分法来从这个前缀和序列里找,那么选取的时间复杂度就是O(logn)了。

 

# coding:utf-8
import random
import bisect

list = ['A', 'B', 'C', 'D']


def weight_choice(weight):
  """
  :param weight: list对应的权重序列
  :return:选取的值在原列表里的索引
  """
  weight_sum = []
  sum = 0
  for a in weight:
    sum += a
    weight_sum.append(sum)
  t = random.randint(0, sum - 1)
  return bisect.bisect_right(weight_sum, t)


if __name__ == "__main__":
  print(list[weight_choice([5, 2, 2, 1])])

以上这篇python的random模块及加权随机算法的python实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3基础之函数用法
Aug 13 Python
Python实现telnet服务器的方法
Jul 10 Python
Python进阶之尾递归的用法实例
Jan 31 Python
Python线程下使用锁的技巧分享
Sep 13 Python
python读取图片任意范围区域
Jan 23 Python
Django高级编程之自定义Field实现多语言
Jul 02 Python
Jupyter Notebook的连接密码 token查询方式
Apr 21 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
Apr 22 Python
Pytorch损失函数nn.NLLLoss2d()用法说明
Jul 07 Python
python爬虫使用正则爬取网站的实现
Aug 03 Python
pycharm 配置svn的图文教程(手把手教你)
Jan 15 Python
Python函数对象与闭包函数
Apr 13 Python
python 实现红包随机生成算法的简单实例
Jan 04 #Python
Python 模板引擎的注入问题分析
Jan 01 #Python
python getopt详解及简单实例
Dec 30 #Python
浅谈编码,解码,乱码的问题
Dec 30 #Python
Python实现将数据库一键导出为Excel表格的实例
Dec 30 #Python
python脚本实现数据导出excel格式的简单方法(推荐)
Dec 30 #Python
利用python生成一个导出数据库的bat脚本文件的方法
Dec 30 #Python
You might like
自己前几天写的无限分类类
2007/02/14 PHP
为PHP5.4开启Zend OPCode缓存
2014/12/26 PHP
使用PHP如何实现高效安全的ftp服务器(二)
2015/12/30 PHP
jquery JSON的解析方式
2009/07/25 Javascript
jquery.Jwin.js 基于jquery的弹出层插件代码
2012/05/23 Javascript
jQuery.buildFragment使用方法及思路分析
2013/01/07 Javascript
jQuery模拟物体自由落体运动(附演示与demo源码下载)
2016/01/21 Javascript
JavaScript中的ParseInt(&quot;08&quot;)和“09”返回0的原因分析及解决办法
2016/05/19 Javascript
轮播的简单实现方法
2016/07/28 Javascript
微信小程序 删除项目工程实现步骤
2016/11/10 Javascript
利用js编写网页进度条效果
2017/10/08 Javascript
JS实现十字坐标跟随鼠标效果
2017/12/25 Javascript
javascript实现获取一个日期段内每天不同的价格(计算入住总价格)
2018/02/05 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
2019/01/18 jQuery
Vue CLI3基础学习之pages构建多页应用
2019/06/02 Javascript
用python + openpyxl处理excel2007文档思路以及心得
2014/07/14 Python
Python编程中的异常处理教程
2015/08/21 Python
Python Django使用forms来实现评论功能
2016/08/17 Python
Python对字符串实现去重操作的方法示例
2017/08/11 Python
Pandas实现数据类型转换的一些小技巧汇总
2018/05/07 Python
解决python报错MemoryError的问题
2018/06/26 Python
对Python 两大环境管理神器 pyenv 和 virtualenv详解
2018/12/31 Python
Python3中_(下划线)和__(双下划线)的用途和区别
2019/04/26 Python
django的settings中设置中文支持的实现
2019/04/28 Python
Python多线程threading模块用法实例分析
2019/05/22 Python
利用python numpy+matplotlib绘制股票k线图的方法
2019/06/26 Python
python按行读取文件并找出其中指定字符串
2019/08/08 Python
浅析PyTorch中nn.Linear的使用
2019/08/18 Python
python区分不同数据类型的方法
2019/10/14 Python
python随机模块random使用方法详解
2020/02/14 Python
基于pygame实现童年掌机打砖块游戏
2020/02/25 Python
秋季运动会加油稿200字
2014/01/11 职场文书
合作投资意向书
2014/04/01 职场文书
大学生敬老院活动总结
2015/05/07 职场文书
二审答辩状范文
2015/05/22 职场文书
幼儿园国培研修日志
2015/11/13 职场文书