我正在尝试在Matlab中创建随机数,这些数据在多个PBS作业中是不同的(我正在使用作业数组)。每个Matlab作业都使用并行parfor循环,其中生成随机数,如下所示:
parfor k = 1:10
tmp = randi(100, [1 200]);
end
然而,当我绘制结果时,我发现不同作业的结果并不是完全随机的 - 我无法量化它,例如通过说数字完全相同,因为我的结果是随机数的函数,但是在绘制它时是明白无误的。 我尝试使用进程ID和/或时钟初始化每个作业中的随机种子:
rngSeed = feature('getpid'); % OR: rngSeed = RandStream.shuffleSeed;
rng(rngSeed);
但这并没有解决问题。在使用shuffleSeed(基于时钟)之前,我还尝试在每个作业中暂停不同的秒数。
所有这些让我觉得parfor在某种程度上混淆了随机种子 - 如果parfor需要确保你在parfor的不同迭代中获得不同的随机数,这是有道理的。
我的问题是,是不是真的如此,我怎样才能解决它并在不同的PBS工作中获得随机性?
编辑运行4个作业,每个作业使用parfor 2名工作人员,我确认虽然每个作业都有自己的种子(设置在parfor之外),但生成的数字在作业之间是相同的(不是跨越迭代) parfor - 由Matlab处理。)
编辑2 尝试@Sam Roberts的建议,我使用以下代码:
matlabpool open local 2
st = RandStream('mlfg6331_64');
RandStream.setGlobalStream(st);
rng('shuffle');
parfor n = 1:4
x=randi(100,[1 10]);
fprintf('%d ',x(:)');
fprintf('\n')
end
matlabpool close
但是我对上述脚本的不同调用仍然得到相同的数字。
答案 0 :(得分:1)
您可能需要考虑使用随机子流,以便在并行运行时获得正确的随机性和可重复性。
RandStream
类允许您创建伪随机数流 - 从此流中提取的数字具有您希望的属性(独立等),如果您控制种子,则还具有可重复性。
但可能并非如此,例如,从流中抽取的每秒或每第四个数字都具有相同的属性。此外,当您使用parfor
时,您无法控制循环迭代的运行顺序,这意味着您将失去可重复性。您可以在parfor
循环中对每个工作人员使用不同的子流。
某些RNG,例如mlfg6331_64
,乘法滞后Fibonacci生成器,或mrg32k3a
,一个组合的多重递归生成器,支持子流 - 独立的流由相同的RNG,但保留相同的伪随机属性,可以单独选择,保持重现性。此外,许多MATLAB和Toolbox函数都有一个选项'UseParallel'
和'UseSubstreams'
,它们会告诉他们自动为你做这些事情。
虽然上面的内容是在MATLAB文档中的技术层面上记录的,但很难找到。统计工具箱文档中有更多解释性指南(如果你问我,应该真的转移到MATLAB)。您可以在线阅读here。
希望有所帮助!