我无法理解这个,哪个更随机?
rand()
OR:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。
我无法理解这个,哪个更随机?
rand()
OR:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。
当前回答
大多数这种分布发生是因为你必须限制或规范随机数。
我们将其标准化为全部为正,符合范围,甚至符合指定变量类型的内存大小限制。
换句话说,因为我们必须将随机调用限制在0和X之间(X是变量的大小限制),所以我们将有一组介于0和X的“随机”数。
现在,当你将随机数与另一个随机数相加时,总和将介于0和2X之间。。。这会使值偏离边缘点(当两个随机数在较大范围内时,将两个小数字相加和将两个大数字相加的概率非常小)。
想象一下这样一个例子,你有一个接近于零的数字,你将它与另一个随机数相加,它肯定会变大,远离0(这对于大数字是正确的,因为随机函数不可能两次返回两个大数字(接近于X的数字)。
现在,如果你用负数和正数设置随机方法(跨越零轴),情况将不再如此。
例如,假设RandomReal({-x,x},50000,.01),那么你会得到负数和正数的偶数分布,如果你将随机数相加,它们将保持其“随机性”。
现在我不确定Random()*Random(()从负到正的跨度会发生什么。。。这将是一个有趣的图表。。。但我现在得回去写代码了-P
其他回答
大多数这种分布发生是因为你必须限制或规范随机数。
我们将其标准化为全部为正,符合范围,甚至符合指定变量类型的内存大小限制。
换句话说,因为我们必须将随机调用限制在0和X之间(X是变量的大小限制),所以我们将有一组介于0和X的“随机”数。
现在,当你将随机数与另一个随机数相加时,总和将介于0和2X之间。。。这会使值偏离边缘点(当两个随机数在较大范围内时,将两个小数字相加和将两个大数字相加的概率非常小)。
想象一下这样一个例子,你有一个接近于零的数字,你将它与另一个随机数相加,它肯定会变大,远离0(这对于大数字是正确的,因为随机函数不可能两次返回两个大数字(接近于X的数字)。
现在,如果你用负数和正数设置随机方法(跨越零轴),情况将不再如此。
例如,假设RandomReal({-x,x},50000,.01),那么你会得到负数和正数的偶数分布,如果你将随机数相加,它们将保持其“随机性”。
现在我不确定Random()*Random(()从负到正的跨度会发生什么。。。这将是一个有趣的图表。。。但我现在得回去写代码了-P
假设rand()返回一个介于[0,1)之间的数字,很明显rand(*rand)将偏向于0。这是因为将x乘以[0,1)之间的数字将得到一个小于x的数字。下面是10000个随机数的分布:
google.charts.load(“current”,{packages:[“corechart”]});google.cacharts.setOnLoadCallback(drawChart);函数drawChart(){变量i;var randomNumbers=[];对于(i=0;i<10000;i++){randomNumbers.push(Math.rrandom()*Math.random());}var chart=新的google.visability.Histogram(document.getElementById(“chart-1”));var data=新的google.visibility.DataTable();data.addColumn(“数字”,“值”);randomNumbers.forEach(函数(randomNumber){data.addRow([randomNumber]);});chart.draw(数据{title:randomNumbers.length+“rand()*rand(值介于[0,1)之间”,图例:{位置:“无”}});}<script src=“https://www.gstatic.com/charts/loader.js“></script><div id=“chart-1”style=“height:500px”>正在生成图表</分区>
如果rand()返回[x,y]之间的整数,则得到以下分布。注意奇数与偶数的数量:
google.charts.load(“current”,{packages:[“corechart”]});google.cacharts.setOnLoadCallback(drawChart);document.querySelector(“#绘制图表”).addEventListener(“单击”,绘制图表);函数randomInt(最小值,最大值){return Math.floor(Math.random()*(max-min+1))+min;}函数drawChart(){var min=编号(document.querySelector(“#rand min”).value);var max=编号(document.querySelector(“#rand max”).value);如果(最小值>=最大值){回来}变量i;var randomNumbers=[];对于(i=0;i<10000;i++){randomNumbers.push(randomInt(最小,最大)*randomInt(最小,最小));}var chart=新的google.visability.Histogram(document.getElementById(“chart-1”));var data=新的google.visibility.DataTable();data.addColumn(“数字”,“值”);randomNumbers.forEach(函数(randomNumber){data.addRow([randomNumber]);});chart.draw(数据{title:randomNumbers.length+“rand()*rand(()值介于[“+min+”,“+max+”]”之间,图例:{位置:“无”},直方图:{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”>正在生成图表</分区>
答案将是,这取决于,希望rand()*rand(()比rand)更随机,但如下所示:
两个答案都取决于你的值的位数在大多数情况下,你根据伪随机算法生成(它主要是一个数字生成器,依赖于你的计算机时钟,而不是那么随机)。让你的代码更可读(不要用这种咒语来召唤一些随机的巫毒神)。
好吧,如果你检查上面的任何一个,我建议你使用简单的“rand()”。因为你的代码会更可读(不会问自己为什么要写这个,时间……嗯……超过2秒),易于维护(如果你想用super_rand替换rand函数)。
如果你想要更好的随机性,我建议你从任何提供足够噪声的源(无线电静态)流式传输,然后一个简单的rand()就足够了。
两者都不是“更随机”的。
rand()基于伪随机种子生成一组可预测的数字(通常基于当前时间,该时间总是在变化)。将序列中的两个连续数字相乘,生成一个不同但同样可预测的数字序列。
关于这是否会减少冲突,答案是否定的。它实际上会增加冲突,这是因为在0<n<1的情况下,两个数字相乘的结果。结果将是一个较小的分数,导致结果偏向频谱的低端。
一些进一步的解释。在下文中,“不可预测”和“随机”是指某人根据先前的数字猜测下一个数字的能力,即预言。
给定生成以下值列表的种子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以下,尽管在原始序列中分布良好。由于两个分数相乘的影响,这些数字是有偏差的。由此产生的数字总是较小,因此更可能发生碰撞,尽管仍然无法预测。
只是一个澄清
尽管每当你试图发现伪随机变量或其乘法的随机性时,前面的答案都是正确的,但你应该知道,虽然random()通常是均匀分布的,但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*Random()均匀分布时:
BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]
随机()+随机()不是!
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个均匀分布的随机变量相加,可以看到从均匀分布到正态分布的道路:
Edit
几个学分
感谢Thomas Ahle在评论中指出,最后两张图片中显示的概率分布称为Irwin Hall分布
感谢Heike出色的撕裂功能