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中的RSS处理
Apr 13 Python
python实现周期方波信号频谱图
Jul 21 Python
Django Admin中增加导出Excel功能过程解析
Sep 04 Python
Python搭建代理IP池实现存储IP的方法
Oct 27 Python
python flask搭建web应用教程
Nov 19 Python
flask框架配置mysql数据库操作详解
Nov 29 Python
python 实现 hive中类似 lateral view explode的功能示例
May 18 Python
Python 如何在字符串中插入变量
Aug 01 Python
Python 忽略文件名编码的方法
Aug 01 Python
在 Python 中使用 MQTT的方法
Aug 18 Python
python openssl模块安装及用法
Dec 06 Python
python使用shell脚本创建kafka连接器
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
德生1994机评
2021/03/02 无线电
人大复印资料处理程序_输入篇
2006/10/09 PHP
PHP 强制性文件下载功能的函数代码(任意文件格式)
2010/05/26 PHP
PHP json_encode中文乱码问题的解决办法
2013/09/09 PHP
php判断ip黑名单程序代码实例
2014/02/24 PHP
ThinkPHP连接数据库及主从数据库的设置教程
2014/08/22 PHP
WordPress开发中用于获取近期文章的PHP函数使用解析
2016/01/05 PHP
PHP设计模式之注册树模式分析
2018/01/26 PHP
ThinkPHP防止重复提交表单的方法实例分析
2018/05/10 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
PHP cookie与session会话基本用法实例分析
2019/11/18 PHP
复制小说文本时出现的随机乱码的去除方法
2010/09/07 Javascript
js 判断图片是否加载完以及实现图片的预下载
2014/08/14 Javascript
js获取iframe中的window对象的实现方法
2016/05/20 Javascript
js Canvas实现圆形时钟教程
2016/09/19 Javascript
微信公众平台开发教程(五)详解自定义菜单
2016/12/02 Javascript
jQuery实现frame之间互通的方法
2017/06/26 jQuery
详解为生产环境编译Angular2应用的方法
2018/12/10 Javascript
JavaScript设计模式之观察者模式实例详解
2019/01/16 Javascript
js实现tab栏切换效果
2020/08/02 Javascript
js实现拖拽与碰撞检测
2020/09/18 Javascript
javascript实现滚轮轮播图片
2020/12/13 Javascript
python爬虫神器Pyppeteer入门及使用
2019/07/13 Python
django+tornado实现实时查看远程日志的方法
2019/08/12 Python
PyCharm更改字体和界面样式的方法步骤
2019/09/27 Python
Python流程控制常用工具详解
2020/02/24 Python
CSS3 input框的实现代码类似Google登录的动画效果
2020/08/04 HTML / CSS
HTML5页面直接调用百度地图API获取当前位置直接导航目的地的实现代码
2018/03/02 HTML / CSS
全球游戏Keys和卡片市场:GamesDeal
2018/03/28 全球购物
DeinDesign德国:设计自己的手机壳
2019/12/14 全球购物
培训讲师邀请函
2014/01/10 职场文书
中学生寄语大全
2014/04/03 职场文书
董事长年会致辞
2015/07/29 职场文书
期中考试后的感想
2015/08/07 职场文书
寒假致家长的一封信
2015/10/10 职场文书
python制作图形界面的2048游戏, 基于tkinter
2021/04/06 Python