我不能让我的头在这里,哪个更随机?
rand()
或:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学答案是它们同样随机,但我不禁想到,如果你“运行随机数算法”两次,当你将两者相乘时,你会创造出比一次更随机的东西。
“随机”和“更随机”有点像问哪个零更零。
在这种情况下,rand是一个PRNG,所以不是完全随机的。(事实上,如果种子已知,则相当可预测)。将其乘以另一个值使其或多或少没有随机。
rand
真正的加密类型RNG实际上是随机的。通过任何类型的函数运行值都不能为其添加更多的熵,并且很可能会消除熵,使其不再随机。
也不是“更随机”。
rand()基于伪随机种子生成一组可预测的数字(通常基于当前时间,时间总是在变化)。将序列中的两个连续数字相乘会生成不同但同样可预测的数字序列。
解决这是否会减少碰撞,答案是否定的。由于将两个数字相乘的效果,它实际上会增加碰撞0 < n < 1。结果将是一个较小的分数,导致结果偏向光谱的低端。
0 < n < 1
一些进一步的解释。在下面,不可预测和随机指的是某人根据以前的数字猜测下一个数字的能力,即。一个预言。
给定种子x,它生成以下值列表:
x
0.3, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.3, ...
rand()将生成上述列表,rand() * rand()将生成:
0.18, 0.08, 0.08, 0.21, ...
这两种方法总是会为同一个种子生成相同的数字列表,因此预言机同样可以预测。但是如果你查看将两个调用相乘的结果,你会发现它们都在0.3以下,尽管原始序列中的分布不错。由于将两个分数相乘的影响,数字是有偏差的。结果数字总是更小,因此更有可能发生碰撞,尽管仍然同样不可预测。
0.3
虽然前面的答案是正确的,当你试图发现一个伪随机变量或其乘法的随机性时,你应该意识到,虽然随机()通常是均匀分布的,但Random()*Random()不是。
这是通过伪随机变量模拟的均匀随机分布样本:
BarChart[BinCounts[RandomReal[{0, 1}, 50000], 0.01]]
虽然这是您将两个随机变量相乘后得到的分布:
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] *RandomReal[{0, 1}, 50000], {50000}], 0.01]]
所以,两者都是“随机”的,但它们的分布非常不同。
2*随机()是均匀分布的:
BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]
Random()+Random()不是!
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] +RandomReal[{0, 1}, 50000], {50000}], 0.01]]
中心极限定理说明Random()的总和趋向于正态分布随着项的增加。
只有四个条件,你会得到:
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000] +Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000],{50000}],0.01]]
在这里,你可以通过将1、2、4、6、10和20个均匀分布的随机变量相加,看到从均匀分布到正态分布的道路:
编辑
一些学分
感谢Thomas Ahle在评论中指出最后两张图片中显示的概率分布被称为欧文霍尔分布
感谢海克的精彩撕裂[]函数
关于“随机性”的一些事情是反直觉的。
假设平坦分布为rand(),下面将得到非平坦分布:
sqrt(rand(range^2))
(rand(range) + rand(range))/2
range - sqrt(rand(range^2))
还有很多其他方法可以创建特定的偏差曲线。我对rand() * rand()做了一个快速测试,它得到了一个非常非线性的分布。
大多数rand()实现都有一定的周期。即在大量调用后,序列重复。rand() * rand()的输出序列在一半的时间内重复,因此在这个意义上它“不那么随机”。
此外,如果没有仔细的构造,对随机值执行算术往往会导致更少的随机性。上面的一张海报引用了“rand()+rand()+rand()…”(比如k次),这实际上往往是rand()返回值范围平均值的k倍。(这是一个随机游走,步骤与平均值对称。)
具体假设你的rand()函数返回一个均匀分布的随机实数,范围在[0,1)。(是的,这个例子允许无限精度。这不会改变结果。)你没有选择一种特定的语言,不同的语言可能会做不同的事情,但以下分析适用于rand()的任何非反常实现。乘积rand() * rand()也在[0,1)范围内,但不再均匀分布。事实上,乘积在区间[0,1/4)和区间[1/4,1)中的可能性一样大。更多的乘法将使结果进一步向零倾斜。这使结果更可预测。在广义上,更可预测==更少的随机。
几乎任何对均匀随机输入的操作序列都是非均匀随机的,从而提高了可预测性。小心点,人们可以克服这个特性,但这样就更容易在你实际想要的范围内生成一个均匀分布的随机数,而不是浪费时间进行算术运算。
一般来说,浮动随机数基于一种算法,该算法产生一个介于零和一定范围之间的整数。因此,通过使用rand()*rand(),您本质上是在说int_rand()*int_rand()/rand_max^2-这意味着您不包括任何素数/rand_max^2。
这大大改变了随机分布。
rand()在大多数系统上是均匀分布的,如果种子正确,很难预测。除非你有特殊的理由对其进行数学运算(即,将分布塑造成所需的曲线),否则请使用它。
答案是视情况而定,希望rand()*rand()比rand()更随机,但是:
好吧,如果你检查上面的任何一个,我建议你选择简单的“rand()”。因为你的代码会更可读(不会问自己为什么要写这个,……嗯……超过2秒),易于维护(如果你想用super_rand替换你的rand函数)。
如果你想要一个更好的随机,我建议你从任何提供足够噪音的来源流式传输它(无线电静电),然后一个简单的rand()应该就足够了。
当对随机数的组合会发生什么有疑问时,您可以使用您在统计理论中学到的课程。
在OP的情况下,他想知道X*X=X^2的结果是什么,其中X是沿均匀[0,1]分布的随机变量。我们将使用CDF技术,因为它只是一个一对一的映射。
由于X~Uniform[0,1]它的cdf是:fX(x)=1我们希望变换Y<-X^2因此y=x^2求x(y)的逆:sqrt(y)=x这给出了x作为y的函数。接下来,找到导数dx/dy:d/dy(sqrt(y))=1/(2 sqrt(y))
Y的分布为:fY(y)=fX(x(y))|dx/dy|=1/(2 sqrt(y))
我们还没有完成,我们必须得到Y的域。因为0<=x<1,0<=x^2<1所以Y在范围[0,1)内。如果你想检查Y的pdf是否确实是pdf,请在域:从0到1积分1/(2 sqrt(y))上集成它,实际上,它会弹出为1。此外,请注意所述函数的形状看起来像发表的那样。
至于X1+X2+…+Xn(其中X我~均匀[0,1]),我们可以求助于中心极限定理,该定理适用于任何矩存在的分布。这就是Z检验实际存在的原因。
用于确定结果pdf的其他技术包括Jacobian变换(这是cdf技术的广义版本)和MGF技术。
编辑:作为澄清,请注意,我说的是结果转换的分布,而不是它的随机性。这实际上是为了单独讨论。此外,我实际派生的是(rand())^2。对于rand()*rand(),它要复杂得多,无论如何,它不会导致任何形式的均匀分布。
这里有一个简单的答案。以大富翁为例。你掷两个六面骰子(对于喜欢博彩符号的人来说,或者2d6),然后取它们的总和。最常见的结果是7,因为有6种可能的方式可以掷出7(1,6,2,5,3,4,3,5,2和6,1)。而2只能在1,1上滚动。很容易看出,滚动2d6与滚动1d12不同,即使范围相同(忽略你可以在1d12上得到1,点保持不变)。将结果相乘而不是相加会以类似的方式扭曲它们,大多数结果都在范围的中间。如果你想减少异常值,这是一个很好的方法,但它无助于实现均匀分布。
(奇怪的是,它也会增加低滚动。假设你的随机性从0开始,你会看到一个峰值在0,因为它会把另一个滚动变成0。考虑0和1(包括)之间的两个随机数并相乘。如果任何一个结果是0,无论另一个结果如何,整个结果都变成了0。从它中得到1的唯一方法是两个滚动都是1。在实践中,这可能无关紧要,但它会产生一个奇怪的图形。)
大多数这些分布的发生是因为您必须限制或归一化随机数。
我们将其归一化为全正值,在一个范围内拟合,甚至在分配的变量类型的内存大小的约束内拟合。
换句话说,因为我们必须限制0和X之间的随机调用(X是我们变量的大小限制),所以我们将在0和X之间有一组“随机”数字。
现在,当您将随机数添加到另一个随机数时,总和将介于0到2X之间……这会使值偏离边缘点(当您在较大范围内有两个随机数时,将两个小数字相加和两个大数字相加的概率非常小)。
想象一下这样的情况,你有一个接近零的数字,你用另一个随机数加上它,它肯定会变大,远离0(这将是真正的大数,以及它不太可能有两个大数(接近X的数字)由随机函数返回两次。
现在,如果您要设置具有负数和正数(在零轴上相等地跨越)的随机方法,则不再是这种情况。
比如说RandomReal({-x, x}, 50000, .01),那么你会得到一个数字在负数和正数上的偶数分布,如果你把随机数加在一起,它们会保持它们的“随机性”。
RandomReal({-x, x}, 50000, .01)
现在我不确定Random() * Random()会发生什么,负到正的跨度……这将是一个有趣的图表……但我现在必须回去编写代码。:-P
Random() * Random()
您正在寻找的概念是“熵”,字符串的无序“程度”这个想法是最容易理解的“最大熵”的概念。
具有最大熵的比特串的近似定义是,它不能精确地用较短的比特串表示(即,使用一些算法来将较小的字符串展开回原始字符串)。
最大熵与随机性的相关性源于这样一个事实如果你“随机”选择一个数字,你几乎肯定会选择一个数字其位串接近最大熵,即不能压缩。这是我们对“随机数”特征的最佳理解。
因此,如果您想从两个随机样本中生成一个随机数,其“两倍”为随机,你会连接两个位字符串在一起。实际上,你只是将样本填充到双长度单词的高半部和低半部中。
更实际的是,如果你发现自己背负着一个蹩脚的rand(),它可以有时会帮助将几个样本异或在一起——尽管,如果它真的收支平衡这个过程没有用
用更离散的数字来考虑这一点可能会有所帮助。考虑想要生成1到36之间的随机数,所以你决定最简单的方法是扔两个公平的6面骰子。你得到这个:
1 2 3 4 5 6-----------------------------1| 1 2 3 4 5 62| 2 4 6 8 10 123| 3 6 9 12 15 184| 4 8 12 16 20 245| 5 10 15 20 25 306| 6 12 18 24 30 36
所以我们有36个数字,但并不是所有的数字都得到了公平的代表,有些数字根本没有出现。靠近中心对角线(左下角到右上角)的数字出现频率最高。
描述骰子之间不公平分布的相同原则同样适用于0.0到1.0之间的浮点数。
我想这两种方法都是随机的,尽管我的直觉会说rand() * rand()不那么随机,因为它会产生更多的零。一旦一个rand()是0,总数就变成了0
0
必须的xkcd…
正如其他人所说,简单的简短答案是:不,它不是更随机,但它确实改变了分布。
假设你在玩一个骰子游戏,你有一些完全公平、随机的骰子。如果在每次掷骰子之前,你先把两个骰子放在一个碗里,摇来摇去,随机选择其中一个骰子,然后再掷那个骰子,那么骰子会“更随机”吗?显然,这不会有什么区别。如果两个骰子都给出随机数,那么随机选择两个骰子中的一个将没有任何区别。无论哪种方式,你都会得到一个在1到6之间的随机数,在足够数量的骰子上呈偶数分布。
我想在现实生活中,如果你怀疑骰子可能不公平,这样的过程可能会有用。例如,如果骰子稍微不平衡,所以一个骰子倾向于给出1的频率超过1/6的时间,而另一个骰子倾向于异常频繁地给出6,那么在两者之间随机选择往往会掩盖偏差。(尽管在这种情况下,1和6仍然会比2、3、4和5更多。嗯,我想这取决于不平衡的性质。)
随机性有很多定义。随机序列的一个定义是,它是由随机过程产生的一系列数字。根据这个定义,如果我滚动一个公平的骰子5次,得到数字2,4,3,2,5,那就是一个随机序列。如果我再滚动同一个公平骰子5次,得到1,1,1,1,1,1,那么这也是一个随机序列。
一些发帖者指出,计算机上的随机函数不是真正的随机,而是伪随机,如果你知道算法和种子,它们是完全可预测的。这是真的,但大多数时候完全无关紧要。如果我洗牌一副牌,然后一次翻过一张,这应该是一个随机系列。如果有人偷看牌,结果将是完全可预测的,但根据大多数随机性的定义,这并不会降低它的随机性。如果系列通过了随机性的统计测试,我偷看牌的事实不会改变这一事实。在实践中,如果我们赌一大笔钱在你猜下一张牌的能力上,那么你偷看牌的事实是高度相关的。如果我们使用该系列来模拟网站访问者的菜单选择以测试系统的性能,那么你偷看的事实将没有任何区别。(只要你不修改程序以利用这些知识。)
我不认为我可以把我对蒙蒂霍尔问题的回应变成评论,所以我会更新我的答案。
对于那些没有读过贝利萨留斯链接的人来说,它的要点是:一个游戏节目参赛者被给予3扇门的选择。在一扇门后面是一个有价值的奖品,在其他门后面是一些毫无价值的东西。他选择了第一扇门。在揭示它是赢家还是输家之前,主持人打开了第三扇门,揭示它是一个输家。然后他给了参赛者切换到第二扇门的机会。参赛者应该这样做吗?
答案是他应该换一下,这违背了很多人的直觉。他原来的选择是赢家的概率是1/3,另一扇门是赢家的概率是2/3。我和其他许多人的最初直觉是,换一下不会有任何好处,赔率刚刚变成了50:50。
毕竟,假设有人在主持人打开失败的门后打开电视。那个人会看到剩下的两扇关闭的门。假设他知道游戏的性质,他会说每扇门都有1/2的机会隐藏奖品。观众的赔率怎么会是1/2:1/2,参赛者的赔率怎么会是1/3:2/3?
我真的不得不考虑这个问题来塑造我的直觉。为了掌握它,要明白,当我们在这样的问题中谈论概率时,我们的意思是,给定可用信息的概率。对于把奖品放在第一扇门后面的船员来说,奖品在第一扇门后面的概率是100%,它在其他两扇门后面的概率是零。
船员的赔率与参赛者的赔率不同,因为他知道参赛者不知道的事情,即他把奖品放在了哪扇门后面。同样,参赛者的赔率与观众的赔率不同,因为他知道观众不知道的事情,即他最初选择了哪扇门。这不是无关紧要的,因为主持人选择打开哪扇门不是随机的。他不会打开参赛者选择的门,他也不会打开隐藏奖品的门。如果这是同一扇门,他有两个选择。如果它们是不同的门,那就只剩下一个了。
那么,我们如何得出1/3和2/3的结果呢?当参赛者最初选择一扇门时,他有1/3的机会选择赢家。我认为这很明显。这意味着有2/3的机会,其他门中的一扇是赢家。如果主持人在没有提供任何额外信息的情况下让他有机会切换,则不会有任何收益。同样,这应该是显而易见的。但一种看法是说,他有2/3的机会通过切换获胜。但他有两个选择。所以每个人只有2/3除以2=1/3的机会成为赢家,这并不比他原来的选择更好。当然我们已经知道最终的结果,这只是计算它的不同方式。
但是现在主持人发现这两个选项中的一个不是赢家。因此,在他没有选择的门的2/3的可能性中,他现在知道两个选项中的一个不是赢家。另一个可能是,也可能不是。所以他不再有2/3除以2。他有零为打开的门,2/3为关闭的门。
假设你有一个简单的硬币翻转问题,其中偶数被认为是正面,奇数被认为是反面。逻辑实现是:
rand() mod 2
在一个足够大的分布上,偶数的数量应该等于奇数的数量。
现在考虑一个轻微的调整:
rand() * rand() mod 2
如果其中一个结果是偶数,那么整个结果应该是偶数。考虑4种可能的结果(偶数*偶数=偶数,偶数*奇数=偶数,奇数*偶数=偶数,奇数*奇数=奇数)。现在,在足够大的分布上,75%的情况下答案应该是偶数。
如果我是你,我就赌人头。
这篇评论实际上更多的是解释为什么你不应该基于你的方法实现自定义随机函数,而不是讨论随机性的数学属性。
乘以数字最终会在一个较小的解决方案范围内,具体取决于您的计算机架构。
如果您的计算机显示16位数字rand(),则表示为01234567890123乘以第二个rand(),0.1234567890123,将得到0.0152415如果你重复这个实验10^14次,你肯定会找到更少的答案。
这不是很明显,但rand()通常比rand()*rand()更随机。重要的是,这对大多数用途来说实际上并不重要。
rand()*rand()
但首先,它们产生不同的分布。这不是个问题如果这是你想要的,但它确实很重要。如果你需要一个特定的分布,那么忽略整个“哪个更随机”的问题。那么为什么rand()更随机呢?
为什么rand()更随机(假设它产生的范围是[0…1]的浮点随机数,这很常见)的核心是,当您将两个FP数与尾数中的大量信息相乘时,您会从尾数中获得一些信息丢失;IEEE双精度浮点数中没有足够的位来容纳从[0…1]中均匀随机选择的两个IEEE双精度浮点数中的所有信息,并且这些额外的信息位会丢失。当然,这并不重要,因为您(可能)不会使用该信息,但损失是真实的。你产生哪个分布(即,你使用哪个操作进行组合)也并不重要。这些随机数中的每一个都有(最多)52位的随机信息——这是IEEE双精度可以容纳的数量——如果你将两个或多个合并成一个,你仍然被限制最多有52位的随机信息。
随机数的大多数用途甚至没有使用随机源中实际可用的那么多随机性。得到一个好的PRNG,不要太担心它。(“好”的程度取决于你用它做什么;在进行蒙特卡洛模拟或密码学时你必须小心,但除此之外,你可能可以使用标准PRNG,因为这通常要快得多。)
接受的答案非常可爱,但是还有另一种方法来回答你的问题。PachydermPuncher的回答已经采用了这种替代方法,我只是将它扩展一点。
考虑信息论的最简单方法是考虑最小的信息单位,即单个比特。
在C标准库中,rand()返回一个0到RAND_MAX范围内的整数,这个限制可能会根据平台的不同而有不同的定义。假设RAND_MAX恰好被定义为2^n - 1,其中n是某个整数(这恰好是微软的实现中的情况,其中n是15)。那么我们会说一个好的实现会返回n位信息。
RAND_MAX
2^n - 1
n
想象一下,rand()通过翻转硬币来构造随机数,找到一位的值,然后重复直到它有一批15位。然后位是独立的(任何一位的值不会影响同一批中其他位具有特定值的可能性)。因此独立考虑的每个位就像0和1之间的随机数,并且在该范围内“均匀分布”(尽可能0和1)。
位的独立性确保了批次位表示的数字也将均匀分布在它们的范围内。这在直觉上是显而易见的:如果有15位,允许的范围是零到2^15 - 1=32767。该范围内的每个数字都是唯一的位模式,例如:
2^15 - 1
010110101110010
如果位是独立的,那么没有任何模式比任何其他模式更有可能发生。所以范围内所有可能的数字都有同样的可能性。所以反之亦然:如果rand()产生均匀分布的整数,那么这些数字是由独立的位组成的。
因此,将rand()想象成一条制造比特的生产线,它恰好以任意大小的批次提供它们。如果你不喜欢大小,请将批次分解为单个比特,然后以你喜欢的任何数量将它们重新组合在一起(尽管如果你需要一个不是2的幂的特定范围,你需要缩小你的数字,到目前为止最简单的方法是转换为浮点数)。
回到你最初的建议,假设你想从15个批次变成30个批次,向rand()询问第一个数字,将其位移15位,然后再添加一个rand()。这是一种将两次调用合并到rand()而不会干扰均匀分布的方法。它之所以有效,只是因为你放置信息位的位置之间没有重叠。
这与通过乘以一个常数来“拉伸”rand()的范围非常不同。例如,如果你想将rand()的范围翻倍,你可以乘以2——但现在你只能得到偶数,而永远不会得到奇数!这不完全是一个平滑的分布,可能是一个严重的问题,具体取决于应用,例如一个轮盘赌式的游戏,据说允许奇数/偶数赌注。(通过从位的角度思考,你会直观地避免这个错误,因为你会意识到乘以2就等于将(更大意义上的)位向左移动一位,并用零填补差距。所以显然信息量是一样的-它只是移动了一点。
在浮点数应用程序中,这种数字范围的差距是无法控制的,因为浮点数范围内在地存在差距,根本无法表示:在每两个可表示的浮点数之间的差距中存在无限个缺失的实数!所以我们无论如何都要学会忍受差距。
正如其他人所警告的那样,直觉在这个领域是有风险的,特别是因为数学家无法抗拒实数的诱惑,实数是令人困惑的,充满了粗糙的无穷大和明显的悖论。
但至少如果你认为它是位的,你的直觉可能会让你走得更远。位真的很容易-甚至计算机也能理解它们。
简单化来说明一个问题。
假设你的随机函数只输出0或1。
1
random()是(0,1)中的一个,但random()*random()是(0,0,0,1)中的一个
random()
(0,1)
random()*random()
(0,0,0,1)
你可以清楚地看到,在第二种情况下获得0的机会与获得1的机会不相等。
当我第一次发布这个答案时,我想让它尽可能简短,这样阅读它的人就会一眼就明白random()和random()*random()之间的区别,但我不能阻止自己回答最初的广告问题:
哪个更随机?
当random()、random()*random()、random()+random()、(random()+1)/2或任何其他不会导致固定结果的组合具有相同的熵源(或伪随机生成器的相同初始状态)时,答案将是它们是同样随机的(区别在于它们的分布)。我们可以看一个完美的例子是骰子游戏。你得到的数字是random(1,6)+random(1,6),我们都知道得到7的几率最高,但这并不意味着掷两个骰子的结果比掷一个骰子的结果或多或少随机。
random()+random()
(random()+1)/2
random(1,6)+random(1,6)
好的,所以我将尝试添加一些价值来补充其他答案,说你正在创建和使用随机数生成器。
随机数生成器是具有多种特性的设备(在非常普遍的意义上),可以对其进行修改以适应目的。其中一些(来自我)是:
在这里的大多数答案中,分布是主要的兴趣点,但是通过混合和匹配函数和参数,您创建了生成随机数的新方法,这些随机数将具有不同的特征,其中一些特征乍一看可能并不明显。
使用实现原始多项式的线性反馈移位寄存器(LFSR)。
结果将是一个2^n个伪随机数的序列,即在序列中没有重复,其中n是LFSR中的位数……导致均匀分布。
http://en.wikipedia.org/wiki/Linear_feedback_shift_registerhttp://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
使用基于计算机时钟的微秒数的“随机”种子,或者在文件系统中一些不断变化的数据上使用md5结果的子集。
例如,32位LFSR将从给定种子开始按顺序生成2^32个唯一数字(没有2个相同)。序列将始终处于相同的顺序,但对于不同的种子,起点将不同(显然)。因此,如果种子之间可能重复的序列不是问题,这可能是一个不错的选择。
我使用128位LFSR在硬件模拟器中使用种子生成随机测试,该种子是连续变化的系统数据上的md5结果。
根本就没有more随机这回事。它要么是随机的,要么不是。Random的意思是“难以预测”。它并不意味着不确定。如果Random()是随机的,则随机()和随机()*随机()同样是随机的。就随机性而言,分布是无关紧要的。如果出现非均匀分布,那只意味着某些值比其他值更有可能;它们仍然是不可预测的。
由于涉及伪随机性,因此数字非常确定。然而,在概率模型和模拟中,伪随机性通常就足够了。众所周知,使伪随机数生成器变得复杂只会使分析变得困难。提高随机性的可能性不大;它经常导致它无法通过统计测试。
随机数的期望性质是重要的:重复性和再现性、统计随机性、(通常)均匀分布、以及大周期是少数。
关于随机数的变换:正如某人所说,两个或多个均匀分布的和结果是正态分布。这就是加性中心极限定理。只要所有分布都是独立和相同的,它就适用于源分布。乘法中心极限定理说,两个或多个独立且指数分布的随机变量的乘积是对数正态的。别人创建的图看起来是指数的,但它实际上是对数正态的。所以随机()*随机()是对数正态分布的(尽管它可能不是独立的,因为数字是从同一个流中提取的)。这在某些应用中可能是可取的。但是,通常最好生成一个随机数并将其转换为对数正态分布的数。Random()*随机()可能难以分析。
有关更多信息,请参阅我的书www.performorama.org.本书正在构建中,但相关材料在那里。请注意,章节和章节编号可能会随着时间的推移而变化。第8章(概率论)-第8.3.1节和第8.3.3节,第10章(随机数)。
很容易看出两个随机数的和并不一定是随机的。假设你有一个6面的骰子,每个数字都有1/6的机会出现。现在假设你有2个骰子,并将结果相加。这些总和的分布不是1/12。为什么?因为某些数字比其他数字出现得更多。它们有多个分区。例如,数字2只是1+1的和,但7可以由3+4、4+3或5+2等组成……所以它出现的机会更大。
因此,在这种情况下,在随机函数上应用变换加法并不会使其更随机,也不一定会保持随机性。在上面的骰子的情况下,分布偏向于7,因此随机程度较低。
我们可以使用以下方法比较两个数字数组的随机性柯尔莫哥洛夫复杂度如果数字序列不能被压缩,那么它是我们在这个长度上能达到的最随机的…我知道这种类型的测量更多的是一种理论选择…
正如其他人已经指出的那样,这个问题是很难回答,因为我们每个人都有他的自己的随机性。
这就是为什么,我强烈建议你花一些时间阅读这个网站,以更好地了解随机性:
回到真正的问题。在这个术语中没有或多或少的随机:
两者都是随机的!
在这两种情况下-只有rand()或rand()*rand()-情况相同:在数十亿个数字之后,序列将重复(!)。对于观察者来说,它出现是随机的,因为他不知道整个序列,但计算机有没有真正的随机源——所以他也不能产生随机性。
<强>例如:天气是随机的吗?我们没有足够的传感器或知识来确定天气是否随机。
实际上,当你想到它时,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%的概率是偶数或奇数
a
b
意味着有一个75%的机会,c是偶数,而只有一个25%的机会是奇数,使得rand() * rand()的值比rand()更可预测,因此更少随机。
c
假设rand()返回一个介于[0, 1)之间的数字,很明显rand() * rand()将偏向于0。这是因为将x乘以[0, 1)之间的数字将导致小于x的数字。这是10000个更多随机数的分布:
[0, 1)
google.charts.load("current", { packages: ["corechart"] });google.charts.setOnLoadCallback(drawChart); function drawChart() {var i;var randomNumbers = [];for (i = 0; i < 10000; i++) {randomNumbers.push(Math.random() * Math.random());}var chart = new google.visualization.Histogram(document.getElementById("chart-1"));var data = new google.visualization.DataTable();data.addColumn("number", "Value");randomNumbers.forEach(function(randomNumber) {data.addRow([randomNumber]);});chart.draw(data, {title: randomNumbers.length + " rand() * rand() values between [0, 1)",legend: { position: "none" }});}
<script src="https://www.gstatic.com/charts/loader.js"></script> <div id="chart-1" style="height: 500px">Generating chart...</div>
如果rand()返回[x, y]之间的整数,则您有以下分布。注意奇数与偶数值的数量:
[x, y]
google.charts.load("current", { packages: ["corechart"] });google.charts.setOnLoadCallback(drawChart);document.querySelector("#draw-chart").addEventListener("click", drawChart); function randomInt(min, max) {return Math.floor(Math.random() * (max - min + 1)) + min;} function drawChart() {var min = Number(document.querySelector("#rand-min").value);var max = Number(document.querySelector("#rand-max").value);if (min >= max) {return;}var i;var randomNumbers = [];for (i = 0; i < 10000; i++) {randomNumbers.push(randomInt(min, max) * randomInt(min, max));}var chart = new google.visualization.Histogram(document.getElementById("chart-1"));var data = new google.visualization.DataTable();data.addColumn("number", "Value");randomNumbers.forEach(function(randomNumber) {data.addRow([randomNumber]);});chart.draw(data, {title: randomNumbers.length + " rand() * rand() values between [" + min + ", " + max + "]",legend: { position: "none" },histogram: { bucketSize: 1 }});}
<script src="https://www.gstatic.com/charts/loader.js"></script> <input type="number" id="rand-min" value="0" min="0" max="10"><input type="number" id="rand-max" value="9" min="0" max="10"><input type="button" id="draw-chart" value="Apply"> <div id="chart-1" style="height: 500px">Generating chart...</div>