2011-12-02 32 views
18

Tôi cần thực hiện một số mô phỏng và cho mục đích gỡ lỗi Tôi muốn sử dụng set.seed để nhận được kết quả tương tự. Dưới đây là ví dụ về những gì tôi đang cố gắng để làm:Làm thế nào để đặt hạt giống cho các mô phỏng ngẫu nhiên với các gói foreach và doMC?

library(foreach) 
library(doMC) 
registerDoMC(2) 

set.seed(123) 
a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
set.seed(123) 
b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 

Objects ab nên giống hệt nhau, ví dụ: sum(abs(a-b)) nên không, nhưng đây không phải là trường hợp. Tôi đang làm điều gì đó sai, hoặc tôi đã vấp vào một số tính năng?

Tôi có thể tái tạo điều này trên hai hệ thống khác nhau với R 2.13 và R 2.14

Trả lời

17

tôi câu trả lời mặc định được sử dụng là "tốt thì không làm điều đó" (sử dụng foreach) như các gói snow thực hiện điều này (đáng tin cậy!) cho bạn.

Nhưng khi @Spacedman chỉ ra, Renaud mới doRNG là những gì bạn đang tìm kiếm nếu bạn muốn ở lại với gia đình doFoo/foreach.

Chìa khóa thực sự mặc dù là một cuộc gọi kiểu clusterApply để có được hạt giống đặt trên tất cả các nút. Và trong một thời trang phối hợp giữa các dòng suối. Oh, và tôi đã đề cập rằng snow bởi Tierney, Rossini, Li và Sevcikova đã làm điều này cho bạn trong gần một thập kỷ?

Edit: Và trong khi bạn không hỏi về snow, cho đầy đủ ở đây là một ví dụ từ dòng lệnh:

[email protected]:~$ r -lsnow -e'cl <- makeSOCKcluster(c("localhost","localhost"));\ 
     clusterSetupRNG(cl);\ 
     print(do.call("rbind", clusterApply(cl, 1:4, \ 
              function(x) { stats::rnorm(1) })))' 
Loading required package: utils 
Loading required package: utils 
Loading required package: rlecuyer 
      [,1] 
[1,] -1.1406340 
[2,] 0.7049582 
[3,] -0.4981589 
[4,] 0.4821092 
[email protected]:~$ r -lsnow -e'cl <- makeSOCKcluster(c("localhost","localhost"));\ 
     clusterSetupRNG(cl);\ 
     print(do.call("rbind", clusterApply(cl, 1:4, \ 
              function(x) { stats::rnorm(1) })))' 
Loading required package: utils 
Loading required package: utils 
Loading required package: rlecuyer 
      [,1] 
[1,] -1.1406340 
[2,] 0.7049582 
[3,] -0.4981589 
[4,] 0.4821092 
[email protected]:~$ 

Edit: Và cho đầy đủ, đây là ví dụ của bạn kết hợp với những gì có trong các tài liệu cho doRNG

> library(foreach) 
R> library(doMC) 
Loading required package: multicore 

Attaching package: ‘multicore’ 

The following object(s) are masked from ‘package:parallel’: 

    mclapply, mcparallel, pvec 

R> registerDoMC(2) 
R> library(doRNG) 
R> set.seed(123) 
R> a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
R> set.seed(123) 
R> b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
R> identical(a,b) 
[1] FALSE      ## ie standard approach not reproducible 
R> 
R> seed <- doRNGseed() 
R> a <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) } 
R> b <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) } 
R> doRNGseed(seed) 
R> a1 <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) } 
R> b1 <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) } 
R> identical(a,a1) && identical(b,b1) 
[1] TRUE      ## all is well now with doRNGseed() 
R> 
+0

Cảm ơn ví dụ về tuyết. Tôi không thành thạo về sự phức tạp của lập trình song song trong R, vì vậy tôi bắt đầu sử dụng 'foreach' để chuyển đổi không đau từ mã không song song thành song song. Tôi biết rằng tôi đã bỏ lỡ một cái gì đó. – mpiktas

+2

Vâng, đó là lý do tại sao tất cả chúng ta bắt đầu nhiều năm trước với tuyết khi việc chuyển đổi từ các hàm chuẩn * apply() sang các hàm song song rất dễ dàng :) –

4

Gói doRNG có sử dụng cho bạn không? Tôi nghi ngờ vấn đề của bạn là do hai luồng cả splatting vector ngẫu nhiên giống:

http://ftp.heanet.ie/mirrors/cran.r-project.org/web/packages/doRNG/index.html

+0

Cám ơn câu trả lời của bạn, tôi thực sự có thể đánh dấu cả hai như là một câu trả lời, nhưng câu trả lời của Dirk thì rộng hơn. Tôi đã upvoted câu trả lời của bạn tuy nhiên, vì nó có đủ thông tin để giải quyết vấn đề của tôi. – mpiktas

2

đối với vòng phức tạp hơn, bạn có thể phải bao gồm set.seed() bên của vòng lặp for:

library(foreach) 
library(doMC) 
registerDoMC(2) 
library(doRNG) 

set.seed(123) 
a <- foreach(i=1:2,.combine=cbind) %dopar% { 
    create_something <- c(1, 2, 3) 
    rnorm(5) 
} 
set.seed(123) 
b <- foreach(i=1:2,.combine=cbind) %dopar% { 
    create_something <- c(4, 5, 6) 
    rnorm(5) 
} 
identical(a, b) 
# FALSE 

so

a <- foreach(i=1:2,.combine=cbind) %dopar% { 
    create_something <- c(1, 2, 3) 
    set.seed(123) 
    rnorm(5) 
} 
b <- foreach(i=1:2,.combine=cbind) %dopar% { 
    create_something <- c(4, 5, 6) 
    set.seed(123) 
    rnorm(5) 
} 
identical(a, b) 
# TRUE 
6

Sử dụng set.seed(123, kind = "L'Ecuyer-CMRG") cũng hiện các trick và không đòi hỏi một gói bổ sung:

set.seed(123, kind = "L'Ecuyer-CMRG") 
a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
identical(a,b) 
# TRUE 
+0

Câu trả lời này đơn giản hơn câu trả lời của Dirk Eddulbuettel. Nó có bất kỳ hạn chế nào không? –

Các vấn đề liên quan