关于知乎上 “房间内有 100 人,每人有 100 块,每分钟随机给另一个人 1 块,最后这个房间内的财富分布怎样?” 的实现

关于知乎上 房间内有 100 人,每人有 100 块,每分钟随机给另一个人 1 块,最后这个房间内的财富分布怎样?,我理解为:

每分钟每一个人给随机的另外一个1块,如果没钱则无需交给别人。


兴趣来了便用代码实现,代码实现如下:

header("Content-type: text/html; charset=utf-8");
$people = []; 
for($i=1;$i<=100;$i++){
    $people[$i] = 100;
}
$day = 365*10;  //$day天后的执行结果
$end_time = $day*24*60;
for($start=0;$start<$end_time;$start+=60){

    foreach($people as $k=>$v){
        if($v>0){
            $people[$k] --;         
            $id = rand(1,100);  
            $people[$id] ++;    
        }
    }   
}

$a = $b = $c = 0;
$a_name = $b_name = $c_name = '';
foreach($people as $k=>$v){
    if($v>100){
        $a ++;
        $a_name .= $k.',';
    }elseif($v == 100){
        $b ++;
        $b_name .= $k.',';
    }else{
        $c ++;
        $c_name .= $k.',';
    }
}

echo '大于100的人数:'.$a.'人,是['.$a_name.']';
echo "<br/>";
echo '等于于100的人数:'.$b.'人,是['.$b_name.']';
echo "<br/>";
echo '小于100的人数:'.$c.'人,是['.$c_name.']';
echo "<br/>";

执行结果为:

大于100的人数:68人,是[1,2,3,5,6,8,9,11,12,14,15,17,18,20,21,23,24,26,27,28,30,31,33,34,36,37,39,40,42,43,45,46,48,49,51,52,53,55,56,58,59,61,62,64,65,67,68,70,71,73,74,76,77,78,80,81,83,84,86,87,89,90,92,93,95,96,98,99,]
等于于100的人数:0人,是[]
小于100的人数:32人,是[4,7,10,13,16,19,22,25,29,32,35,38,41,44,47,50,54,57,60,63,66,69,72,75,79,82,85,88,91,94,97,100,]

经过测试发现大于5年以后数据每次都是以上结果。不知道这是为啥?

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 26

这里的rand本质上算是伪随机吧。。 不知道用/dev/urandom会不会不一样

6年前 评论

都是随机了 还能有什么财富分布 搞不懂知乎的脑回路

6年前 评论

大于100的人数:40人,是[1,2,4,6,9,10,11,13,14,16,19,20,23,24,28,30,33,37,38,40,41,45,48,49,53,54,55,58,61,65,68,69,74,81,84,88,92,93,98,100,]等于于100的人数:0人,是[]小于100的人数:60人,是[3,5,7,8,12,15,17,18,21,22,25,26,27,29,31,32,34,35,36,39,42,43,44,46,47,50,51,52,56,57,59,60,62,63,64,66,67,70,71,72,73,75,76,77,78,79,80,82,83,85,86,87,89,90,91,94,95,96,97,99,]

我这里每次都不一样

6年前 评论

@我不饿 这个我还真不知道。。。没看过rand是怎么实现的

6年前 评论

@Rekkles 我感觉这是随机,一时兴起就执行了一下,但是在我本地每次结果都一样,让我十分惊讶

6年前 评论

@我不饿
你是使用我以上代码吗?我每次刷新页面,答案不改变!每次都是如下,刚刚执行了一遍:anguished:

file

6年前 评论

@tradzero 这个我还真不知道。。。没看过rand是怎么实现的:anguished:

6年前 评论

@悲剧不上演 我是复制的你的代码 我在shell下执行的,你输出的页面应该有缓存

6年前 评论

@tradzero rand是随机函数,每次是不一样的,扯什么伪随机

6年前 评论

@我不饿 清除浏览器缓存后执行一次,仍然是以上结果:anguished:
用cli模式执行结果依旧如此,只是有些乱码.

file

6年前 评论

@悲剧不上演 你再看看吧 这个题结果确实是随机的,我执行你的代码结果也确实是不一样的,你那边每次一样的问题 应该不是代码的问题

6年前 评论
大于100的人数:35人,是[6,7,8,13,16,19,20,32,33,34,39,45,46,49,51,54,56,58,59,60,61,63,64,66,70,71,75,76,80,81,82,91,94,98,99,]
等于于100的人数:0人,是[]
小于100的人数:65人,是[1,2,3,4,5,9,10,11,12,14,15,17,18,21,22,23,24,25,26,27,28,29,30,31,35,36,37,38,40,41,42,43,44,47,48,50,52,53,55,57,62,65,67,68,69,72,73,74,77,78,79,83,84,85,86,87,88,89,90,92,93,95,96,97,100,]
大于100的人数:37人,是[1,2,4,5,7,13,14,20,25,27,28,33,34,37,38,39,41,42,44,50,51,52,64,73,74,75,83,84,85,86,87,88,93,96,98,99,100,]
等于于100的人数:0人,是[]
小于100的人数:63人,是[3,6,8,9,10,11,12,15,16,17,18,19,21,22,23,24,26,29,30,31,32,35,36,40,43,45,46,47,48,49,53,54,55,56,57,58,59,60,61,62,63,65,66,67,68,69,70,71,72,76,77,78,79,80,81,82,89,90,91,92,94,95,97,]

每次结果都不一样

6年前 评论

@wangchao 可能是我本地的原因吧,不知道为何每次刷新都是一个结果~:cold_sweat:

6年前 评论
LOST

执行的结果应该是不一样的, 很好奇楼主一样的结果是啥原因.

6年前 评论

@LOST 暂时还没发现原因,咱们是同一套代码,你是在哪里运行的?

6年前 评论
LOST

@悲剧不上演 我的是本地wnmp环境, 跑了几次, 相邻两次的结果基本上都不一样.

6年前 评论

@LOST请问一下,是和我上面的代码一致吗?我在朋友那本地也是xampp运行也是相同的结果~

6年前 评论

这个是用C#的System.Random类生成的随机数填充的位图。

这个是用php的rand函数生成的随机数填充的位图

所以,php还是用random 函数吧,别用rand了

PHP7 直接支持
PHP5 看这里 https://github.com/paragonie/random_compat...

6年前 评论

大于100的人数:68人,是[1,2,3,5,6,8,9,11,12,14,15,17,18,20,21,23,24,26,27,28,30,31,33,34,36,37,39,40,42,43,45,46,48,49,51,52,53,55,56,58,59,61,62,64,65,67,68,70,71,73,74,76,77,78,80,81,83,84,86,87,89,90,92,93,95,96,98,99,]
等于于100的人数:0人,是[]
小于100的人数:32人,是[4,7,10,13,16,19,22,25,29,32,35,38,41,44,47,50,54,57,60,63,66,69,72,75,79,82,85,88,91,94,97,100,]

一模一样!!!!

6年前 评论
LOST

@悲剧不上演 完全copy你的代码

6年前 评论

在C语言中,rand()函数可以用来产生随机数,但是这不是真正意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态分布,从而相当于产生了随机数,但这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统,为了改变这个种子的值,C提供了srand()函数,它的原形是void srand( int a)。初始化随机产生器即rand()函数的初始值,即使把种子的值改成a; 从这你可以看到通过srand()函数,我们是可以产生可以预见的随机序列----------------摘自百度百科

6年前 评论

@L伟 楼上有人怼我 " rand是随机函数,每次是不一样的,扯什么伪随机" hhhh

6年前 评论

你这个rand有错误啊 你有可能自己给自己发钱啊 应该吧自己排除掉好吧= =

6年前 评论

@就好比 对,你说的对。确实当时没考虑到这点

6年前 评论

@L伟 我以为就我一个是没有随机的,:smile:
你说的对着呢。确实这次使我对rand()这个方法了解颇多

6年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!