Могу ли я иметь несколько независимых генераторов случайных чисел в R, как в C++?

У меня есть много независимых случайных процессов (скажем, процессов прибытия), которые требуют, чтобы я генерировал случайные числа. Я хочу использовать общие случайные числа для каждого из этих процессов, чтобы можно было сравнить, как работают разные политики при управлении этими политиками.

Я хочу, чтобы процесс A управлялся генератором A (используя начальное число A) Я хочу, чтобы процесс B управлялся генератором B (используя начальное число B) ..

и так далее.

Возможно ли это реализовать в R. Я не могу найти никого, кто это сделал. Я пытался. Простите, если это повторяющийся вопрос.

Спасибо

Джек


person Jak Marshall    schedule 04.04.2014    source источник
comment
Поддержка С++ 11 в компиляторе?   -  person Yakk - Adam Nevraumont    schedule 04.04.2014
comment
Почему бы вам заранее не сгенерировать все свои случайные числа, используя разные семена? A и B могут иметь политику выбора чисел из сгенерированного набора без повторений (нечетные/четные индексы, где шансы имеют одно начальное число, а четные - другое, последовательные и т. д.). Когда у вас закончатся числа, если это проблема, сгенерируйте больше.   -  person mockinterface    schedule 04.04.2014
comment
Я думаю, что это лучший подход, который у меня есть. Может быть неэффективно, что я генерирую и храню гораздо больше чисел, чем мне когда-либо понадобится, но если нет возможности предложить «несколько независимых стопок» случайных чисел, мне придется подумать об умной реализации предложения mockinterface. . Спасибо за ваши быстрые ответы.   -  person Jak Marshall    schedule 04.04.2014
comment
Если вы используете разные ядра, см.: stats.stackexchange.com/q/3532/229.   -  person James    schedule 04.04.2014
comment
Поскольку R действительно делает только одну вещь за раз, все, что вам нужно сделать, это установить желаемое начальное значение перед вызовом ваших функций A и B . Но позвольте мне спросить: как только вы установите начальное число, последовательность чисел будет определена. Какая разница, рисуете ли вы (в одном и том же порядке) одну или несколько последовательностей псевдослучайных чисел?   -  person Carl Witthoft    schedule 04.04.2014
comment
Я хотел бы сравнить производительность различных политик. С этой целью я хотел бы, чтобы проблемы, видимые каждой из политик, были как можно более похожими, чтобы уменьшить шум и создать «стандартный» набор проблем. Из-за характера выборки, основанного на политике, и конечного временного горизонта мне никогда не нужно использовать значения (Horizon_Length*Number_of_sources), поскольку я делаю выборку только (Horizon_Length) раз. Поэтому вместо того, чтобы сохранять их заранее, что, безусловно, сработает, но потребует много места для хранения, я просто хочу получить номер, который мне нужен, только тогда, когда я этого хочу, без необходимости хранить все.   -  person Jak Marshall    schedule 04.04.2014


Ответы (2)


Это то, что я иногда хотел сделать - и еще не придумал ничего лучше, чем следующий кладж (который действительно полезен, только если вы используете только 1 или 2 разных случайных распределения, поскольку вам нужно написать функция для каждого:

#Make a list of seeds - generalises to mkore than 2
seed <- list(NA,NA)
set.seed(1)
seed[[1]] <- .Random.seed
set.seed(2)
seed[[2]] <- .Random.seed

my_runif <- function(...,which.seed=1)
{
  .Random.seed <<- seed[[which.seed]]
  x <-runif(...)
  seed[[which.seed]] <<- .Random.seed
  x
}

##Print some data for comparison
> set.seed(1); runif(10)
 [1] 0.26550866 0.37212390 0.57285336 0.90820779 0.20168193 0.89838968 0.94467527 0.66079779 0.629114040.06178627
> set.seed(2); runif(10)
 [1] 0.1848823 0.7023740 0.5733263 0.1680519 0.9438393 0.9434750 0.1291590 0.8334488 0.4680185 0.5499837

#Test
> my_runif(1,which.seed=1)
[1] 0.2655087
> my_runif(1,which.seed=1)
[1] 0.3721239
> my_runif(1,which.seed=1)
[1] 0.5728534
> my_runif(1,which.seed=2)
[1] 0.1848823
> my_runif(1,which.seed=1)
[1] 0.9082078

Я полагаю, что <<- сломается, если вы вызовете my_runif из другой функции.

fortunes::fortune("<<-")

ETA: следующее может быть более надежным

my_runif <- function(...,which.seed=1)
{
  assign(".Random.seed", seed[[which.seed]], envir = .GlobalEnv)
  x <-runif(...)
  seed <- seed #Bring into local envir
  seed[[which.seed]] <- .Random.seed
  assign("seed", seed, envir = .GlobalEnv)
  x
}
person Miff    schedule 04.04.2014

Что ж, хорошая новость заключается в том, что вы уже это делаете — см. help(RNGkind):

 The currently available RNG kinds are given below.  ‘kind’ is
 partially matched to this list.  The default is
 ‘"Mersenne-Twister"’.

 ‘"Wichmann-Hill"’ [...]

 ‘"Marsaglia-Multicarry"’: [...]

 ‘"Super-Duper"’: [...]

 ‘"Mersenne-Twister"’: [...]

 ‘"Knuth-TAOCP-2002"’: [...]

 ‘"Knuth-TAOCP"’: [...]

 ‘"L'Ecuyer-CMRG"’: 

 ‘"user-supplied"’: Use a user-supplied generator.  See
      ‘Random.user’ for details.

а user-supplied позволяет использовать свои собственные.

И для N (0,1) у вас также есть

 ‘normal.kind’ can be ‘"Kinderman-Ramage"’, ‘"Buggy
 Kinderman-Ramage"’ (not for ‘set.seed’), ‘"Ahrens-Dieter"’,
 ‘"Box-Muller"’, ‘"Inversion"’ (the default), or ‘"user-supplied"’.
 (For inversion, see the reference in ‘qnorm’.)  [...]

Для параллельной работы см. (отличную) виньетку пакета parallel, поставляемого с R. Существуют существующие генераторы для нескольких потоков/ядер/... и т. д.

И последнее, но не менее важное: R, конечно, расширяемый, и вы можете, например, использовать Rcpp, где у нас есть несколько сообщений о случайных числах на сайте Rcpp Gallery.

person Dirk Eddelbuettel    schedule 04.04.2014