我正在编写一个在Delphi中编写统计测试的程序(必须是Delphi),我听说随机功能有些奇怪。当程序启动时,你必须调用randomize来随机化随机函数的种子。
我想知道随机函数(在调用randomize之后)是否足够随机进行统计测试或是否需要使用Mersenne twister?有没有人对随机的实际实现有任何了解,这可以告诉我这有多重要?
答案 0 :(得分:20)
与几乎所有编程语言RTL PRNG一样,Delphi的PRNG是linear congruential generator。
这对于大多数小规模的东西来说已经足够了,但有些事情需要注意。特别要注意低阶位:乘法和加法的模式意味着低阶位根本不是非常随机的。但这通常仅适用于拉出的大32位值,然后用mod
或类似截断。使用Random(10)
来获取0到9之间的值在内部使用整数32位而不是mod
操作的乘法。
答案 1 :(得分:16)
我无法抗拒。
答案 2 :(得分:6)
如果您正在寻求以最快的执行时间保证随机数的唯一性的方法,About.com已在Fastest Unique Random Number Generator上创建了挑战,并且Patrick van Logchem's implementation已被选为获胜者。
答案 3 :(得分:6)
Random
对于统计测试是否足够可靠取决于您打算使用它的上下文。
话虽如此,我已经编写了几段需要进行适当统计的Delphi代码,并使用了Random
例如用于获得各种空分布,数据伪复制和重采样。到目前为止,我没有在我自己的代码中遇到任何情况Random
会产生有偏见或不可靠的结果,或者结果会阻止其用于预期的统计测试。但是对于我的代码而言,并不一定要适用于你的代码。
如果有疑问,您当然可以统计分析调用Random
的结果(例如在R,SPSS等中),并检查结果的分布是否违反了您的特定统计检验的分布要求( S)。 [如果你是一名合适的科学家,无论如何这都是你应该做的。]
您是否需要其他PRNG - 例如TPMath库包含一些。 (对于更多涉及的事情,还可以选择从R通过Delphi调用精细的统计函数。)
答案 4 :(得分:4)
除非您购买一些相对深奥的硬件,否则计算机可以提供的随机数的最佳近似值是完全确定的伪随机序列。通常,randomize函数使用一些相对随机的值(通常基于时间,但有时候在鼠标移动中 - 我不知道Delphi做了什么)作为提供伪随机序列的入口点的种子。如果没有这个,你每次都会以相同的顺序返回相同的随机数集,这往往会破坏首先使用随机数的目的。
好吧,我意识到这并没有回答关于可靠性的问题,但它应该让你有信心要求你调用randomize是一个好的生成器的标志,而不是一个坏的生成器。有许多统计测试表明数字序列是如何随机的,并且德尔福随机数发生器很可能适用于许多目的,因为它是一个成熟的产品。
答案 5 :(得分:3)
只是为了增加可能性池--Windows提供了一系列内置Cryptography functions。如果默认情况下还没有包含它们,那么它们可能还有一个Delphi包装器。
这些功能中还有一个cryptographically strong random number generator。到目前为止,这是您在软件中获得的最佳随机性,因为它基于很长的因素列表来自我种子。我不确定,但我怀疑它会使用硬件随机数生成器(如果你有的话)。
如果这还不够,您还可以尝试在Quantum Random Bit Generator Service注册一些真正随机值。
答案 6 :(得分:2)
来自Embarcadero网站:
_lrand是长随机数生成器函数。 _rand使用乘法同余随机数发生器,周期为2 ^ 64,返回0到2 ^ 31 - 1范围内的连续伪随机数。
通过使用参数值1调用srand重新初始化生成器。可以通过使用给定的种子编号调用srand将其设置为新的起始点。
答案 7 :(得分:2)
如果他们在我分析之后没有改变实现(Delphi 4 IIRC),那么Delphi PRNG就是这样实现的:
Randseed:=int32(Randseed*$08088405)+1
result:=Randseed*Range shr 32
(伪代码/假设乘法是任意大整数)
答案 8 :(得分:-2)
在0..9之间随机返回
StrToInt(copy(FloatToStr(Random),4,1))
注意:使用前检查FloatToStr(随机)长度或使用小数部分中的任何其他数字......