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 相关文章推荐
Web服务器框架 Tornado简介
Jul 16 Python
python中urllib模块用法实例详解
Nov 19 Python
Python配置文件解析模块ConfigParser使用实例
Apr 13 Python
浅析Python中元祖、列表和字典的区别
Aug 17 Python
Python中断言Assertion的一些改进方案
Oct 27 Python
解决python3捕获cx_oracle抛出的异常错误问题
Oct 18 Python
python异步实现定时任务和周期任务的方法
Jun 29 Python
Python计算一个点到所有点的欧式距离实现方法
Jul 04 Python
Django中提供的6种缓存方式详解
Aug 05 Python
Python+OpenCv制作证件图片生成器的操作方法
Aug 21 Python
浅析Python语言自带的数据结构有哪些
Aug 27 Python
tensorflow模型继续训练 fineturn实例
Jan 21 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
PHP删除数组中的特定元素的代码
2012/06/28 PHP
探讨PHP中OO之静态关键字以及类常量的详解
2013/06/07 PHP
php实现图片缩放功能类
2013/12/18 PHP
php中apc缓存使用示例
2013/12/25 PHP
php实现json编码的方法
2015/07/30 PHP
Yii2框架实现注册和登录教程
2016/09/30 PHP
laravel 解决路由除了根目录其他都404的问题
2019/10/18 PHP
javascript 获取函数形参个数
2014/07/31 Javascript
node.js实现BigPipe详解
2014/12/05 Javascript
使用纯javascript实现经典扫雷游戏
2015/04/23 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
JQ图片文件上传之前预览功能的简单实例(分享)
2017/11/12 Javascript
JavaScript实现创建自定义对象的常用方式总结
2018/07/09 Javascript
vue项目中使用rem,在入口文件添加内容操作
2020/11/11 Javascript
vant 中van-list的用法说明
2020/11/11 Javascript
Python getopt模块处理命令行选项实例
2014/05/13 Python
Python实现比较两个列表(list)范围
2015/06/12 Python
Python中对象的引用与复制代码示例
2017/12/04 Python
Python实战小程序利用matplotlib模块画图代码分享
2017/12/09 Python
微信跳一跳辅助python代码实现
2018/01/05 Python
浅谈python中真正关闭socket的方法
2018/12/18 Python
python requests.get带header
2020/05/05 Python
html5的websockets全双工通信详解学习示例
2014/02/26 HTML / CSS
HTML5图片层叠的实现示例
2020/07/07 HTML / CSS
J2EE面试题大全
2016/08/06 面试题
幼儿园长自我鉴定
2013/10/17 职场文书
劲霸男装广告词
2014/03/21 职场文书
给市场的环保建议书
2014/05/14 职场文书
人力资源管理专业自荐信
2014/06/24 职场文书
课程设计的心得体会
2014/09/03 职场文书
民间借贷协议书范本
2014/10/01 职场文书
关于颐和园的导游词
2015/01/30 职场文书
个人求职意向书
2015/05/11 职场文书
纪检干部学习心得体会
2016/01/23 职场文书
 python中的元类metaclass详情
2022/05/30 Python
MySql按时,天,周,月进行数据统计
2022/08/14 MySQL