一個經典機率算法(用於抽獎等場景)

假設有一個數組[100,400,200,300],它的意思是,總數是100+400+200+300=1000. 取到第一個數的機率是100/1000,取到第二個數的機率是400/1000......代碼以下:算法

            function getResult(arr){
                var leng = 0;
                for(var i=0; i<arr.length; i++){
                    leng+=arr[i]                                     //獲取總數
                }
                for(var i=0; i<arr.length; i++){
                    var random = parseInt(Math.random()*leng);       //獲取 0-總數 之間的一個隨隨機整數 if(random<arr[i]){
                        return i                                     //若是在當前的機率範圍內,獲得的就是當前機率
                    }
                    else {
                        leng-=arr[i]                                 //不然減去當前的機率範圍,進入下一輪循環
                    }
                }
            }    

下面來解釋一下這個算法,把數組抽象出來,假設爲a,b,c,d,這四個機率數,那麼,他們的總和就是 a+b+c+d. 畫成數軸:數組

從0-(a+b+c+d) 中取一個隨機數,數字落在對應的空間裏,取到的就是對應的機率.dom

第一次循環取數,有兩個可能: 函數

<a    或者    >a: spa

若是是第一種可能,那就直接是機率a/(a+b+c+d),獲得的對應結果就是a.直接返回.code

若是是第二種可能,那麼機率應該是(b+c+d)/(a+b+c+d).而後進入第二次循環,第二次取數咱們把a的機率空間減去,獲得新的數軸:blog

新的數軸以原來的a爲原點0,後面不變.這時候,總和變成 b+c+d.get

從 0-(b+c+d) 中取一個隨機數,數字落在對應的空間裏,取到的就是對應的機率.io

一樣有兩個可能: console

<b    或者     >b

若是是第一種,那麼它的機率就是 b/(b+c+d). 注意,這個機率出現的前提是第一次的結果是 >a ,因此總機率就是兩次乘積: (b+c+d)/(a+b+c+d) * b/(b+c+d) 獲得的結果是 b/(a+b+c+d),獲得的對應結果就是b.返回.

若是是第二種,那麼它的機率就是 (c+d)/(b+c+d). 一樣,和 >a 的結果同時出現,這種狀況的總機率應該是: (b+c+d)/(a+b+c+d) * (c+d)/(b+c+d) 獲得的結果是(c+d)/(a+b+c+d).而後進入第三次循環,而後第三次循環時,咱們再把b的機率空間減去............以此類推.............

這樣直到最後...總能取到一個機率值...

 

這個算法能夠用在抽獎上,好比有這樣一組獎品和對應的機率:

 

       var gifts = [
                {
                    "name":"mac",
                    "prop":1
                },
                {
                    "name":"紅米",
                    "prop":10
                },
                {
                    "name":"u盤",
                    "prop":40
                },
                {
                    "name":"香皂",
                    "prop":49
                }
            ];

 

就能夠用前面的函數來進行抽獎:

            var gArr = [];
            for(var i=0; i<gifts.length; i++){
                gArr.push(gifts[i]['prop'])
            }
            console.log(gifts[getResult(gArr)]['name'])    

源文件下載:http://pan.baidu.com/s/1oeOG2

非轉載,親測可行~~~

相關文章
相關標籤/搜索