2015-05-26 16 views
5

Stellen Sie sich vor, wir machen eine Reihe von Prozessen, bei denen ich am Anfang eines Programms eine Gesamtsumme setzen möchte: z.Steuerung von Seeds mit mclapply

mylist <- list(as.list(rep(NA,3)), as.list(rep(NA,3))) 
foo <- function(x){ for(i in 1:length(x)){ 
         x[[i]] <- sample(100,1) 
         } 
         return(x) 
        } 

# start block 
set.seed(1) 
l1 <- lapply(mylist, foo) 
l2 <- lapply(mylist, foo) 
# end 

natürlich innerhalb eines Blocks l1 und l2 sind unterschiedlich, aber wenn ich den obigen Block laufen wieder l1 werden die gleichen sein wie vorher und l2 wird die gleiche wie zuvor.

Stellen Sie sich vor foo ist schrecklich zeitaufwendig, so will ich mclapply nicht lapply verwenden, so dass ich tun:

library(parallel) 

# start block 
set.seed(1) 
mclapply(mylist , foo, mc.cores = 3) 
mclapply(mylist , foo, mc.cores = 3) 
# end 

Wenn ich diesen Block erneut ausführen werde ich unterschiedliche Ergebnisse das nächste Mal bekommen. Wie erzeuge ich das gleiche Verhalten wie bei der Einstellung eines Gesamtsaats mit lapply, aber unter Verwendung von mclappy. Ich habe durch mclapply doc aussehen, aber ich bin nicht sicher, weil mit:

set.seed(1) 
l1 <- mclapply(mylist , foo, mc.cores = 3, mc.set.seed=FALSE) 
l2 <- mclapply(mylist , foo, mc.cores = 3, mc.set.seed=FALSE) 

Ergebnis in l1 und l2 gleich ist, was nicht, was ich will ...

+0

Sie können 'clusterSetupRNG' ... http://stackoverflow.com/questions/8358098/how-to-set-seed-for-random-simulations-with-foreach-and-domc-packages – user20650

+0

Prost verwenden, aber die Bibliothek (doRNG) Beispiel scheint datiert und nicht mehr funktionsfähig und die ClusterSetupRNG i s nicht wirklich, was ich wollte, es sei denn, du kannst mir etwas anderes zeigen. – user1320502

+0

Scheint sich leicht verändert zu haben ... werfen Sie einen Blick auf Seite 3 des ['doRNG Referenzhandbuchs] (http://cran.r-project.org/web/packages/doRNG/index.html). Oder benutze 'snow' – user20650

Antwort

6

Das parallel Paket kommt mit besonderer Unterstützung für den Zufallsgenerator "L'Ecuyer-CMRG", der gleichzeitig mit parallel eingeführt wurde. Sie können die Dokumentation für diese Unterstützung gelesen werden:

library(parallel) 
?mc.reset.stream 

es nutzen zu können, müssen Sie zuerst "L'Ecuyer-CMRG" aktivieren:

RNGkind("L'Ecuyer-CMRG") 

Danach tun, Code wie:

wird reproduzierbar sein, aber die beiden Aufrufe an mclapply werden identische Ergebnisse zurückgeben. Dies liegt daran, dass der Zustand des Zufallsgenerators im Master-Prozess durch Aufruf von mclapply nicht geändert wird.

Ich habe die folgende Funktion überspringen über die Zufallszahl, die von den mclapply Arbeiter verwendet Ströme:

skip.streams <- function(n) { 
    x <- .Random.seed 
    for (i in seq_len(n)) 
    x <- nextRNGStream(x) 
    assign('.Random.seed', x, pos=.GlobalEnv) 
} 

Sie diese Funktion nutzen zu können, das Verhalten zu bekommen, dass ich glaube, Sie wollen:

set.seed(1) 
mclapply(mylist, foo, mc.cores=3) 
skip.streams(3) 
mclapply(mylist, foo, mc.cores=3) 
skip.streams(3) 
Verwandte Themen