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简单实现获取当前时间
Aug 27 Python
python爬取哈尔滨天气信息
Jul 14 Python
Python合并多个Excel数据的方法
Jul 16 Python
对Pycharm创建py文件时自定义头部模板的方法详解
Feb 12 Python
浅谈PYTHON 关于文件的操作
Mar 19 Python
python创建n行m列数组示例
Dec 02 Python
Django框架models使用group by详解
Mar 11 Python
解决jupyter notebook打不开无反应 浏览器未启动的问题
Apr 10 Python
Python filter过滤器原理及实例应用
Aug 18 Python
深入分析python 排序
Aug 24 Python
pip 20.3 新版本发布!即将抛弃 Python 2.x(推荐)
Dec 16 Python
Python+uiautomator2实现自动刷抖音视频功能
Apr 29 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
ThinkPHP CURD方法之order方法详解
2014/06/18 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
基于PHP给大家讲解防刷票的一些技巧
2015/11/18 PHP
yii数据库的查询方法
2015/12/28 PHP
PHP设计模式之迭代器模式
2016/06/17 PHP
替代window.event.srcElement效果的可兼容性的函数
2009/12/18 Javascript
Jquery 表格合并的问题分享
2011/09/17 Javascript
jquery remove方法应用详解
2012/11/22 Javascript
JQuery实现鼠标滑过显示导航下拉列表
2013/09/12 Javascript
jQuery子窗体取得父窗体元素的方法
2015/05/11 Javascript
js时间戳和c#时间戳互转方法(推荐)
2017/02/15 Javascript
nodeJS(express4.x)+vue(vue-cli)构建前后端分离实例(带跨域)
2017/07/05 NodeJs
详解在vue-cli中引用jQuery、bootstrap以及使用sass、less编写css
2017/11/08 jQuery
详解性能更优越的小程序图片懒加载方式
2018/07/18 Javascript
使用Angular-CLI构建NPM包的方法
2018/09/07 Javascript
vue 项目打包时样式及背景图片路径找不到的解决方式
2019/11/12 Javascript
详解javascript中var与ES6规范中let、const区别与用法
2020/01/11 Javascript
浅谈vue 组件中的setInterval方法和window的不同
2020/07/30 Javascript
在vue-cli3中使用axios获取本地json操作
2020/07/30 Javascript
Python中关于使用模块的基础知识
2015/05/24 Python
Django URL传递参数的方法总结
2016/08/28 Python
Python实现抓取网页生成Excel文件的方法示例
2017/08/05 Python
对python中不同模块(函数、类、变量)的调用详解
2019/07/16 Python
Python 导入文件过程图解
2019/10/15 Python
K最近邻算法(KNN)---sklearn+python实现方式
2020/02/24 Python
python中strip(),lstrip(),rstrip()函数的使用讲解
2020/11/17 Python
手把手教你用纯css3实现轮播图效果实例
2017/05/04 HTML / CSS
Stührling手表官方网站:男女高品质时尚手表的领先零售商
2021/01/07 全球购物
SQL Server 2000数据库的文件有哪些,分别进行描述
2013/03/30 面试题
捐助倡议书范文
2014/04/15 职场文书
我为党旗添光彩演讲稿
2014/09/13 职场文书
2014法院干警廉洁警示教育思想汇报
2014/09/13 职场文书
个人房屋转让协议书范本
2014/10/26 职场文书
解约证明模板
2015/06/19 职场文书
小学庆六一主持词
2015/06/30 职场文书
小学毕业教师寄语
2019/06/21 职场文书