Воспроизвести рандомы

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Воспроизвести рандомы

Сообщение Дож » 25.05.2016 03:06:54

Есть программа на паскале. Она использует генератор случайных чисел (стандартные функции Random). Задача: сохранить из этой программы такую информацию, чтобы потом можно было бы воспроизвести ту же последовательность случайных чисел в этой же программе.

Проблема: информация должна быть кроссплатформенной, т.е. в одной ОС её сохранили, а на другой по ней запустили программу. Из-за этого условия я не уверен, что достаточно будет сохранить RandSeed, — насколько RandSeed и Random кроссплатформенны?

Сохранять чиселки с каждого вызова Random очень не хочется.

Предполагается, что программа для всех платформ компилируется одной версией fpc.

Вариант «Напиши и используй свой рандом» не предлагать.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 673
Зарегистрирован: 12.10.2008 16:14:47

Re: Воспроизвести рандомы

Сообщение скалогрыз » 25.05.2016 03:44:02

Дож писал(а):Из-за этого условия я не уверен, что достаточно будет сохранить RandSeed, — насколько RandSeed и Random кроссплатформенны?

кроссплатформенный, т.к. реализован в RTL-е, и не зависит от системных функций.
Единственная тонкость, что сама реализация random-a может в RTL-е поменяться в очередной версии FPC (в баг трекере регулярно появляются более рандомные рандомы() :D)
но в таком случае достаточно будет скопировать нужную реализацию.

Randseed - наше всё!
скалогрыз
долгожитель
 
Сообщения: 1645
Зарегистрирован: 03.09.2008 02:36:48

Re: Воспроизвести рандомы

Сообщение Дож » 25.05.2016 04:17:46

Как раз за версии fpc не боюсь, так как собирать буду одной.

А 32/64-bit, little/big endian — тоже не влияют? Например, я при переходе с little на big свапну части, а по факту в реализации используется последовательность байт…
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 673
Зарегистрирован: 12.10.2008 16:14:47

Re: Воспроизвести рандомы

Сообщение скалогрыз » 25.05.2016 06:12:56

Дож писал(а):А 32/64-bit, little/big endian — тоже не влияют?

Не влияют. Как пишет документация на рандом, в основе математический алгоритм Вихрь Мерсена
Алгоритм математический, на конкретную платформу не привязан.
В реализации каких-либо платформо специфичных хаков нет (такие платформо-привязанные хаки обычно встречаются в игровых движках)

Если пугают операции вроде shr и shl, то на самом деле они дают одинаковый результат в big-end и little-end платформах (увеличивая/уменьшая число). Внутренняя реализация привязана к 32-битным числам на любой платформе (включая dos).
например random(int64) даже на 64-х битной платформе это двойной вызов к random(int32)

...главное Randseed между little и big endian правильно передать :) предлагаю в текстовой форме!
скалогрыз
долгожитель
 
Сообщения: 1645
Зарегистрирован: 03.09.2008 02:36:48

Re: Воспроизвести рандомы

Сообщение sign » 25.05.2016 06:31:18

Написать самому.
Дело не сложное, зато будет гарантия тому, что всегда будет одна и та же последовательность, при одних исходных данных, засылаемых в генератор.

Добавлено спустя 3 минуты 29 секунд:
Скачайте себе Кнута, если нет.
Во втором томе подробнейшим образом разобраны всяческие алгоритмы генерации случайных чисел.
sign
энтузиаст
 
Сообщения: 873
Зарегистрирован: 30.08.2009 09:20:53

Re: Воспроизвести рандомы

Сообщение Дож » 25.05.2016 10:54:42

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

Предположим, я так и сделал. Допустим, в программе вызывается функция f из некоторой сторонней библиотеки A, а внутри функции используется стандартный Random. Если всё оставить нетронутым, то этот вызов f может порушить детерменированность. Что делать? Бегать по всем библиотекам и подменять Random на DojRandom, добавляя зависимостью свою модуль? (Так себе вариант.) Написать свой system.pas, постоянно пересобирать fpc rtl под него? (Тоже так себе вариант.)
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 673
Зарегистрирован: 12.10.2008 16:14:47

Re: Воспроизвести рандомы

Сообщение zub » 25.05.2016 11:35:36

>>Вариант «Напиши и используй свой рандом» не предлагать.
Это единственный 100% вариант. Т.к. несмотря на то что random кроссплатформенный, гарантии того что на каконить платформе в какойнить библиотеке гденибудь он не используется нет.
Сохранили randseed, а TVasyaSuperButton на платформе win16 вызывает стандартный random при нажатии на эту суперкнопку из какихто хитрых соображений - последовательность нарушится...
zub
долгожитель
 
Сообщения: 2257
Зарегистрирован: 14.11.2005 23:51:26

Re: Воспроизвести рандомы

Сообщение Дож » 25.05.2016 11:58:11

TVasyaSuperButton на платформе win16 вызывает стандартный random при нажатии на эту суперкнопку из какихто хитрых соображений - последовательность нарушится...

Это как раз не сильно беспокоит, я хочу записать все «входные данные» в программу, соответственно нажатие на эту суперкнопку произойдёт в тот же момент и дёрнет ту же чиселку, не нарушив последовательность. А вот помнить про свой рандом и лезть постоянно во все библиотеки и что-то в них править — сомнительная практика, не фанат такого.

Сохранили randseed

Во, расскажите лучше подробнее как сохранять по науке :) Как число или как последовательность байт в памяти? Я в коде вижу shr и shl и прибитые гвоздём константы (т.е. как число?)
Код: Выделить всё
// rtl/inc/system.inc
function mtwist_u32rand: cardinal;
begin
  if (RandSeed<>OldRandSeed) or
     (mt_index=MTWIST_N+1) then
    begin
      mtwist_init(RandSeed);
      { Detect resets of randseed

        This will break if someone coincidentally uses not(randseed) as the
        next randseed, but it's much more common that you will reset randseed
        to the same value as before to regenerate the same sequence of numbers
      }
      RandSeed:=not(RandSeed);
      OldRandSeed:=RandSeed;
    end;
  if mt_index=MTWIST_N then
    mtwist_update_state;
  result:=mt_state[mt_index];
  inc(mt_index);
  result:=result xor (result shr 11);
  result:=result xor ((result shl 7) and cardinal($9D2C5680));
  result:=result xor ((result shl 15) and cardinal($EFC60000));
  result:=result xor (result shr 18);
end;
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 673
Зарегистрирован: 12.10.2008 16:14:47

Re: Воспроизвести рандомы

Сообщение zub » 25.05.2016 12:19:44

Как не сохраняй устанавливаться та он будет уже в виде cardinal
Код: Выделить всё
procedure mtwist_init(seed: cardinal);
var
  i: longint;
begin
  mt_state[0]:=seed;
  for i:=1 to MTWIST_N-1 do
    mt_state[i]:=cardinal(1812433253) * (mt_state[i-1] xor (mt_state[i-1] shr 30)) + i;
   { still need to update the state }
  mt_index:=MTWIST_N;
end;

Если сохранять бинарно - то фиксировать endian при записи, например всегда писать как little и свапить по нужде на платформе где читается, если она big.
Если текстом, то вообще заморачиваться ничем ненадо.

>>А вот помнить про свой рандом и лезть постоянно во все библиотеки и что-то в них править — сомнительная практика, не фанат такого.
В программе так много мест с рандомом который нужно сохранять? Если разделить на свой\системный и выделить нужные места - то лазить по чужим библиотекам не придется.
простейший рандом выглядит както так:
Код: Выделить всё
...
randseed:integer{cardinal};
...
procedure MyRandom:integer{cardinal};
begin
           randseed:=randseed * $343fd;
           randseed:=randseed + $269ec3;
           result:=randseed;
end;
zub
долгожитель
 
Сообщения: 2257
Зарегистрирован: 14.11.2005 23:51:26

Re: Воспроизвести рандомы

Сообщение Дож » 25.05.2016 12:32:55

Ок, спасибо, попробую сохранять seed.

Если разделить на свой\системный и выделить нужные места - то лазить по чужим библиотекам не придется.

На самом деле даже в своём коде не очень хочу использовать свой рандом, чтобы не плодить библиотек и зависимостей :) Если прокатит с RandSeed, то это реально очень упростит поддержку кода.

Для надёжности, возможно, добавлю сохранение «контрольных рандомов» (вызванный в определённые моменты Random специально для подтверждения идентичности воспроизводимой последовательности).

простейший рандом выглядит както так:

Вот что-что, а клепать вилосипеды я точно не боюсь :)
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 673
Зарегистрирован: 12.10.2008 16:14:47

Re: Воспроизвести рандомы

Сообщение Cheb » 28.05.2016 19:57:47

Вариант «Напиши и используй свой рандом» не предлагать.

Скопипасть фрипаскалевский рандом в собственный модуль. Тогда эту копию будут использовать только твои модули.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 590
Зарегистрирован: 06.06.2005 15:54:34

Re: Воспроизвести рандомы

Сообщение Ism » 29.05.2016 00:53:43

Какой смысл в рандоме если его надо повторять ?
Тогда уж создать файл с шумом и подкладывать, кроссплатформенно, надежно :)
Ism
энтузиаст
 
Сообщения: 900
Зарегистрирован: 06.04.2007 17:36:08

Re: Воспроизвести рандомы

Сообщение Дож » 29.05.2016 01:16:57

Cheb писал(а):
Вариант «Напиши и используй свой рандом» не предлагать.

Скопипасть фрипаскалевский рандом в собственный модуль. Тогда эту копию будут использовать только твои модули.

А как быть с НЕ моими модулями, которые используются в программе и используют рандом?

Какой смысл в рандоме если его надо повторять ?
Тогда уж создать файл с шумом и подкладывать, кроссплатформенно, надежно

Мне не нужен невоспроизводимый рандом, у меня не криптография.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 673
Зарегистрирован: 12.10.2008 16:14:47

Re: Воспроизвести рандомы

Сообщение Mirage » 29.05.2016 01:33:53

Дож писал(а):Предположим, я так и сделал. Допустим, в программе вызывается функция f из некоторой сторонней библиотеки A, а внутри функции используется стандартный Random.


А если там Randomize() используется?
Mirage
энтузиаст
 
Сообщения: 752
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Воспроизвести рандомы

Сообщение Дож » 29.05.2016 01:38:44

Mirage писал(а):
Дож писал(а):Предположим, я так и сделал. Допустим, в программе вызывается функция f из некоторой сторонней библиотеки A, а внутри функции используется стандартный Random.


А если там Randomize() используется?

В выбранном пока что решении — я узнаю по контрольным рандомам, что что-то пошло не так и буду смотреть что именно. А так — это тоже проблема, конечно.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 673
Зарегистрирован: 12.10.2008 16:14:47

След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru