亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python利用帶權(quán)重隨機(jī)數(shù)解決抽獎(jiǎng)和游戲爆裝備問(wèn)題

 更新時(shí)間:2016年06月16日 15:58:39   作者:mattkang  
帶權(quán)重隨機(jī)數(shù)即是隨機(jī)數(shù)各個(gè)區(qū)間段被抽中的概率根據(jù)權(quán)重而不同,這里我們就來(lái)看一下Python利用帶權(quán)重隨機(jī)數(shù)解決抽獎(jiǎng)和游戲爆裝備問(wèn)題的方法,首先還是來(lái)進(jìn)一步解釋帶權(quán)隨機(jī)數(shù):

關(guān)于帶權(quán)隨機(jī)數(shù)
為了幫助理解,先來(lái)看三類(lèi)隨機(jī)問(wèn)題的對(duì)比:
1.已有n條記錄,從中選取m條記錄,選取出來(lái)的記錄前后順序不管。
實(shí)現(xiàn)思路:按行遍歷所有記錄,約隔n/m條取一個(gè)數(shù)據(jù)即可
2.在1類(lèi)情況下,還要求選取出來(lái)的m條記錄是隨機(jī)排序的
實(shí)現(xiàn)思路: 給n條記錄,分別增加一列標(biāo)記,值為隨機(jī)選取的1至n之間的不重復(fù)數(shù)據(jù)。
3.區(qū)別于1,2類(lèi)問(wèn)題, 如果記錄是有權(quán)重的,如何結(jié)合權(quán)重去隨機(jī)選取。 比如A的權(quán)重為10, B的權(quán)重股為5, C的權(quán)重為1, 則隨機(jī)選取4個(gè)時(shí)可能應(yīng)該出現(xiàn)AABB。
第3類(lèi)問(wèn)題便是本文重點(diǎn)了。
實(shí)現(xiàn)思路: 以 A:10, B:5, C:1 三條記錄上隨機(jī)選取4條為例,(是否以權(quán)重排序這個(gè)無(wú)所謂)
    對(duì)于
    A 10
    B 5
    C 1
首先,將第n行的數(shù)值賦為第n行加第n-1行的,遞歸執(zhí)行,如下:
    A 10
    B 15
    C 16
然后每次從[1,16]隨機(jī)選取一個(gè)數(shù),如果落在[1,10]之間,則選取A,如果落在(10,15]之間則選B,如果落在(16,16]之間則選取C, 圖示如下,誰(shuí)占的區(qū)間大(權(quán)重高),被選上的概率更大。

2016616155350152.jpg (596×75)

在抽獎(jiǎng)和游戲爆裝備中的運(yùn)用
帶權(quán)隨機(jī)在游戲開(kāi)發(fā)中重度使用,各種抽獎(jiǎng)和爆裝備等.
運(yùn)營(yíng)根據(jù)需要來(lái)配置各個(gè)物品出現(xiàn)的概率.
今天要說(shuō)的這個(gè)帶權(quán)隨機(jī)算法思想很簡(jiǎn)單,就是"把所有物品根據(jù)其權(quán)重構(gòu)成一個(gè)個(gè)區(qū)間,權(quán)重大的區(qū)間大.可以想象成一個(gè)餅圖.  然后,扔骰子,看落在哪個(gè)區(qū)間,"
舉個(gè)栗子,有個(gè)年終抽獎(jiǎng),物品是iphone/ipad/itouch.
主辦方配置的權(quán)重是[('iphone', 10), ('ipad', 40), ('itouch', 50)].
用一行代碼即可說(shuō)明其思想,即random.choice(['iphone']*10 + ['ipad']*40 + ['itouch']*50).
下面,我們寫(xiě)成一個(gè)通用函數(shù).

#coding=utf-8 
import random 
def weighted_random(items): 
  total = sum(w for _,w in items) 
  n = random.uniform(0, total)#在餅圖扔骰子 
  for x, w in items:#遍歷找出骰子所在的區(qū)間 
    if n<w: 
      break 
    n -= w 
  return x 
 
print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)]) 

上面的代碼夠直觀,不過(guò)細(xì)心的會(huì)發(fā)現(xiàn),每次都會(huì)計(jì)算total,每次都會(huì)線(xiàn)性遍歷區(qū)間進(jìn)行減操作.其實(shí)我們可以先存起來(lái),查表就行了.利用accumulate+bisect二分查找.
物品越多,二分查找提升的性能越明顯.

#coding=utf-8 
class WeightRandom: 
  def __init__(self, items): 
    weights = [w for _,w in items] 
    self.goods = [x for x,_ in items] 
    self.total = sum(weights) 
    self.acc = list(self.accumulate(weights)) 
 
  def accumulate(self, weights):#累和.如accumulate([10,40,50])->[10,50,100] 
    cur = 0 
    for w in weights: 
      cur = cur+w 
      yield cur 
 
  def __call__(self): 
    return self.goods[bisect.bisect_right(self.acc , random.uniform(0, self.total))] 
 
wr = WeightRandom([('iphone', 10), ('ipad', 40), ('itouch', 50)]) 
print wr() 

相關(guān)文章

最新評(píng)論