抽獎概率-三種算法


一、逢“幾”中獎

逢“幾”中獎,即通過預估抽獎人數和獎品數來判斷,“幾”=(抽獎人數/獎品數)*N。這是一種最簡單抽獎算法,適合抽獎人數眾多,而且互相無聯系的情況。如今大為流行的微博轉發得獎就常常使用這種算法,即根據轉發次數來決定獎品歸屬,透明而且具有激勵性。

當然這個“幾”也不單只次數,還可能是時間,逢某個時間點就可以抽中,不過這種方案可能產生無人中獎和很多人中獎的情況,時間點的安排很關鍵!這個時間點一旦公布出去,那就是秒殺,霍霍。。

逢“幾”中獎有很多弊端,但是非常簡單,很容易實現,被很多抽獎活動所采用,有些會公布抽獎規則,激勵抽獎,有些則不會公布,其實后台運行的可能也是這個算法,簡單高效又不失公平。在信息不透明的情況下,鬼知道你是第幾個抽獎的,哈哈。。

二、概率抽獎

所謂概率抽獎是最容易想到的抽獎算法了,這個概率可以是一成不變的,也可以是一直在變化調整的,最難的是采用多大的概率,何種情況下采用何種概率。這個也沒有什么通用的方案,不同的應用場景,所用的概率算法不同。下面介紹一種算法,根據獎品的過期日期來計算它當前時間的中獎率,當時間逐漸接近獎品過期時間時,中獎概率會逐漸發生變化,如果設為1表示線性衰減,2為平方衰減,以此類推。

importjava.util.Date;

importjava.util.Random;

 

publicclass LotteryTool {

 

private double factor;

private double probability;

private Random rand;

 

private LotteryTool(double probability, long expireTime, int reduce){

this.factor = (double) System.currentTimeMillis() / expireTime;

this.probability = probability * Math.pow(factor, reduce);

this.rand = new Random(System.currentTimeMillis());

}

 

public static LotteryTool getInstance(double probability, longexpireTime,

int reduce) {

return new LotteryTool(probability, expireTime, reduce);

}

 

public boolean isLucky(long expected) {

long token = generateLong();

expected = expected % (int) (1 / probability);

if (expected == token) {

return true;

}

return false;

}

 

三、依賴不可控的物理隨機數 

什么意思呢,先看個圖,看完你就知道了

 

 

 

明白了吧,呵呵,這就是現如今灰常流行的一種抽獎算法,絕對公平、絕對透明、絕對木有暗箱(除非偷偷給你換了抽獎號碼)!但是這種方法唯一的缺點是無法實時抽獎,只能事后抽獎。也就是只能拿個抽獎號等着上帝的眷顧,阿門。。。

 

 

例如游戲中打敗一個boss,會掉落下面其中一個物品,而每個物品都有一定概率: 1. 靴子 20% 2. 披風 25% 3. 飾品 10% 4. 雙手劍 5% 5. 金幣袋 40% 現在的問題就是如何根據概率掉落一個物品給玩家。

一. 一般算法:生成一個列表,分成幾個區間,例如列表長度100,1-20是靴子的區間,21-45是披風的區間等,然后隨機從100取出一個數,看落在哪個區間。算法時間復雜度:預處理O(MN),隨機數生成O(1),空間復雜度O(MN),其中N代表物品種類,M則由最低概率決定。

二、離散算法:也就是上面的改進,竟然1-20都是靴子,21-45都是披風,那抽象成小於等於20的是靴子,大於20且小於等於45是披風,就變成幾個點[20,45,55,60,100],然后也是從1到99隨機取一個數R,按順序在這些點進行比較,知道找到第一個比R大的數的下標,比一般算法減少占用空間,還可以采用二分法找出R,這樣,預處理O(N),隨機數生成O(logN),空間復雜度O(N)。 請點擊查看詳細:http://www.cnblogs.com/miloyip/archive/2010/04/21/1717109.html

三、Alias Method Alias Method就不太好理解,實現很巧妙,推薦先看看這篇文章:http://www.keithschwarz.com/darts-dice-coins/ 大致意思:把N種可能性拼裝成一個方形(整體),分成N列,每列高度為1且最多兩種可能性,可能性抽象為某種顏色,即每列最多有兩種顏色,且第n列中必有第n種可能性,這里將第n種可能性稱為原色。 想象拋出一個硬幣,會落在其中一列,並且是落在列上的一種顏色。這樣就得到兩個數組:一個記錄落在原色的概率是多少,記為Prob數組,另一個記錄列上非原色的顏色名稱,記為Alias數組,若該列只有原色則記為null。

之前的例子,為了便於演示換成分數 1. 靴子 20% -> 1/4 2. 披風 25% -> 1/5 3. 飾品 10% -> 1/10 4. 雙手劍 5% -> 1/20 5. 金幣袋 40% -> 2/5 然后每個都乘以5(使每列高度為1),再拼湊成方形 拼湊原則:每次都從大於等於1的方塊分出一小塊,與小於1的方塊合成高度為1

由上圖方形可得到兩個數組: Prob: [3/4, 1/4, 1/2, 1/4, 1] Alias: [4, 4, 0, 1, null] (記錄非原色的下標)

之后就根據Prob和Alias獲取其中一個物品 隨機產生一列C,再隨機產生一個數R,通過與Prob[C]比較,R較大則返回C,反之返回Alias[C]。

Alias Method 復雜度:預處理O(NlogN),隨機數生成O(1),空間復雜度O(2N)

 

 


免責聲明!

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



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