2012-04-06 70 views
2

我有一個問題,在PARFOR循環產生炒擬蒙特卡羅的數字。遇到類似問題炒擬蒙特卡羅數字在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 

我想知道是否有人可以考慮解決這個問題。我認爲必須有一些我可以做的事情,因爲當我使用普通的隨機數字流時,問題不會發生。

我應該指出,這是不可能的,我利用類似的「跳過」或準隨機數流「大躍進」的屬性。其原因是,我在我並行運行較大的MATLAB程序使用的代碼片斷上面...

回答

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中正常工作。MATLAB每次調用qrand時都會繼續工作(虛擬)列表。

但在PARFOR,所有需要的變量,函數等的副本被傳遞到每個員工。結果,每個工人都得到一個重複的,預先確定的準隨機數字流,從而得到每個工人的相同樣本流。順便說一句,這並不意味着所有的數字{i}將具有相同的值。對於大於並行工作器(機器核心)數量的parfor循環範圍,多個循環迭代將在同一個worker上發生,因此共享相同的非重複qrandstream。在我的兩個核心機的4次迭代的示例代碼顯示出與numbers{1}==numbers{4}numbers{2}==numbers{3}

這種行爲