我能找到的大多数随机函数是序列函数,它将最后生成的结果作为下一个调用的种子
我想要一个可以自行运行的纯函数,并且可以从头到尾给出任何数字,并且可以给出看似随机的序列和一个种子
说实话,我希望一种算法可以并行生成随机数(并且可以在gpu中使用(,并且在每种元素的启动时只有一个随机种子作为输入
也许我可以使用哈希函数,但我想知道哪种算法可以给出最可能的均匀分布,并且在任何种子和任何长度上似乎总是随机的
编辑:谢谢大家的建议。我对我想要的东西有一个更扎实的想法,我可以解释
我不需要太多的雪崩物业,而是我更关心统一分配。并且要与之并联,它必须是一种无状态算法,因此大多数PRNG不合适
但是最不关心的是安全性。我想要一个看似随机的序列,但不要在任何安全性中使用它,仅用于视觉和界面
,如果它是非常快的算法
有几种选择"纯"随机功能。它们包括:
- 哈希功能。
- 播种伪数编号生成器(PRNG(的功能,其输入并返回PRNG的输出。
- 一个符合内部状态并输出随机数和新内部状态的函数(此方法非常适合Haskell和其他功能编程语言(。
另请参见我有关PRNGS设计或平行计算机的文章的文章:要求和方法,重点是GPU。(2015年(,由L'Ecuyer,Munger等人。
关于使用哪种哈希功能,有多种选择,包括SHA-1,SHA-256,XXHASH,MURMURHASH3等;某些哈希功能可能比其他功能更合适,具体取决于您是否需要安全性,除其他因素外。
大多数哈希函数输出一系列位,但是不难看到它们如何转换为数字 - 例如,请参阅此问题或我在数字上的文章,例如0和1。
好吧,以下是对问题的一些想法。
假随机函数通常称为伪随机数生成器(PRNG(。
您可能对[0 ... 1(范围内的双打感兴趣,但是PRNG通常会生成单个64位(适用于double(或32bit(适用于浮点(整数。转换为两倍,虽然并不是很简单,但非常简单。
典型的PRNG具有状态,用种子和输出发起。对于最简单的PRNG(例如LCG(种子,状态和输出是同一回事,但总体上并非如此。通常状态的特征是位数(例如,LCG的64位直到19937年的Mersenne Twister(。
从任何PRNG算法中制作纯函数都很简单 - PRNG只是以
的形式的三个函数集state_type make_state(seed_type seed) {
// convert seeding to state, bits chopping
return new_state;
}
state_type advance_state(state_type old_state) {
// do bits chopping with old state
// and advance to the next state
return new_state;
}
uint64_t generate_output(state_type state) {
// extract 64bits of randomness from state
return new_random_number;
}
就是这样,除了这些功能之外,Prng中没有其他内容。
和,在手中的问题
您可以使用具有良好雪崩属性的非晶体哈希,基本上意味着输入值的单位变化(输入增加1(会导致大变化。快速,合理,可能不是很随机。杂音还可以,还有妈妈哈希。
在计数器模式下运行的加密密码。比选项1慢,但是高质量的数字。相对较大的状态(例如512只左右(。我更喜欢Chacha20-它是众所周知的,合理的快速,在此处查看代码。选项1和2都假定您只是线性增加计数器作为输入。
另一个选项是使用具有对数复杂度的PRNG,从而提前功能。这可以从全球种子开始,如果您有2 10 cuda核,您的第一个核心将使用种子,第二个将跳下2 64 /2 10 = 2 54 ,使用O(log 2 (n((复杂性仅为54个操作,第三名将被另外2 54 步骤和54个操作等等。从已知的Prngs Googarihmic跳跃中,为LCG和PCG工作。我建议看PCG。
这意味着以
的形式存在非平凡的功能state_type advance_state(state_type old_state, int64_t distance) {
// non-trivial advance by distance
// non-trivial means it is not just a loop, it is better than linear algorithm
return new_state;
}