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 相关文章推荐
用Python脚本生成Android SALT扰码的方法
Sep 18 Python
Python中Collection的使用小技巧
Aug 18 Python
python批量制作雷达图的实现方法
Jul 26 Python
解决出现Incorrect integer value: '' for column 'id' at row 1的问题
Oct 29 Python
Python向MySQL批量插数据的实例讲解
Mar 31 Python
Python批量生成特定尺寸图片及图画任意文字的实例
Jan 30 Python
python3 selenium自动化测试 强大的CSS定位方法
Aug 23 Python
在python3中实现查找数组中最接近与某值的元素操作
Feb 29 Python
Python基于Serializer实现字段验证及序列化
Nov 04 Python
Django 用户认证Auth组件的使用
Nov 30 Python
Django实现在线无水印抖音视频下载(附源码及地址)
May 06 Python
Python中with上下文管理协议的作用及用法
Mar 18 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
判“新”函数:得到今天与明天的秒数
2006/10/09 PHP
CodeIgniter采用config控制的多语言实现根据浏览器语言自动转换功能
2014/07/18 PHP
如何在Laravel5.8中正确地应用Repository设计模式
2019/11/26 PHP
javascript重写alert方法的实例代码
2013/03/29 Javascript
onkeydown事件解决按回车键直接提交数据的需求
2013/04/11 Javascript
jquery利用ajax调用后台方法实例
2013/08/23 Javascript
jQuery之选项卡的简单实现
2014/02/28 Javascript
浅谈javascript中for in 和 for each in的区别
2015/04/23 Javascript
JavaScript获取各大浏览器信息图示
2015/11/20 Javascript
详解JavaScript中的自定义事件编写
2016/05/10 Javascript
jquery  实现轮播图详解及实例代码
2016/10/12 Javascript
jQuery之动画效果大全
2016/11/09 Javascript
使用BootStrap实现表格隔行变色及hover变色并在需要时出现滚动条
2017/01/04 Javascript
详解Jquery 遍历数组之$().each方法与$.each()方法介绍
2017/01/09 Javascript
vue.js中mint-ui框架的使用方法
2017/05/12 Javascript
Koa2微信公众号开发之本地开发调试环境搭建
2018/05/16 Javascript
微信小程序文章详情页跳转案例详解
2019/07/09 Javascript
一个基于flask的web应用诞生(1)
2017/04/11 Python
Django2.1.3 中间件使用详解
2018/11/26 Python
使用python3实现操作串口详解
2019/01/01 Python
Pycharm使用之设置代码字体大小和颜色主题的教程
2019/07/12 Python
django页面跳转问题及注意事项
2019/07/18 Python
Python绘制热力图示例
2019/09/27 Python
IntelliJ 中配置 Anaconda的过程图解
2020/06/01 Python
分享PyCharm最新激活码(真永久激活方法)不用每月找安装参数或最新激活码了
2020/12/27 Python
师范生的个人求职信范文
2014/01/04 职场文书
个人优缺点自我评价
2014/01/27 职场文书
《小蝌蚪找妈妈》教学反思
2014/02/21 职场文书
信息管理与信息系统专业求职信
2014/06/21 职场文书
2015年超市收银员工作总结
2015/04/25 职场文书
详解Redis实现限流的三种方式
2021/04/27 Redis
Python词云的正确实现方法实例
2021/05/08 Python
windows下快速安装nginx并配置开机自启动的方法
2021/05/11 Servers
python迷宫问题深度优先遍历实例
2021/06/20 Python
试用1103暨1103、1101同门大比武 [ DAIWEI ]
2022/04/05 无线电
HTML中link标签属性的具体用法
2023/05/07 HTML / CSS