1、逢「幾」中獎html
逢「幾」中獎,即經過預估抽獎人數和獎品數來判斷,「幾」=(抽獎人數/獎品數)*N。這是一種最簡單抽獎算法,適合抽獎人數衆多,並且互相無聯繫的狀況。現在大爲流行的微博轉發得獎就經常使用這種算法,即根據轉發次數來決定獎品歸屬,透明並且具備激勵性。java
固然這個「幾」也不單隻次數,還多是時間,逢某個時間點就能夠抽中,不過這種方案可能產生無人中獎和不少人中獎的狀況,時間點的安排很關鍵!這個時間點一旦公佈出去,那就是秒殺,霍霍。。算法
逢「幾」中獎有不少弊端,可是很是簡單,很容易實現,被不少抽獎活動所採用,有些會公佈抽獎規則,激勵抽獎,有些則不會公佈,其實後臺運行的可能也是這個算法,簡單高效又不失公平。在信息不透明的狀況下,鬼知道你是第幾個抽獎的,哈哈。。數組
2、機率抽獎dom
所謂機率抽獎是最容易想到的抽獎算法了,這個機率能夠是一成不變的,也能夠是一直在變化調整的,最難的是採用多大的機率,何種狀況下采用何種機率。這個也沒有什麼通用的方案,不一樣的應用場景,所用的機率算法不一樣。下面介紹一種算法,根據獎品的過時日期來計算它當前時間的中獎率,當時間逐漸接近獎品過時時間時,中獎機率會逐漸發生變化,若是設爲1表示線性衰減,2爲平方衰減,以此類推。this
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; }
3、依賴不可控的物理隨機數 spa
什麼意思呢,先看個圖,看完你就知道了3d
明白了吧,呵呵,這就是現現在灰常流行的一種抽獎算法,絕對公平、絕對透明、絕對木有暗箱(除非偷偷給你換了抽獎號碼)!可是這種方法惟一的缺點是沒法實時抽獎,只能過後抽獎。也就是隻能拿個抽獎號等着上帝的眷顧,阿門。。。code
例如遊戲中戰勝一個boss,會掉落下面其中一個物品,而每一個物品都有必定機率: 1. 靴子 20% 2. 披風 25% 3. 飾品 10% 4. 雙手劍 5% 5. 金幣袋 40% 如今的問題就是如何根據機率掉落一個物品給玩家。htm
一. 通常算法:生成一個列表,分紅幾個區間,例如列表長度100,1-20是靴子的區間,21-45是披風的區間等,而後隨機從100取出一個數,看落在哪一個區間。算法時間複雜度:預處理O(MN),隨機數生成O(1),空間複雜度O(MN),其中N表明物品種類,M則由最低機率決定。
2、離散算法:也就是上面的改進,居然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
3、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)