Установить случайное семя R с помощью хэша - PullRequest
0 голосов
/ 14 сентября 2018

R предоставляет функцию set.seed для заполнения ГСЧ целым числом. Стандартный пакет digest может хэшировать объекты с различными алгоритмами хэширования и может выводить ASCII-представление хэша или вектора необработанных байтов, но не может произвести целое число. Как я могу использовать хеш произвольного объекта для заполнения ГСЧ?

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Похоже, set.seed - единственный интерфейс для заполнения RNG R. И целые числа R всегда 32-битные, даже на 64-битных машинах. Поэтому нам нужно использовать 32-битный хеш. digest предоставляет несколько 32-битных хешей, но raw = TRUE игнорируется для всех них, поэтому нам нужно выполнить некоторые строковые операции с шестнадцатеричным представлением хеша. Собираем все вместе:

set.seed.obj = function(x)
   {x = as.raw(as.hexmode(substring(
        digest::digest(x, algo = "xxhash32"),
        c(1, 3, 5, 7),
        c(2, 4, 6, 8))))
    x = rawConnection(x)
    set.seed(readBin(x, "int"))
    close(x)}

set.seed.obj("hello world")
print(rnorm(3))
set.seed.obj("goodbye world")
print(rnorm(3))
set.seed.obj("hello world")
print(rnorm(3))

Удивительно, но первое присвоение x необходимо: вызов rawConnection для выражения as.raw(...) напрямую приводит к Error in rawConnection…: invalid 'description' argument. Очевидно, что сбой R при попытке создать строковое представление аргумента для атрибута description соединения.

0 голосов
/ 14 сентября 2018

Интерфейс для set.seed() действительно задан и принимает только целое число. Это дизайнерское решение, и оно неплохое: set.seed(123) легко записать, а впоследствии гарантированное поведение гарантировано.

Если вы действительно копаете глубже, в множестве (!!) RNG, используемых R., есть намного больше . Есть разные, вы можете переключаться между ними, и даже по умолчанию вы получаете (насколько я помню) разные для равномерного и нормального розыгрыша. Тем не менее, интерфейс заполнения охватывает оба.

А на уровне C в игре присутствует гораздо более крупная (более сложная) структура данных.

Теперь мой дайджест посылки. Он действительно работает с произвольными объектами R, возвращающими строковые объекты. Таким образом, это не помогает с set.seed(), так как эти символы не являются целыми числами. Но вы можете, например, установить промежуточный слой, где вы еще раз «отобразите» эти строки символов на целые числа.

Короче говоря, я думаю, вам нужно немного переосмыслить свой дизайн.

Редактировать: По запросу, даже если я думаю, что это не способ сделать это:

 R> c2i <- function(s) sum(as.integer(charToRaw(s)))
 R> c2i(digest(42))
 [1] 2332
 R> set.seed(c2i(digest(42)))
...