Parfor循环中生成扰乱的准蒙特卡罗数的问题

时间:2012-04-06 06:55:35

标签: matlab random parallel-processing

我遇到了在parfor循环中生成混乱的准蒙特卡罗数字的问题。

问题在于,当我在parfor循环中生成多组这些数字时,每组中的数字最终都是相同的。我在下面提供了一个非常简单的例子。

D = 3;
M = 1000;
numbers = cell(1,4);

mystream = qrandstream(scramble(sobolset(D),'MatousekAffineOwen'));
myfun = @(x) qrand(mystream,x);

parfor i = 1:4
    numbers{i} = myfun(M);
end

为了演示此问题,运行此代码后,数字{1},数字{2},数字{3}和数字{4}中的数字相同:

>>numbers{1}(1:3,:)
ans =
          0.76          0.05          0.77
          0.33          0.96          0.23
          0.60          0.72          0.52

>> numbers{2}(1:3,:)
ans =
          0.76          0.05          0.77
          0.33          0.96          0.23
          0.60          0.72          0.52

我想知道是否有人能想到解决这个问题的方法。我认为必须有一些我可以做的事情,因为当我使用普通的随机数字流时问题不会发生。

我应该提到,我不可能利用准随机数流的'Skip'或'Leap'属性。原因是我在一个更大的MATLAB程序中使用上面的代码片段,我并行运行...

1 个答案:

答案 0 :(得分:4)

您需要单独调用以对每个并行工作进行加扰。这可以通过在parfor循环中移动qrandstream相关语句来完成,如下所示:

D = 3;
M = 1000;
numbers = cell(1,4);

parfor i = 1:4
    mystream = qrandstream(scramble(sobolset(D),'MatousekAffineOwen'));
    myfun = @(x) qrand(mystream,x);

    numbers{i} = myfun(M);
end

为什么: 尽管MatousekAffineOwen确实具有随机加扰顺序,但MATLAB将准随机序列视为巨大的预定义数组,并且每次需要新样本时都会动态计算样本数据。加扰改变了这个顺序,但是一旦调用了加扰,qrandstream对象的行为就好像它发生了一次。之后,qrandstream是一个确定的数字流。在非并行代码中(或者如果你在没有首先启用matlabpool的情况下使用parfor),这个设置可以在单个qrandstream b / c中正常工作。每次调用qrand时,MATLAB都会在(虚拟)列表中继续工作。

但是在parfor中,所有需要的变量,函数等的副本都会传递给每个worker。结果,每个工作人员获得一个重复的,预先确定的准随机数流,从而在每个工人上产生相同的样本流。顺便说一下,这并不意味着所有数字{i}都具有相同的值。对于大于并行工作者(机器核心)数量的parfor循环范围,将在同一工作程序上进行多循环迭代,从而共享相同的非重复qrandstream。在我的两个核心机器上,您的4个迭代示例代码在numbers{1}==numbers{4}numbers{2}==numbers{3}

中表现出这种行为