我应该验证我们实现Lua的随机数生成器的能力。
这就是我想出来的......
for i = 1,10000 do -- I hope that's ten thousand
X = math.random(0,9)
if X == 0 then This_Many_0 = This_Many_0 + 1
elseif X == 1 then This_Many_1 = This_Many_1 + 1
elseif X == 2 then This_Many_2 = This_Many_2 + 1
elseif X == 3 then This_Many_3 = This_Many_3 + 1
elseif X == 4 then This_Many_4 = This_Many_4 + 1
elseif X == 5 then This_Many_5 = This_Many_5 + 1
elseif X == 6 then This_Many_6 = This_Many_6 + 1
elseif X == 7 then This_Many_7 = This_Many_7 + 1
elseif X == 8 then This_Many_8 = This_Many_8 + 1
elseif X == 9 then This_Many_9 = This_Many_9 + 1
else Bogus_Alert = True -- Better not happen
end -- End the big if/elseif block
The_Interim_Sum = The_Interim_Sum + X -- Keep a running sum
end -- This is the i loop
然后我打印了结果,这里是......
Running
Number of times we got 0 ... 1019
Number of times we got 1 ... 979
Number of times we got 2 ... 954
Number of times we got 3 ... 1006
Number of times we got 4 ... 995
Number of times we got 5 ... 999
Number of times we got 6 ... 989
Number of times we got 7 ... 1000
Number of times we got 8 ... 1042
Number of times we got 9 ... 1017
The sum of the ten thousand random numbers was 45303
The average of those numbers was 4.5303
End
这些都符合我的期望;即,平均值非常接近4.5,每个个体数的分布接近千。
更重要的是,对于像这样的数字,我说确实是的,那个生成器在制作一万个真正随机的随机数方面做得非常好。
这里有一个混乱的地方:我的老板说如果机器真正做好了工作,真正给我们随机数字,那么每个数字的分布应该是均匀的;也就是说,在一万次迭代中,我应该得到每个数字的一千个。
我尝试在使用math.randomseed(os.time())
的循环之前添加X = math.random(0,9)
,基于StackOverflow上的其他一些对话。结果进一步消失,而不是更接近。
我取出math.randomseed(os.time())
行,再次进行测试,得到的平均值为4.5007(这是我见过的最好的)。
那么,我发现了什么?还有什么?没有 ?随机数生成器实际上是*伪*随机数生成器?每个人都已经知道了。
我是否证明了这个伪随机数发生器几乎和我们预期的一样随机?
我有理由担心使用这些值吗?我会按常规拍摄,并故意给他不好的数字。全范围对于测试每个案例都太过分了。我猜测正确分布,16K的蠢事让我有信心芯片正确处理(故意坏的)价值。
(注意读者,我在多处理器系统上进行V& V操作,而我的Lua脚本伪造了我们尚未拥有的系统部分之一的行为。)
在这种情况下,使用math.random()
函数是否有办法让Lua生成每个数字的一千个?
如果是这样,那真的是随机的吗?
答案 0 :(得分:5)
首先,您需要在使用math.randomseed()
之前运行math.random()
一次,并且最好丢弃前几个随机数,因为前几个在某些实现中不是随机数,请参阅{{3对于细节。
math.randomseed(os.time())
math.random(); math.random(); math.random()
其次,即使你将一个完美的平衡硬币翻转一千次,你通常也不会精确 500次头部和500次尾部。只是获得头部的概率大约是500.如果实验已经进行了很多次,你会发现头部的平均值是500,但是每次都不是500。
第三,是的,math.random()
是 psudo 随机数生成器。实际上,您无法仅使用计算机生成真实随机数。 Lua math.random()
在内部使用C库函数rand()
。确实,C rand()
函数不是一个好的随机数生成器。如果随机性很重要,请使用一些更好的方法来实现,例如C ++随机引擎,或Linux上的dev/random
等。
答案 1 :(得分:3)
一个非常简单的测试是使用随机数序列作为(x,y)或(x,y,z)坐标并绘制它们。以下是一些现实世界的例子:
答案 2 :(得分:2)
还有其他测试而不是频率。见http://en.wikipedia.org/wiki/Statistical_randomness。你可能想尝试一下。
如果您想要一个具有已知属性的Lua随机数生成器,请尝试lrandom,它基于Mersenne Twister。