python的random模組及加權隨機演算法的python實現方法,randompython

來源:互聯網
上載者:User

python的random模組及加權隨機演算法的python實現方法,randompython

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-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, 2, 1]))

方法二:

比較常用的方法是這樣:

計算權重總和sum,然後在1到sum之間隨機播放一個數R,之後遍曆整個集合,統計遍曆的項的權重之和,如果大於等於R,就停止遍曆,選擇遇到的項。

還是以上面的集合為例,sum等於10,如果隨機到1-5,則會在遍曆第一個數位時候就退出遍曆。符合所選取的機率。

選取的時候要遍曆集合,它的時間複雜度是O(n)。

# coding:utf-8import randomlist = ['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 iif __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-8import randomimport bisectlist = ['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實現方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援幫客之家。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.