一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python利用帶權重隨機數解決抽獎和游戲爆裝備問題

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

2020-08-27 12:24mattkang Python

帶權重隨機數即是隨機數各個區間段被抽中的概率根據權重而不同,這里我們就來看一下Python利用帶權重隨機數解決抽獎和游戲爆裝備問題的方法,首先還是來進一步解釋帶權隨機數:

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
#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:#遍歷找出骰子所在的區間
    if n<w:
      break
    n -= w
  return x
 
print weighted_random([('iphone', 10), ('ipad', 40), ('itouch', 50)])

上面的代碼夠直觀,不過細心的會發現,每次都會計算total,每次都會線性遍歷區間進行減操作.其實我們可以先存起來,查表就行了.利用accumulate+bisect二分查找.
物品越多,二分查找提升的性能越明顯.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#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()

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 狠狠撸在线影院 | 亚洲 欧美 成人 | 成人性生交大片免费看软件 | 国产福利一区二区精品视频 | 韩国漂亮美女三级在线观看 | 欧美在线一 | 精品亚洲视频在线观看 | 美女扒开粉嫩尿口漫画 | 精品国产区一区二区三区在线观看 | 四虎精品影视 | 成人网18免费网站 | 久久久久伊人 | 欧美一区二区日韩一区二区 | 天天色影视综合网 | 动漫人物差差差动漫人物免费观看 | 高清在线观看免费入口 | 丰满岳乱妇在线观看视频国产 | 亚洲成a人片777777久久 | 久久精品免视看国产 | yjzz视频| 四虎精品免费国产成人 | 暖暖视频高清图片免费完整版 | 亚洲欧洲网站 | xxxx18日本视频xxxxx | 青青热久麻豆精品视频在线观看 | 高跟翘臀老师后进式视频 | 俄罗斯女人与公拘i交酡 | 青草福利视频 | 玩高中女同桌肉色短丝袜脚文 | 亚洲精品无码不卡在线观看 | 日韩经典在线 | 国产日日干 | 亚洲 欧美 国产 日韩 字幕 | 精品国产成人 | 美女主播免费观看 | 久久亚洲精品成人 | 丝瓜茄子绿巨人秋葵榴莲污 | 日本又大又硬又粗的视频 | 国产伦精品一区二区 | 女人麻豆国产香蕉久久精品 | 日韩欧美综合在线二区三区 |