2015-05-26 29 views
5

Immaginate di eseguire un numero di processi in cui desidero impostare un seme globale all'inizio di un programma: ad es.semi di controllo con 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 

naturalmente all'interno di un blocco l1 e l2 sono diversi, ma se eseguire nuovamente il blocco sopra l1 sarà la stessa di prima e l2 sarà la stessa di prima.

Immaginate foo è tempo orribilmente consumando così voglio usare mclapply non lapply, così faccio:

library(parallel) 

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

se corro questo blocco di nuovo io otterrà risultati diversi la prossima volta. Come faccio a produrre lo stesso comportamento con l'impostazione di un seme complessivo con lapply ma utilizzando mclappy. Ho osservato con mclapply doc, ma non sono sicuro perché l'utilizzo di:

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) 

risultato l1 e l2 è lo stesso, che non è quello che voglio ...

+0

È possibile utilizzare 'clusterSetupRNG' ... http://stackoverflow.com/questions/8358098/how-to-set-seed-for-random-simulations-with-foreach-and-domc-packages – user20650

+0

applausi, ma il esempio di libreria (doRNG) sembra datato e non più funzionale e il clusterSetupRNG i Non è proprio quello che ho richiesto, a meno che tu non possa mostrarmi il contrario. – user1320502

+0

Sembra essere cambiato leggermente ... dai un'occhiata a pg tre del ['doRNG reference manual'] (http://cran.r-project.org/web/packages/doRNG/index.html). Oppure usa 'snow' – user20650

risposta

6

Il pacchetto parallel è dotato di supporto speciale per il generatore di numeri casuali "L'Ecuyer-CMRG" che è stato introdotto contemporaneamente allo parallel. È possibile leggere la documentazione per tale sostegno utilizzando:

library(parallel) 
?mc.reset.stream 

Per usarlo, necessario prima di abilitare "L'Ecuyer-CMRG":

RNGkind("L'Ecuyer-CMRG") 

Dopo aver fatto questo, come ad esempio il codice:

set.seed(1) 
mclapply(mylist, foo, mc.cores=3) 
mclapply(mylist, foo, mc.cores=3) 

sarà riproducibile, ma le due chiamate a mclapply restituiranno risultati identici. Questo perché lo stato del generatore di numeri casuali nel processo master non viene modificato chiamando mclapply.

Ho usato il seguente funzione per saltare il numero casuale flussi di usato dagli operai mclapply:

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

È possibile utilizzare questa funzione per ottenere il comportamento che credo si desidera:

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