Python 内置模块之 random
常用API?
import random# 隨機(jī)小數(shù) print(random.random()) # 大于0且小于1之間的小數(shù)。0<= n<1.0 print(random.uniform(1,3)) # 大于1小于3的小數(shù)# 隨機(jī)整數(shù) print(random.randint(1,5)) # 大于等于1且小于等于5之間的整數(shù)#從指定范圍內(nèi),按指定基數(shù)遞增的集合中 獲取一個隨機(jī)數(shù)。 random.randrange([start], stop[, step]) random.randrange(10, 30, 2) # 結(jié)果相當(dāng)于從[10, 12, ... 26, 28]序列中獲取一個隨機(jī)數(shù)。 random.randrange(10, 30, 2) # 在結(jié)果上與 random.choice(range(10, 30, 2) 等效。# 隨機(jī)選擇一個返回 print(random.choice([1,'23',[4,5]])) # 1或者23或者[4,5] # 隨機(jī)選擇多個返回,返回的個數(shù)為函數(shù)的第二個參數(shù) print(random.sample([1,'23',[4,5]],2)) # 列表元素任意2個組合[[4, 5], '23']# 打亂列表順序 item=[1,3,5,7,9] random.shuffle(item) # 打亂次序 print(item) # [5, 1, 3, 7, 9] random.shuffle(item) print(item) # [5, 9, 7, 1, 3]加權(quán)隨機(jī)算法實現(xiàn)
方法一
最簡單的方法可以這樣:把序列按權(quán)重值擴(kuò)展成:lists=[A,A,A,A,A,B,B,C,C,D],然后random.choice(lists)隨機(jī)選一個就行。雖然這樣選取的時間復(fù)雜度是O(1),但是數(shù)據(jù)量一大,空間消耗就太大了。
# coding:utf-8 import randomdef weight_choice(list, weight):""":param list: 待選取序列:param weight: list對應(yīng)的權(quán)重序列: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]))?
?
方法二
比較常用的方法是這樣:計算權(quán)重總和sum,然后在1到sum之間隨機(jī)選擇一個數(shù)R,之后遍歷整個集合,統(tǒng)計遍歷的項的權(quán)重之和,如果大于等于R,就停止遍歷,選擇遇到的項。
還是以上面的集合為例,sum等于10,如果隨機(jī)到1-5,則會在遍歷第一個數(shù)字的時候就退出遍歷。符合所選取的概率。
選取的時候要遍歷集合,它的時間復(fù)雜度是O(n)。
?
# coding:utf-8 import randomlist = ['A', 'B', 'C', 'D']def weight_choice(weight):""":param weight: list對應(yīng)的權(quán)重序列:return:選取的值在原列表里的索引"""t = random.randint(0, sum(weight) - 1)for i, val in enumerate(weight):t -= valif t < 0:return iif __name__ == "__main__":print(list[weight_choice([5, 2, 2, 1])])方法三
可以先對原始序列按照權(quán)重排序。這樣遍歷的時候,概率高的項可以很快遇到,減少遍歷的項。(因為rnd遞減的速度最快(先減去最大的數(shù)))比較{A:5,B:2,C:2,D:1}和{B:2,C:2,A:5,D:1}前者遍歷步數(shù)的期望是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。這樣提高了平均選取速度,但是原序列排序也需要時間。先搞一個權(quán)重值的前綴和序列,然后在生成一個隨機(jī)數(shù)t后,可以用二分法來從這個前綴和序列里找,那么選取的時間復(fù)雜度就是O(logn)了。
# coding:utf-8 import random import bisectlist = ['A', 'B', 'C', 'D']def weight_choice(weight):""":param weight: list對應(yīng)的權(quán)重序列:return:選取的值在原列表里的索引"""weight_sum = []sum = 0for a in weight:sum += aweight_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])])?
總結(jié)
以上是生活随笔為你收集整理的Python 内置模块之 random的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最新计算机毕业设计源码开源啦,java毕
- 下一篇: Python 内置模块之 ConfigP