如何在群集上生成独立的伪随机数,例如蒙特卡罗模拟?我可以拥有许多计算节点(例如100),我需要在每个节点上生成数百万个数字。我需要保证一个节点上的PRN序列不会与另一个节点上的PRN序列重叠。
答案 0 :(得分:11)
您永远不应使用从相同原始流获取的可能重叠的随机流。如果您尚未测试生成的交错流,则不了解其统计质量。
幸运的是, Mersenne Twister(MT)将帮助您完成分发任务。使用名为 Dynamic Creator 的专用算法(以下简称DC),您可以创建独立随机数生成器,从而生成高度独立的随机数据流。
将在将要使用它的节点上创建每个流。基本上,将DC视为面向对象范例中的构造函数,它创建了不同的MT实例。每个不同的实例都旨在产生高度独立的随机序列。
您可以在此处找到DC:http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/DC/dc.html
它非常简单易用,您可以修复不同的参数,例如您想要获取的不同MT实例的数量或这些MT的周期。根据其输入参数,DC将运行时将更改。
除了DC附带的自述文件外,请查看DC存档中的文件example/new_example2.c
。它显示了获取独立序列的调用示例给定不同的输入标识符,这基本上是您必须识别集群作业的。
最后,如果您打算详细了解如何在并行或分布式环境中使用PRNG,我建议您阅读这些科学文章:
随机高性能计算随机流的实际分布 ,David RC Hill,高性能计算与仿真国际会议(HPCS),2010
答案 1 :(得分:1)
好的,回答#2; - )
我要说...保持简单。只需使用“短”种子来填充MT(假设这个种子是2 32 位,因为没有更好的限制)。这假设短种子生成“充分分布”的MT起始状态(例如,在我的其他答案中的代码中init_genrand
,希望如此)。这并不保证一个平均分布的起始状态,而是“足够好”,见下文。
每个节点将使用它自己预先选择的种子序列(传输的随机种子列表或类似number_nodes * node_number * iteration
的公式)。重要的是,最初的“短”种子永远不会在节点间重复使用。
然后,每个节点将使用使用此种子n
初始化的MT PRNG n <<< MT_period / max_value_of_short_seed
TT800 is 2800-1 and MT19937 is 219937-1,因此n
仍然可以非常大< / em>数字)。在n
次之后,节点将移动到所选列表中的下一个种子。
虽然我(我也不能)提供“保证”,即任何节点都不会同时(或根本没有)重复序列,这里是AMD says about Using Different Seends :(显然是初始播种)算法起作用。)
在这里描述的创建多个流的四种方法中,这是最不令人满意的 ...例如,如果初始值相距不够远,则从不同起点生成的序列可能会重叠。如果使用的发电机的周期很长,则减少了重叠序列的可能性。 虽然不能保证序列的独立性,但由于其周期极长,使用具有随机起始值的Mersenne Twister不太可能导致问题,特别是如果所需序列的数量很少...
快乐的编码。
答案 2 :(得分:1)
我可以在每个节点上跳到序列中的已知距离。但是 有Mersenne-Twister或任何其他好的算法 PRNG,可以在合理的时间和记忆下完成吗?
是的,请参阅http://theo.phys.sci.hiroshima-u.ac.jp/~ishikawa/PRNG/mt_stream_en.html。这是获得独立随机数流的绝佳解决方案。通过使跳转大于每个流所需的随机数来创建每个流的开始,流不会重叠。
答案 3 :(得分:0)
免责声明:我不确定MT在从任意“uint”(或x,其中x是较小的任意但唯一值)种子开始时,在循环重叠方面有什么保证,但这可能值得研究,好像有一个保证,那么在一个不同的“uint”种子上启动每个节点可能就足够了,而这个帖子的其余部分在很大程度上没有实际意义。 (The cycle length/period of MT is staggering并且除去UINT_MAX仍会留下难以理解的 - 除了纸上 - 号码。)
嗯,这是我的评论回答......
我喜欢使用预先生成的一组状态来处理#2;然后用给定的起始状态初始化每个节点中的MT。
当然,只有初始状态必须保留,一旦生成,这些状态就可以
考虑到MT 快速生成,我不推荐上面的#3,因为它只是复杂并且附加了许多字符串。选项#1很简单,但可能不够动态。
选项#2似乎是非常好的可能性。服务器(“快速机器”,不一定是节点)只需要传输下一个“未使用的序列块”的起始状态(比如,10亿个周期) - 节点将在询问之前使用发生器10亿个周期换一个新的街区。这将使其成为帖子中#1的混合,非常罕见的消息传递。
在我的系统上,Core2 Duo,我可以使用下面提供的代码在17秒内生成 10亿个随机数(它在LINQPad中运行)。我不确定这是什么MT变种。
void Main()
{
var mt = new MersenneTwister();
var start = DateTime.UtcNow;
var ct = 1000000000;
int n = 0;
for (var i = 0; i < ct; i++) {
n = mt.genrand_int32();
}
var end = DateTime.UtcNow;
(end - start).TotalSeconds.Dump();
}
// From ... and modified (stripped) to work in LINQPad.
// http://mathnet-numerics.googlecode.com/svn-history/r190/trunk/src/Numerics/Random/MersenneTwister.cs
// See link for license and copyright information.
public class MersenneTwister
{
private const uint _lower_mask = 0x7fffffff;
private const int _m = 397;
private const uint _matrix_a = 0x9908b0df;
private const int _n = 624;
private const double _reciprocal = 1.0/4294967295.0;
private const uint _upper_mask = 0x80000000;
private static readonly uint[] _mag01 = {0x0U, _matrix_a};
private readonly uint[] _mt = new uint[624];
private int mti = _n + 1;
public MersenneTwister() : this((int) DateTime.Now.Ticks)
{
}
public MersenneTwister(int seed)
{
init_genrand((uint)seed);
}
private void init_genrand(uint s)
{
_mt[0] = s & 0xffffffff;
for (mti = 1; mti < _n; mti++)
{
_mt[mti] = (1812433253*(_mt[mti - 1] ^ (_mt[mti - 1] >> 30)) + (uint) mti);
_mt[mti] &= 0xffffffff;
}
}
public uint genrand_int32()
{
uint y;
if (mti >= _n)
{
int kk;
if (mti == _n + 1) /* if init_genrand() has not been called, */
init_genrand(5489); /* a default initial seed is used */
for (kk = 0; kk < _n - _m; kk++)
{
y = (_mt[kk] & _upper_mask) | (_mt[kk + 1] & _lower_mask);
_mt[kk] = _mt[kk + _m] ^ (y >> 1) ^ _mag01[y & 0x1];
}
for (; kk < _n - 1; kk++)
{
y = (_mt[kk] & _upper_mask) | (_mt[kk + 1] & _lower_mask);
_mt[kk] = _mt[kk + (_m - _n)] ^ (y >> 1) ^ _mag01[y & 0x1];
}
y = (_mt[_n - 1] & _upper_mask) | (_mt[0] & _lower_mask);
_mt[_n - 1] = _mt[_m - 1] ^ (y >> 1) ^ _mag01[y & 0x1];
mti = 0;
}
y = _mt[mti++];
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >> 18);
return y;
}
}
快乐的编码。
答案 4 :(得分:0)
TRNG是一个随机数生成器,专门针对并行集群环境而构建(特别是它是为德国的TINA超级计算机而构建的)。因此,创建独立的随机数流并生成非标准分布非常容易。有一个如何在这里设置它的教程: http://www.lindonslog.com/programming/parallel-random-number-generation-trng/