2013-11-01 115 views
4

我目前正在使用8个以上的管道(线程)运行多线程仿真应用程序。这些管道运行一个非常复杂的代码,这取决于种子生成的随机序列。该序列然后被煮成一个单一的0/1。64位随机发生器的种子

我希望这个“随机处理”在从主线程传递一个种子到处理管道后是100%确定性的。所以,我可以在第二轮复制结果。

所以,例如:(我有这个编码和它的作品)

Pipe 1 -> Seed: 123 -> Result: 0 
Pipe 2 -> Seed: 123 -> Result: 0 
Pipe 3 -> Seed: 589 -> Result: 1 

,当我需要运行这些过程的100M或以上,然后平均结果,就会出现问题。可能是这种情况,100M中只有1个是1,其余为0. 显然,我不能用32bit种子向srand()进行采样,因此无法采样100M随机值。

是否有可能在VS2010中使用64bit种子播种到srand()或使用等效方法?

rand()在2^32后重复自己还是没有(有一些内部隐藏状态)?

感谢

+0

'rand'具有周期RAND_MAX'的'其通常是2^16-1,没有接种的量将解决这个问题,最好使用较高质量PRNG。 – Necrolis

回答

3

您可以使用C++ 11的random工具生成给定大小和种子大小的随机数,尽管这里的过程有点复杂,无法总结。

例如,您可以构造一个std::mersenne_twister<uint64_t, ...>并以64位整数对它进行种子处理,然后在指定的分布中获取随机数,这似乎是您要查找的内容。

+0

谢谢!但我与VS2010 ... – DarkZeros

+0

VS2010已经支持这个 –

+0

很有意思,我想我会用这个到底 – DarkZeros

0

我不能回答你的问题,但如果你发现你想要的东西,你不能做,你可以实现自己的pseudo-random algorithm generator这需要一个uint64_t作为种子。 如果您想要一些更严重的生成器(例如用于加密目的),那么有更好的算法用于此目的,但是LCG是我见过的最容易实现的算法。

编辑

其实你不能使用的rand()功能的64位种子。你将不得不为自己的。在this维基百科表中有一些参数由MMIX Donald Knuth用来实现它。请注意,根据您使用的参数,随机数生成器周期将比2^64小得多,并且由于乘法运算,您可能需要一个大数字库来处理数学运算。

2

一个简单的64位LCG应该能够满足您的需求。位LC(最低有效位数为1位)最多有一个周期(如果参数选择正确,则正好)2^n,所以如果不需要使用低位, /或在输出上使用回火功能。示例实现可以在我的答案可以发现另外一个问题在这里:

https://stackoverflow.com/a/19083740/379897

而且转贴:

static uint32_t temper(uint32_t x) 
{ 
    x ^= x>>11; 
    x ^= x<<7 & 0x9D2C5680; 
    x ^= x<<15 & 0xEFC60000; 
    x ^= x>>18; 
    return x; 
} 
uint32_t lcg64_temper(uint64_t *seed) 
{ 
    *seed = 6364136223846793005ULL * *seed + 1; 
    return temper(*seed >> 32); 
} 
+0

我会保存这段代码,很有用。 – DarkZeros

2

你可以使用XOR SHIFT psuedorandom数发生器

它是快速和作品一种享受 - 这是我的实现类中的实际生成部分。我发现这个算法在psuedorandom数发生器维基百科搜索信息......

uint64_t XRS_64::generate(void) 
{ 
    seed ^= seed >> 12; // a 
    seed ^= seed << 25; // b 
    seed ^= seed >> 27; // c 
    return seed * UINT64_C(2685821657736338717); 
} 

它是快速和初始化你这样做的构造函数中

XRS_64::XRS_64() 
{ 
    seed = 6394358446697381921; 
} 

种子是一个unsigned int 64它是在类中声明的。

class XRS_64 
{ 
public: 
    XRS_64(); 
    ~XRS_64(); 
    void init(uint64_t newseed); 
    uint64_t generate(); 

private : 
    uint64_t seed; /* The state must be seeded with a nonzero value. */ 
};