我无法理解这个,哪个更随机?

rand()

OR:

rand() * rand()

我发现这是一个真正的脑筋急转弯,你能帮我吗?


编辑:

直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。


当前回答

强制性的xkcd。。。

其他回答

答案将是,这取决于,希望rand()*rand(()比rand)更随机,但如下所示:

两个答案都取决于你的值的位数在大多数情况下,你根据伪随机算法生成(它主要是一个数字生成器,依赖于你的计算机时钟,而不是那么随机)。让你的代码更可读(不要用这种咒语来召唤一些随机的巫毒神)。

好吧,如果你检查上面的任何一个,我建议你使用简单的“rand()”。因为你的代码会更可读(不会问自己为什么要写这个,时间……嗯……超过2秒),易于维护(如果你想用super_rand替换rand函数)。

如果你想要更好的随机性,我建议你从任何提供足够噪声的源(无线电静态)流式传输,然后一个简单的rand()就足够了。

我们可以通过使用Kolmogorov复杂性如果数字序列不能被压缩,那么它是我们在这个长度上可以达到的最随机的。。。我知道这种测量更多的是理论上的选择。。。

事实上,仔细想想rand()*rand(()比rand(。原因如下。

基本上,奇数和偶数的数量相同。假设0.04325是奇数,像0.388是偶数,0.4是偶数,0.15是奇数,

这意味着rand()有相等的机会成为偶数或奇数小数。

另一方面,rand()*rand(()的几率有点不同。让我们说:

double a = rand();
double b = rand();
double c = a * b;

a和b都有50%的几率是偶数或奇数。知道这一点

偶数*偶数=偶数偶数*奇数=偶数奇数*奇数=奇数奇数*偶数=偶数

这意味着c有75%的几率是偶数,而只有25%的几率是奇数,这使得rand()*rand(()的值比rand)更可预测,因此随机性更小。

公认的答案很好,但有另一种方法可以回答你的问题。PachydermPuncher的答案已经采用了这种替代方法,我只是将其扩展一点。

思考信息理论最简单的方法是用最小的信息单位,一个比特。

在C标准库中,rand()返回一个0到rand_MAX范围内的整数,根据平台的不同,这个限制可能会有不同的定义。假设RAND_MAX恰好被定义为2^n-1,其中n是某个整数(这恰好是Microsoft实现中的情况,其中n为15)。然后我们可以说,一个好的实现将返回n位信息。

想象一下,rand()通过翻转硬币找到一位的值来构造随机数,然后重复直到它有一批15位。然后,这些位是独立的(任何一个位的值都不会影响同一批中其他位具有特定值的可能性)。因此,独立考虑的每个比特都像一个介于0和1之间的随机数,并且在该范围内“均匀分布”(可能是0和1)。

位的独立性确保了由一批位表示的数字也将在其范围内均匀分布。这很明显:如果有15位,允许的范围是0到2^15-1=32767。该范围内的每个数字都是唯一的位模式,例如:

010110101110010

并且如果比特是独立的,则没有模式比任何其他模式更可能发生。因此,该范围内所有可能的数字都有相同的可能性。反之亦然:如果rand()产生均匀分布的整数,那么这些数字是由独立的位组成的。

因此,将rand()看作是一条生产比特的生产线,它恰好以任意大小的批量提供比特。如果您不喜欢大小,请将批分成单独的位,然后按您喜欢的数量将它们放回一起(尽管如果您需要的特定范围不是2的幂,则需要缩小数字,目前最简单的方法是转换为浮点)。

回到你最初的建议,假设你想从15个批次到30个批次,向rand()请求第一个数字,将其移位15位,然后向其添加另一个rand(()。这是一种在不影响均匀分布的情况下组合对rand(的两个调用的方法。它的工作原理很简单,因为放置信息位的位置之间没有重叠。

这与通过乘以常数来“拉伸”rand()的范围非常不同。例如,如果你想将rand()的范围加倍,你可以乘以2,但现在你只能得到偶数,而不能得到奇数!这并不完全是一个平稳的分布,并且可能是一个严重的问题,具体取决于应用程序,例如,假设允许奇数/偶数下注的轮盘游戏。(从位的角度考虑,你可以直观地避免这个错误,因为你会意识到,乘以2等于将位向左移动一位(意义更大),然后用零填补空白。所以很明显,信息量是一样的——只是移动了一点。)

在浮点数应用程序中,数字范围中的这种差距是无法解决的,因为浮点数范围内在地具有根本无法表示的差距:在每两个可表示的浮点数之间的差距中存在无限数量的缺失实数!所以无论如何,我们必须学会与差距共处。

正如其他人所警告的那样,直觉在这一领域是有风险的,特别是因为数学家无法抵抗实数的诱惑,因为实数是一种充满了粗糙的无限和明显的悖论的可怕的令人困惑的东西。

但至少如果你从比特角度来看,你的直觉可能会让你走得更远。比特真的很容易——甚至计算机都能理解。

好的,所以我会尝试添加一些值来补充其他答案,说你正在创建和使用一个随机数生成器。

随机数发生器是一种具有多种特性的设备(从非常普遍的意义上讲),可以根据需要进行修改。其中一些(来自我)是:

熵:如香农熵分布:统计分布(泊松、正态等)类型:数字的来源(算法、自然事件、组合等)和应用的算法。效率:执行的速度或复杂性。模式:周期、顺序、运行等。也许还有更多。。。

在这里的大多数答案中,分布是主要的关注点,但通过混合和匹配函数和参数,您可以创建生成随机数的新方法,这些随机数将具有不同的特征,其中一些特征乍一看可能不明显。