需要一个快速的随机生成器的C + +
我试图做一些opt-3交换我的TSP发生器的欧几里德距离,因为我在很多情况下有超过500个节点,我需要随机select我想尝试交换的3个节点中的至less1个。
所以基本上我需要一个快速的随机数函数。 (正常的rand()方式太慢)它不一定非常好,只是够好。
编辑:我忘了提及,我坐在一个环境,我不能添加除标准语言库(如STL,iostream等)以外的任何库。 所以没有提升= /
另一个线程提到了Marsaglia的xorshf生成器,但没有人发布代码。
static unsigned long x=123456789, y=362436069, z=521288629; unsigned long xorshf96(void) { //period 2^96-1 unsigned long t; x ^= x << 16; x ^= x >> 5; x ^= x << 1; t = x; x = y; y = z; z = t ^ x ^ y; return z; }
我已经在这个地方使用了这个。 唯一失败的地方是当我试图产生随机二进制matrix。 过去约95x95matrix,它开始产生太less或太多奇异matrix(我忘记了)。 已经表明,这个发生器相当于一个线性移位反馈寄存器。 但是,除非你正在做密码学或严重的蒙特卡罗工作,否则这个发生器就会摇摆。
来自英特尔网站的两个不错的select:
1)fastrand – 比std rand()快2.01倍。 该例程返回一个整数,与C lib类似的输出值范围。
inline int fastrand() { g_seed = (214013*g_seed+2531011); return (g_seed>>16)&0x7FFF; }
2)一个SSE版本(见下面的链接)大约5.5倍于std rand(),但是它一次产生4个随机值,需要一个处理器与sse(几乎所有的),并且更复杂。
从随机数生成器专家George Marsaglia中查看这些生成器。 它们被实现为Cmacros,而且它们闪电般快,只是每个数字产生一些操作。
Mersenne Twister有一些快速的实现。
从Ivy Bridge体系结构开始,Intel增加了RdRand CPU指令,AMD在2015年6月稍后添加了它。因此,如果您的目标是足够新的处理器,并且不介意使用(内联)汇编,生成随机数的最快方法应该是在调用RdRand
CPU指令来获得一个16位或32位或64位的随机数,如下所述。 滚动到页面中间的代码示例。 在这个链接上还有一个代码示例,用于检查当前的CPU是否支持RdRand指令,另请参阅维基百科,了解如何使用CPUID指令执行此操作。
相关问题: 利用沙桥的硬件真随机数发生器? (尽pipe根据维基百科, RdRand
指令首先出现在Ivy Bridge,而不是Sandy Bridge架构,因为这个问题说)
兰特()实在是太快了,我不相信你会发现更快。
如果它实际上减慢了你的速度(我有点怀疑),那么你需要一个架构的改变。
我build议使用随机数字预先填充一个长列表 ,然后当您需要时,只需从列表中选取一个,而不是生成一个列表。 您可以使用后台线程重新填充列表。
即使这个职位已经有几十年了,但当我find一个类似的答案时,它就出现了,我所使用的答案甚至不在其中。 所以我加了一个我发现的
#include <random>
msdn条目
这种方法将构build一个自包含的随机生成器,我发现它比rand()%x
更加随机。 超过几十万次迭代。 rand()%
将永远不会抛出16 +头/尾连续,当它应该每隔65K尝试。 这不仅是这样,而且是在四分之一的时间内。
这是我自己实现#include <random>
:
//create rng_gen, using mt technique, with range 0,1 (coin) and 1,6(dice); std::random_device rd; //seed std::mt19937 gen(rd()); //seed for rd(merzenne twister) std::uniform_int_distribution<> rng_coin(0, 1); //rng1 range std::uniform_int_distribution<> rng_dice(1, 6); ///rng2 range rng_coin(gen); //will apply rng1 range on (gen) object. Is very fast rng_dice(gen); //will apply rng2 range, returns int. //will output 1000 cointosses to console for (int i=0;i<1000;++i)std::cout<<rng_coin(gen)<<std::endl //will generate 1000 dice throws for (int i=0;i<1000;++i)rng_dice(gen);
你能提前预先生成一堆随机数,并且一次剥离掉它们(因为你只需要一个1到3之间的随机数)?
Boost库有一组随机生成器。 性能图表可以在这里find。
编辑:这个答案在这里是原始问题的编辑之前。 但是,我希望它仍然有帮助,所以我把它留在这里。
我觉得WELL很不错,WELL512a很短。 http://www.iro.umontreal.ca/~panneton/WELLRNG.html WELL44497a当时也很复杂。 但是,WELL会生成一个介于0和1之间的数字。