首頁  >  文章  >  後端開發  >  自己寫仿微信紅包的隨機分配,為什麼平均數差距這麼大?

自己寫仿微信紅包的隨機分配,為什麼平均數差距這麼大?

WBOY
WBOY原創
2016-08-04 09:20:451124瀏覽

這幾天比較閒,自己研究了一下微信紅包的演算法。用度娘查了一下,看到了一個官方的回答:「隨機,額度在0.01和(剩餘平均值2)之間。」也就是說,每個人拿紅包的時候,生成的金額都是即時計算,這樣可以減少記憶體的佔用,而每個紅包的額度是在0.01和(剩餘平均值2)之間,就是說,如果100塊5個紅包,第一個紅包的錢會在0.01到40之間,但玩過搶紅包的人都知道,這是不對的,第一個搶,拿超過剩餘平均值*2是很平常的事。
而我自己在沒看到這個回答之前,自己的設想是發紅包後就已經將金額分配好,然後等人來打開紅包。

<code>public function index($money,$count){
        if($count==1){
            echo $money;exit;
        }
        $max=$money*100;
        
        if($max<$count){
            echo '钱太少,人太多,不够分';exit;
        }
        
        $data=array();
        $arr=array();  
        if($count==2){
            $arr[]=mt_rand(1,$max-1);
        }else{
            $a=range(1,$max-1);
            shuffle($a);
            $arr= array_rand($a,$count-1);
        }
        for($i=0;$i<=$count-1;$i++){
            if($i==0){
                $data[$i]=$arr[$i];
            }elseif($i==$count-1){
                $data[$i]=$max-$arr[$i-1];
            }else{
                $data[$i]=$arr[$i]-$arr[$i-1];
            }
            $data[$i]=$data[$i]/100;
            //echo $data[$i].'<br/>';
        }
        return $data;
}</code>

我的想法是,紅包總金額金額就等於一條直線的長度,然後在直線上隨機放n-1個點,點與點之間的距離就等於每個紅包的金額。一開始,我以為,這樣會相對平均,然後我測試了100塊發10個紅包,測試了一萬次,結果發現

自己寫仿微信紅包的隨機分配,為什麼平均數差距這麼大?
而且這還是我打亂點與點長度排序後所得出來的結果,

自己寫仿微信紅包的隨機分配,為什麼平均數差距這麼大?
如果沒打亂之前的結果時這樣,相差更大。
很明顯可以看出,離平均,差很遠,是我的思路本來就是錯的嗎?

回覆內容:

這幾天比較閒,自己研究了一下微信紅包的演算法。用度娘查了一下,看到了一個官方的回答:「隨機,額度在0.01和(剩餘平均值2)之間。」也就是說,每個人拿紅包的時候,生成的金額都是即時計算,這樣可以減少記憶體的佔用,而每個紅包的額度是在0.01和(剩餘平均值2)之間,就是說,如果100塊5個紅包,第一個紅包的錢會在0.01到40之間,但玩過搶紅包的人都知道,這是不對的,第一個搶,拿超過剩餘平均值*2是很平常的事。
而我自己在沒看到這個回答之前,自己的設想是發紅包後就已經將金額分配好,然後等人來打開紅包。

<code>public function index($money,$count){
        if($count==1){
            echo $money;exit;
        }
        $max=$money*100;
        
        if($max<$count){
            echo '钱太少,人太多,不够分';exit;
        }
        
        $data=array();
        $arr=array();  
        if($count==2){
            $arr[]=mt_rand(1,$max-1);
        }else{
            $a=range(1,$max-1);
            shuffle($a);
            $arr= array_rand($a,$count-1);
        }
        for($i=0;$i<=$count-1;$i++){
            if($i==0){
                $data[$i]=$arr[$i];
            }elseif($i==$count-1){
                $data[$i]=$max-$arr[$i-1];
            }else{
                $data[$i]=$arr[$i]-$arr[$i-1];
            }
            $data[$i]=$data[$i]/100;
            //echo $data[$i].'<br/>';
        }
        return $data;
}</code>

我的想法是,紅包總金額金額就等於一條直線的長度,然後在直線上隨機放n-1個點,點與點之間的距離就等於每個紅包的金額。一開始,我以為,這樣會相對平均,然後我測試了100塊發10個紅包,測試了一萬次,結果發現

自己寫仿微信紅包的隨機分配,為什麼平均數差距這麼大?
而且這還是我打亂點與點長度排序後所得出來的結果,

自己寫仿微信紅包的隨機分配,為什麼平均數差距這麼大?
如果沒打亂之前的結果時這樣,相差更大。
很明顯可以看出,離平均,差很遠,是我的思路本來就是錯的嗎?

看看這裡的紅包演算法合你的要求不
https://github.com/qieangel2013/yaf

微信金額是拆的時候即時算出來的,採用的是純記憶體計算,不需要預算空間儲存。採取即時計算金額的考量:預算需要佔存儲,即時效率很高。

這個答案分析的不錯你可以看下http://coderroc.com/article/%E6%95%B0%E5%AD%A6%E5%92%8C%E7%AE%97%E6%B3%95 /%E5%BE%AE%E4%BF%A1%E7%BA%A2%E5%8C%85%E9%9A%8F%E6%9C%BA%E7%AE%97%E6%B3%95% E5%88%9D%E6%8E%A2.html

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn