用Python實現簡單的抽獎程序


抽獎基本需求

1、假設中獎概率為:獲得 a道具 10% b道具 20% c道具 30% d道具 40%
2、基本的想法是:生成1-100的連續數組,隨機生成一個整數,如果是1-10 則中a、10-30 中b、30-60中c、60-100中d

實現方法一:布爾判斷

1、第一種方法,直接判斷數據在哪個范圍,非常簡單

def choujiang0():
    #生成一個1-100的隨機整數
    x = np.random.randint(0,100,dtype='int')
    if x>=0 and x<10:
        return 'a'
    if x>=10 and x<30:
        return 'b'
    if x>=30 and x<60:
        return 'c'
    if x>=60:
        return 'd'

實現方法二:算法判斷

2、第二種方法:作為一個程序猿,不能滿足於這種太簡單的方法,不適合拓展嘛,所以想辦法做改造下,用一個算法來實現抽獎,主要有以下兩種方式:
2.1 把一個初始概率用字典來做配置,注意這里字典的鍵值是10、30、60、100,然后通過程序生成整數,判斷這個整數落在區間里的概率,對應字典得到獲得的獎勵,以下是choujiang1方法:

ratio = {10:'a',30:'b',60:'c',100:'d'}
def choujiang1():
    #生成一個1-100的隨機整數
    x = np.random.randint(1,101,dtype='int')
    #生成一個1-100的數組
    mother = [x for x in range(1,101,1)]
    #判斷x在數組的什么位置
    x_position = mother.index(x)
    pre_number = 0
    for key in ratio.keys():
        if x_position - pre_number>=0 and x_position-int(key)<0:
            return ratio[key]
        if pre_number == 0:
            pre_number=int(key)
    return -1

2.2 在第一點判斷整理落在哪個區間的方法,有兩種,第一種比較簡單,通過for循環遍歷字典,從數字0開始,如果滿足大於等於前區間小於后區間,則直接讀取字典值作為獎勵,方法沒問題,但次數多了這種遍歷效率不高;第二種使用二分法,相對復雜一點,但是算法效率高一些,需要額外寫一個二分法的遞歸方法search,來判斷隨機數值落在哪個區間,以下是search方法和choujiang2方法:

search方法:這個方法尤為重要,可以說是經典遞歸的基礎方法

#二分查詢方法
def search(seq,number,lower=0,upper=None):
    if upper==None:       
        upper = len(seq) - 1
        #print('now lower is ',lower,' upper is ',upper)
    if upper==lower:
        #print('now lower is ',lower,' upper is ',upper)
        return upper
    else:
        middle = (upper+lower)//2        
        if number>seq[middle]:
            #print('now lower is ',middle+1,' upper is ',upper)
            return search(seq,number,middle+1,upper)
        else:
            #print('now lower is ',lower,' upper is ',middle)
            return search(seq,number,lower,middle)

choujiang2方法:

#第二種抽獎方式
ratio = {10:'a',30:'b',60:'c',100:'d'}
list_ratio = []
for i in ratio.keys():
    list_ratio.append(i)
list_ratio = sorted(list_ratio)

def choujiang2():
    #生成一個1-100的隨機整數
    x = np.random.randint(1,101,dtype='int')
    i = search(list_ratio,x,lower=0)
    key = list_ratio[i]
    return ratio[key]

驗證和效率

1、如何驗證

驗證一下概率是否符合我們的期望,代碼如下:

def test_choujiang(func,*args,**kwargs):
    Counter = {'a':0,'b':0,'c':0,'d':0}
    n = 1000000
    for i in range(n):
        result = func(*args,**kwargs)
        for key in Counter.keys():
            if result==key:
                Counter[key] += 1
    print('a的概率是:{}'.format(Counter['a']/n))
    print('b的概率是:{}'.format(Counter['b']/n))
    print('c的概率是:{}'.format(Counter['c']/n))
    print('d的概率是:{}'.format(Counter['d']/n))

%time test_choujiang(choujiang0)

2、比較不同抽獎方法的效率

采用二分法的抽獎方法,相對來說靈活性好且效率最高。

%time test_choujiang(choujiang0)
%time test_choujiang(choujiang1)
%time test_choujiang(choujiang2)

#投100萬次的結果
輸出結果:
a的概率是:0.098874
b的概率是:0.199867
c的概率是:0.300063
d的概率是:0.401196
Wall time: 7.98 s
a的概率是:0.10022
b的概率是:0.199958
c的概率是:0.300433
d的概率是:0.399389
Wall time: 17 s
a的概率是:0.100109
b的概率是:0.200252
c的概率是:0.300102
d的概率是:0.399537
Wall time: 4.54 s

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM