国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python利用帶權重隨機數(shù)解決抽獎和游戲爆裝備問題

2019-11-25 16:43:33
字體:
來源:轉載
供稿:網(wǎng)友

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

2016616155350152.jpg (596×75)

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

上面的代碼夠直觀,不過細心的會發(fā)現(xiàn),每次都會計算total,每次都會線性遍歷區(qū)間進行減操作.其實我們可以先存起來,查表就行了.利用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() 

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 洱源县| 庐江县| 临洮县| 江孜县| 连平县| 上蔡县| 肃南| 吉林市| 高平市| 青河县| 门源| 兖州市| 荆门市| 方正县| 青海省| 利津县| 丽水市| 西城区| 玉林市| 安国市| 高陵县| 通道| 凤台县| 大方县| 革吉县| 平泉县| 金华市| 犍为县| 荆门市| 奉贤区| 双辽市| 广汉市| 安达市| 两当县| 蒙阴县| 永善县| 武功县| 安多县| 宾阳县| 内黄县| 界首市|