C ++上的随机数


12

最近,我习惯了现代语言,其中包括一个很好的随机生成器,通常是Mersenne Twister。回到C ++之后,我必须决定使用什么。

我搜索了Mersenne Twister实现,然后发现有这么多实现:是否有一种使用更广泛,使用更广泛的实现,还是应该假设它们都一样好而选择一种?


1
我喜欢您将C ++和现代语言分开的做法。
jcora 2012年

2
也许说“更高级别”更合适。
o0'。

我认为这个问题属于stackoverflow
TravisG 2012年

5
因此,我会给出不同的答案,因为我不知道它是用于游戏引擎的,而不是用于医学疗法的蒙特卡洛模拟,在这种情况下,不具有624维的随机性可能是致命的。

Answers:


19

默认情况下,C ++ 11包括一个Mersenne Twister生成器,作为其新<random>接口的一部分。例如,要使用MT均匀地在[-10,10]之间生成整数:

std::mt19937 eng; // This is the Mersenne Twister
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

尽管名称略有不同,但大多数提供TR1的编译器中都提供了此功能。std::tr1::mt19937std::tr1::uniform_int<int>

我通常会提醒人们不要使用Mersenne Twister。这是一个不错的算法,但是它的很多流行只是营销。624个维度的随机性超出了大多数人的需求,并且MT承载着相对繁重的状态要求,并且当它对整个表进行重新计算时,它可能会破坏高速缓存。我个人比较喜欢xorshift,它为游戏所需的任何内容提供了出色的周期和合理的分配,而对内存和CPU的要求却很小。

我已经编写了(主要是?)符合C ++ 11的xorshift生成器-xorshift.hppxorshift.cpp,并将其放置在公共域中。您可以将其插入任何C ++ 11随机化函数,如上所述:

xorshift eng;
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

5
是的,这就是我一直在寻找的答案,这就是为什么我在这里将其发布在gamedev:)
o0'上。

1
只是要注意,您链接的文件中没有任何内容表明它们在公共领域中。版权法的运作方式,确实需要明确说明这一点,因为该法律默认假定为“保留所有权利”。实际上,使用诸如MIT或BSD 2条款之类的许可证实际上更为安全,因为某些管辖区基本上不承认“这是在公共领域中”具有法律约束力。如果您有兴趣让人们使用您的代码,那么值得考虑一下。
肖恩·米德迪奇

1
@seanmiddleditch:我在这里很清楚。如果您希望以MIT风格的许可证使用它,我将按照SQLite的指导进行操作,并以$ 1000的价格将其赠与您。

主要问题是缺少代码中的标头声明任何内容(SQLite这样做,iirc)。如果您不在乎,那很酷。只是给您一个友好的建议。
肖恩·米德迪奇

1

我以前用过的gamedev目的另一个RNG是鲍勃·詹金斯的‘小’RNG,描述在这里

(他还拥有一种称为ISAAC的加密强度RNG,但它更大,更慢,并且游戏不需要这种强度。)


1
看起来比xorshift昂贵(4个xor和3个移位与4个加,6个移位,2个ors和一个xor),周期更糟,并且在进行某些初始化时冒着非常短的周期的风险。它看起来很快,但不是最快。好的时期,但远未达到最佳状态;与xorshift具有相同的基本发行质量;我没有任何理由使用它。

很公平。我对RNG分析了解不足,无法深入了解分布和循环属性。
内森·里德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.