C++ 程序内容的快速伪随机数生成器

C++ 程序内容的快速伪随机数生成器,c++,x86,random,C++,X86,Random,我正在寻找一个伪随机数生成器,它将专门用于在生成每个数字之前给它一个种子时快速工作。到目前为止,我看到的大多数生成器都假设您设置一次种子,然后生成一个长序列的数字。到目前为止,唯一看起来有点类似的是柏林噪声,但它生成的数据太“平滑”,对于类似的输入,它往往会产生类似的结果 生成器的声明应类似于: int RandomNumber1(int seed); 或: 我认为拥有好的RandomNumber1就足够了,因为可以通过散列输入并将结果传递到RandomNumber1来实现RandomNumb

我正在寻找一个伪随机数生成器,它将专门用于在生成每个数字之前给它一个种子时快速工作。到目前为止,我看到的大多数生成器都假设您设置一次种子,然后生成一个长序列的数字。到目前为止,唯一看起来有点类似的是柏林噪声,但它生成的数据太“平滑”,对于类似的输入,它往往会产生类似的结果

生成器的声明应类似于:

int RandomNumber1(int seed);
或:

我认为拥有好的RandomNumber1就足够了,因为可以通过散列输入并将结果传递到RandomNumber1来实现RandomNumber3,但是我编写了第二个原型,以防一些实现可以使用独立的输入

此生成器的预期用途是将其用于程序内容生成器,例如通过将树放置在网格中并确定每个位置的随机树种和随机空间偏移来生成森林


生成器需要非常高效(低于500个CPU周期),因为在渲染过程中会实时创建大量过程内容。

看起来您需要的是哈希函数而不是PRNG。通过谷歌搜索“快速散列函数”可以得到几个有希望的结果

:

uint32\u t散列(uint32\u t a)
a=(a^61)^(a>>16);
a=a+(a>4);
a=a*0x27d4eb2d;
a=a^(a>>15);
返回a;
}
编辑:是的,某些哈希函数看起来确实比其他的更合适


出于您的目的,查看函数并检查输入中的单个位更改是否会传播到许多输出位就足够了。

是的,您正在寻找快速整数哈希算法,而不是PRNG

这有一些算法,我相信你会发现更多,现在你知道了正确的搜索词


< > >强>编辑< /强>:原始页已被删除,实况版本可以。

< P>见代码> STD::RANX3,或其他随机数生成器,是Tr1添加到标准C++库的一部分。我最初建议mt19937,但后来看到你的说明,它需要非常快。TR1应该在和GCC上可用,也可以在支持更多编译器的boost库中找到

示例改编自:


任何TR1随机数生成器都可以为任何其他随机数生成器种子。如果你需要更高质量的结果,考虑将MT1937的输出(速度较慢,但质量更高)送入MimSTdLyRand或RANDLU3,这是更快的生成器。

< P>如果内存不是真正的问题,速度是最重要的,那么你可以预先构建一个大的随机数数组,并在运行时迭代一遍。例如,让一个单独的程序生成100000个随机数,并将其保存为自己的文件,如

无符号整数随机数组[]={1,2,3,…..}


然后将该文件包含到编译中,在运行时,您的随机数函数只需从该数组中提取数字,并在到达末尾时循环回开始处。

这是George Marsaglia开发的一个小型随机数生成器。他是这一领域的专家,因此你可以确信生成器具有良好的统计特性

v = 36969*(v & 65535) + (v >> 16);
u = 18000*(u & 65535) + (u >> 16);
return (v << 16) + (u & 65535);
v=36969*(v&65535)+(v>>16);
u=18000*(u&65535)+(u>>16);

return(v我在Java随机数库中使用了以下代码-这对我来说非常有效。我还使用它来生成过程内容

/**
 * State for random number generation
 */
private static volatile long state=xorShift64(System.nanoTime()|0xCAFEBABE);

/**
 * Gets a long random value
 * @return Random long value based on static state
 */
public static long nextLong() {
    long a=state;
    state = xorShift64(a);
    return a;
}

/**
 * XORShift algorithm - credit to George Marsaglia!
 * @param a initial state
 * @return new state
 */
public static final long xorShift64(long a) {
    a ^= (a << 21);
    a ^= (a >>> 35);
    a ^= (a << 4);
    return a;
}
/**
*随机数生成的状态
*/
私有静态易失性长状态=xorShift64(System.nanoTime()| 0xCAFEBABE);
/**
*获取一个长随机值
*@返回基于静态的随机长值
*/
公共静态long nextLong(){
长a=状态;
状态=xorShift64(a);
返回a;
}
/**
*XORShift算法-归功于George Marsaglia!
*@param a初始状态
*@返回新状态
*/
公共静态最终长xorShift64(长a){
a^=(a>>35);

a^=(a我希望这是一个好的方向。乍看起来,虽然哈希函数有一个重要的属性(均匀分布),但我不太确定它的输出是否可以被视为“随机”-我如何知道一个特定函数的输出有多像噪声?一个好的哈希函数的一个测试是给它一个整数序列0,1,2..,并使用伪随机数生成器测试输出的“随机性”。答案很好,尽管我不同意“哈希函数而不是PRNG”一般来说,哈希函数并不总是很好的随机数生成器(它们更多地是为其他属性设计的:),OP确实需要某种质量的随机性,否则他的森林看起来会是假的。也就是说,一些哈希函数“足够随机”PRNG,它们当然是OP要求的确定性的。像中那样计算一个简单的散列几乎总是比访问一个大数组快(大数组不能放入缓存,因此访问它很慢)我只是在我的电脑上对它进行了分析,使用我的查找表方法与哈希函数相比,查找表的速度快了13倍。当查找表足够小,可以放入二级缓存时,以及当您不使用二级缓存进行任何其他操作时,查找表的速度可能会更快—这在您的测试中是最有可能的。如果您想要测试真实世界的性能,您需要在查找之间执行一些重要的数据处理。不幸的是,这与问题不符。我每次都需要提供自己的U和V,而不是将它们存储在某个位置并在迭代之间进行更新。如果输入相同,函数需要始终生成相同的输出。@Suma:为什么不能为每个t提供自己的U和V如果你只是把它们作为参数传递给这个函数,那么每次都有相同的U和V也会产生相同的结果
#include <random>
#include <iostream>
#include <iterator>
#include <functional>
#include <algorithm>
#include <ctime>
using namespace std;
using namespace std::tr1;
int main(){
    random_device trueRand;
    ranlux3 rng(trueRand);  // produces randomness out of thin air
                            // see pseudo-random number generators
    uniform_int<> six(1,6); // distribution that maps to 1..6
                            // see random number distributions
    variate_generator<ranlux3&, uniform_int<> >
           die(rng, six);   // glues randomness with mapping

    // simulate rolling a die
    generate_n( ostream_iterator<int>(cout, " "), 10, ref(die));
}
2 4 4 2 4 5 4 3 6 2
v = 36969*(v & 65535) + (v >> 16);
u = 18000*(u & 65535) + (u >> 16);
return (v << 16) + (u & 65535);
/**
 * State for random number generation
 */
private static volatile long state=xorShift64(System.nanoTime()|0xCAFEBABE);

/**
 * Gets a long random value
 * @return Random long value based on static state
 */
public static long nextLong() {
    long a=state;
    state = xorShift64(a);
    return a;
}

/**
 * XORShift algorithm - credit to George Marsaglia!
 * @param a initial state
 * @return new state
 */
public static final long xorShift64(long a) {
    a ^= (a << 21);
    a ^= (a >>> 35);
    a ^= (a << 4);
    return a;
}