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

python的random模块及加权随机算法的python实现方法,第1张

概述random是用于生成随机数的,我们可以利用它随机生成数字或者选择字符串。•random.seed(x)改变随机数生成器的种子seed。

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,D],然后random.choice(Lists)随机选一个就行。虽然这样选取的时间复杂度是O(1),但是数据量一大,空间消耗就太大了。

# Coding:utf-8import randomdef 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,1]))

方法二:

比较常用的方法是这样:

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

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

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

# Coding:utf-8import randomList = ['A','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 iif __name__ == "__main__":  print(List[weight_choice([5,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-8import randomimport bisectList = ['A','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,1])])

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

您可能感兴趣的文章:python中的随机函数random的用法示例python实现随机森林random forest的原理及方法Python随机数用法实例详解【基于random模块】Python随机数random模块使用指南Python中random模块生成随机数详解python中随机函数random用法实例Python随机生成数模块random使用实例Python标准库之随机数 (math包、random包)介绍Python random模块(获取随机数)常用方法和使用例子Python随机函数random()使用方法小结 总结

以上是内存溢出为你收集整理的python的random模块及加权随机算法的python实现方法全部内容,希望文章能够帮你解决python的random模块及加权随机算法的python实现方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1204360.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存