我试图做我的欧几里得距离TSP产生一些选择-3交换,因为我在很多情况下比〜500个节点更多,我需要随机选择,我想尝试更换3个节点的至少1 。
所以基本上我需要一个随机数函数, 速度非常快 。 (正常兰特()是太慢),它不必是真棒,只是不够好。
编辑:我忘了提,我坐在这里我不能添加任何库除了标准的语言库的环境中(如STL,的iostream等)。 因此,没有升压= /
我试图做我的欧几里得距离TSP产生一些选择-3交换,因为我在很多情况下比〜500个节点更多,我需要随机选择,我想尝试更换3个节点的至少1 。
所以基本上我需要一个随机数函数, 速度非常快 。 (正常兰特()是太慢),它不必是真棒,只是不够好。
编辑:我忘了提,我坐在这里我不能添加任何库除了标准的语言库的环境中(如STL,的iostream等)。 因此,没有升压= /
其他线程提到马尔萨利亚的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;
}
我使用所有的地方这一块。 当我试图产生随机二进制矩阵它没有唯一的地方了。 约95x95矩阵过去,人们开始产生过少或过多的奇异矩阵(我忘了)。 它已经表明,这种发电机相当于一个线性移位反馈寄存器。 但是,除非你是做加密或严重蒙特卡洛工作,这个发电机的岩石。
从英特尔的网站有两个很好的选择:
1)fastrand - 它比STD兰特更快2.01 X()。 程序返回一个整数,类似的输出值范围为C库。
inline int fastrand() {
g_seed = (214013*g_seed+2531011);
return (g_seed>>16)&0x7FFF;
}
2)版本SSE(见下面的链接)为约5.5 X一样快STD兰特(),然而它在一个时间产生4个随机值,需要与SSE一个processer(几乎所有做),和更复杂。
http://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/
见这些发电机从随机数发生器专家乔治马尔萨利亚。 他们实现了C宏,他们是快如闪电,每次生成的数字只是一些操作。
在梅森倍捻机具有一定的快速实现。
与开始的Ivy Bridge架构的Intel增加RdRand CPU指令和AMD在2015年六月以后增加它因此,如果你的目标的处理器是足够新的不介意使用(在线)组装,生成随机数应该是最快的方法在调用RdRand
CPU指令描述得到一个16位或32位或64位的随机数这里 。 滚动到页面的大约中间的代码示例。 在该链接也有用于检查支持RdRand指令的当前CPU的代码示例,并且也看到了维基百科的如何使用CPUID指令做一个解释。
相关问题: 利用Sandy Bridge的硬件真随机数发生器的? (虽然根据维基百科, RdRand
指令最早出现在Ivy Bridge的,但不是的Sandy Bridge架构,这个问题说的)
例如C ++代码基于_rdrand64_step() :
#include <immintrin.h>
uint64_t randVal;
if(!_rdrand64_step(&randVal)) {
// Report an error here: random number generation has failed!
}
// If no error occured, randVal contains a random 64-bit number
甚至尽管这个帖子岁,就出现了,当我在寻找一个类似的答案,我结束了即使在使用它,心不是答案。 所以我加入一个,我发现;
#include <random>
MSDN条目
这种做法将建立一个自包含随机生成的,我发现这是一个很多超过随机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(Mersenne 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)<<"\n";
//will generate 1000 dice throws
for (int i=0;i<1000;++i)rng_dice(gen);
兰特()是真的织补快,我不相信你会发现要快得多。
如果它实际上是放慢你失望(我有点怀疑),那么你就需要一个架构的变化。
我建议预填充一长串随机数 ,那么在您需要时,随便拿一个从列表中,而不是生成一个。 您可以使用一个后台线程来重新填写列表。
Boost库有一组随机生成的。 性能图表可以发现在这里 。
编辑:这答案是这里原题的编辑之前。 但我希望它可能还是有帮助的,所以我离开这里。
您可以预生成一串随机比特的时间提前,并同时剥离其关闭2(因为你只需要1之间的随机数,3)?
我想好是相当不错的,而且WELL512a是很短。 http://www.iro.umontreal.ca/~panneton/WELLRNG.html WELL44497a在当时是太复杂了。 然而,WELL生成0和1之间的数字。