2015-05-26 2 views
5

Представьте, что мы выполняем ряд процессов, в которых я хочу установить одно общее семя в начале программы: например,контроль семян с помощью 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 

конечно в пределах блока l1 и l2 различны, но если я снова запустить выше блок l1 будет таким же, как и раньше, и l2 будет таким же, как и раньше.

Представьте foo ужасно много времени, поэтому я хочу, чтобы использовать mclapply не lapply, так что я:

library(parallel) 

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

Если я запускаю этот блок снова я получить разные результаты в следующий раз. Как мне произвести то же поведение, что и при установке одного общего семени с lapply, но с использованием mclappy. Я просмотрел mclapply документ, но я не уверен, потому что с помощью:

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) 

результат в l1 и l2 быть тем же самым, что не то, что я хочу ...

+0

Вы можете использовать 'clusterSetupRNG' ... http://stackoverflow.com/questions/8358098/how-to-set-seed-for-random-simulations-with-foreach-and-domc-packages – user20650

+0

ура, но библиотека (doRNG), кажется, устарела и больше не работает, а clusterSetupRNG i на самом деле не совсем то, что я просил, если вы не можете показать мне другое. – user1320502

+0

Кажется, что вы немного изменились ... посмотрите на pg три справочника ['doRNG reference manual'] (http://cran.r-project.org/web/packages/doRNG/index.html). Или используйте 'snow' – user20650

ответ

6

Пакет parallel поставляется с особой поддержкой для генератора случайных чисел «L'Ecuyer-CMRG», который был введен одновременно с parallel. Вы можете прочитать документацию для этой поддержки с помощью:

library(parallel) 
?mc.reset.stream 

Чтобы его использовать, сначала нужно включить "L'Ecuyer-CMRG":

RNGkind("L'Ecuyer-CMRG") 

После выполнения этого кода, такие как:

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

будет воспроизводимым, но два обращения к mclapply вернут одинаковые результаты. Это связано с тем, что состояние генератора случайных чисел в основном процессе не изменяется, вызывая mclapply.

Я использовал следующую функцию, чтобы пропускать через случайное число потоков используется mclapply работников:

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

Вы можете использовать эту функцию, чтобы получить поведение, что я думаю, что вы хотите:

set.seed(1) 
mclapply(mylist, foo, mc.cores=3) 
skip.streams(3) 
mclapply(mylist, foo, mc.cores=3) 
skip.streams(3) 
Смежные вопросы