2013-06-14 18 views
5

tôi thiết lập ví dụ tối thiểu sau đây:MATLAB: Làm thế nào để thiết lập hạt giống ngẫu nhiên trong parfor để sản xuất các kết quả tương tự như nối tiếp cho?

rng(0); 

randseedoffset = random('unid', 10^5) + 1; 

t = cell(10,1); 
for i = 1:10 
    rng(randseedoffset+i); 
    t{i} = random('unid', 1000); 
end 

disp(t); 

Điều này sẽ tạo ra 10 số ngẫu nhiên và lưu trữ chúng trong t. Nó sẽ luôn luôn tạo ra cùng một số ngẫu nhiên đáng tin cậy bởi vì tôi đặt hạt giống với rng trong vòng lặp for.

Nếu bây giờ tôi thay đổi for thành parfor, tôi nhận được kết quả khác nhau! Mặc dù chúng cũng sẽ luôn được tái sản xuất.

Tôi muốn đẩy nhanh tiến độ mã của tôi với parfor và vẫn có được sự chính xác cùng một giống số ngẫu nhiên như với cho ...

Trả lời

6

Ok, tôi chỉ tìm thấy lý do:

MATLAB hỗ trợ các thuật toán genereation số ngẫu nhiên khác nhau . Trong khi ở cài đặt thông thường của phiên bản hiện tại, đây là Misterenne Twister. Khi bạn đi vào vòng lặp parfor, điều này thay đổi thành những gì họ gọi là 'Phương pháp đệ quy kết hợp'.

Vấn đề có thể được cố định bởi explicitely thiết lập các kiểu để 'twister' trong vòng lặp:

parfor i = 1:10 
    rng(randseedoffset+i, 'twister'); 
    t{i} = random('unid', 1000); 
end 
+0

Thú vị. Tôi không thể tìm thấy thay đổi của trình tạo mặc định được đề cập ở bất kỳ đâu trong tài liệu. Bạn có biết điều này có ảnh hưởng đến 'rand' và' randn' không? Nhân tiện, bạn có thể chấp nhận câu trả lời của riêng bạn cho câu hỏi của bạn. – horchler

+0

+1 Rất thú vị. Hãy cẩn thận với hack này trong các bối cảnh mã lớn hơn - có vẻ như các công nhân song song hiện đã được thiết lập để có các trạng thái RNG gần song song và các cuộc gọi 'parfor' hoặc DCT tương lai không đặt lại hạt giống có thể gây lạ các kết quả. Việc tạo trước các số ngẫu nhiên bên ngoài vòng lặp có thể sạch hơn nếu bạn cần tổng số lần lặp lại. –

+0

tôi có hoàn cảnh ngược lại. Bạn có thể trả lời câu hỏi của tôi không: http: //stackoverflow.com/questions/40190243/matlab-generating-random-numbers-in-parfor-or-allel-computing? Noredirect = 1 # comment67680730_40190243 – kyle

0

tôi cảm thấy cần phải xây dựng về vấn đề này. Không đặt lại hạt giống trong vòng lặp parfor và hơn nữa không sử dụng thuật toán Mersenne Twister song song (bạn sẽ nhận được kết quả kém độc lập về thống kê).

Lý do bạn nhận được kết quả khác nhau là do thuật toán khác nhau do các thuộc tính thống kê mà các số này nên duy trì. Trong một hồ bơi song song MATLAB sẽ thiết lập thuật toán 'combRecursive' và thiết lập một subStream khác nhau trên mỗi nhân viên, do đó, đối với các số ngẫu nhiên, bạn nên thực hiện. Hơn nữa, parfor vòng lặp không đảm bảo —

  • Thứ tự mà các vòng tiến hành,
  • mà người lao động sẽ được thực hiện từng mảnh, hoặc
  • bao nhiêu lần lặp được thực hiện trên mỗi công nhân.

Do đó, việc tạo các số ngẫu nhiên trong các vòng parfor thường sẽ không trả về cùng số ngẫu nhiên ngay cả với cùng một trạng thái trên mỗi công nhân. Thay vì tạo ra một RandStream với subStreams của thuật toán combRecursive, thiết lập các dòng toàn cầu trên mỗi công nhân trong một khối spmd, sau đó tạo ra các con số trên mỗi công nhân trong một khối spmd:

p = gcp; % Get or open a pool 

numWork = p.NumWorkers; % Get the number of workers 

s = RandStream.create('mrg32k3a','NumStreams',numWork,... 
    'CellOutput',true); % create numWork independent streams 

n = 200; % number of values to generate on each worker 
spmd 
    RandStream.setGlobalStream(s{labindex}); 
    x = rand(1,n); 
end 

% I generate row vectors as the Composite matrix x will return a 
% comma-separated list using the syntax, x{:}, which can then be 
% concatenated into a single vector: 
randVals2 = [x{:}]'; 
+0

rất thú vị. parfor dường như để có được những điều lộn xộn khi tôi chuyển từ cho vòng lặp để parfor: bạn có thể trả lời câu hỏi của tôi: http://stackoverflow.com/questions/40190243/matlab-generating-random-numbers-in-parfor-or-parallel- computer? noredirect = 1 # comment67680730_40190243 – kyle

0

thử điều này:

p = gcp; % Get or open a pool 

numWork = p.NumWorkers; % Get the number of workers 

stream = RandStream('mrg32k3a','seed',mydata.seed); 
RandStream.setGlobalStream(stream); 

% s = RandStream.create('mrg32k3a','NumStreams',numWork,'CellOutput',true,'Seed',mydata.seed); % create numWork independent streams 

n = 200; % number of values to generate on each worker 
spmd 
RandStream.setGlobalStream(stream); 
x = rand(1,n); 
end 
Các vấn đề liên quan