php - 自己写仿微信红包的随机分配,为什么平均数差距这么大?
ringa_lee
ringa_lee 2017-04-11 09:17:25
[PHP讨论组]

这几天比较闲,自己研究了一下微信红包的算法。用度娘查了一下,看到了一个官方的回答:“随机,额度在0.01和(剩余平均值2)之间。”也就是说,每个人拿红包的时候,生成的金额都是即时计算,这样可以减少内存的占用,而每个红包的额度是在0.01和(剩余平均值2)之间,就是说,如果100块5个红包,第一个红包的钱会在0.01到40之间,但玩过抢红包的人都知道,这是不对的,第一个抢,拿超过剩余平均值*2是很平常的事。
而我自己在没看到这个回答之前,自己的设想是发红包后就已经将金额分配好,然后等人来打开红包。

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;
}

我的思路是,红包总金额金额就等于一条直线的长度,然后在直线上随机放n-1个点,点与点之间的距离就等于每个红包的金额。一开始,我以为,这样会相对平均,然后我测试了100块发10个红包,测试了一万次,结果发现


而且这还是我打乱点与点长度排序后所得出来的结果,


如果没打乱之前的结果时这样,相差更大。
明显可以看出,离平均,差好远,是我的思路本来就是错误的吗?

ringa_lee
ringa_lee

ringa_lee

全部回复(2)
黄舟

看看这里的红包算法合你的要求不
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

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号