|
|
  |
Простой ГСП на Си |
|
|
Guest_TSerg_*
|
Jan 19 2014, 13:24
|
Guests

|
Использование чисто арифметических методов приведения диапазона ГСП к малым значениям может привести к весьма плачевным результатам в отношении качества их статистических свойств.
Лучше попробовать использование класса ГСП сразу генерирующего псевдо-случайные числа в желаемом амплитудном диапазоне (одновременно, к сожалению будет ограничен и период), к примеру класс LCG-генераторов: Si = ( A*Sii + B ) mod M
К примеру, при M=83, A=2, B=0 получаем простой ГСП с периодом P=M-1=82, амплитудами 1..82:
Sii = 1..82; // Например Sii := 1; --- Si := (Sii << 1) mod M; Sii := Si;
Вместо mod M: while Si<M do Si -= M;
или для данного A=2 даже: if Si > M then Si -= M;
P.S. Немногие удачные сочетания (A;M) c P=M-1: (5;22), (2,29), ..., (6;41), .., (5;167), (2,5,6,8..;227)...
|
|
|
|
Guest_TSerg_*
|
Jan 19 2014, 15:51
|
Guests

|
Цитата(SM @ Jan 19 2014, 18:40)  мои глюки повторяем  while Si>=M do Si -= M; Ну да, очепытка, т.к. все не читал  Ниже-то - правильно.
|
|
|
|
|
Jan 20 2014, 08:24
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Herz @ Jan 20 2014, 02:06)  Мне кажется, результат будет ровно тем же, если часть чисел из распределения с большей амплитудой возвращать в заданный диапазон вычитанием константы по условию. Если считать саму вероятность появления того или иного кода, то тут будет выглядеть все очень просто: допустим, изначально у любого кода вероятность 1/256. Для случая, когда мы используем нахождение остатка, то для части кодов вероятность составит [256/N]/256, а для части ([256/N]-1)/256 ([] - ближайшее большее целое, тут я не знаю как спец-символ математический вставить), первому условию будут подчиняться первые 256 mod N кодов, 0....((256 mod N) - 1), второй части - оставшиеся N-(256 mod N) кодов (если я ничего не попутал). Причиной этому является то, что коды "заворачиваются в диапазон", перекрывая диапазон полностью, меньшее_целое(256/N) раз, а последний "заворот" происходит не полностью, перекрывая лишь первые (256 mod N) кодов, таким образом вероятность выпадения оставшихся кодов уменьшается. В худшем случае вдвое (1/256 и 2/256), ну и чем меньше N, тем меньше различие. UPD: Да, ну а если ГСЧ сразу строится по mod N, то у него изначально вероятности для всех генерируемых кодов равны, если, конечно, он построен правильно, то есть за весь его период каждый код выдается одинаковое кол-во раз.
|
|
|
|
|
Jan 20 2014, 13:01
|

Гуру
     
Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287

|
Цитата(TSerg @ Jan 19 2014, 15:24)  Лучше попробовать использование класса ГСП сразу генерирующего псевдо-случайные числа в желаемом амплитудном диапазоне (одновременно, к сожалению будет ограничен и период), к примеру класс LCG-генераторов: Si = ( A*Sii + B ) mod M
К примеру, при M=83, A=2, B=0 получаем простой ГСП с периодом P=M-1=82, амплитудами 1..82:
Sii = 1..82; // Например Sii := 1; --- Надеюсь, для А=2, В=0 и М=83 правильно записал на Си: Код unsigned char rnd8(void) { static unsigned char seed = 1; unsigned int temp;
temp = seed << 1; if(temp > 83) temp -= 83; seed = (unsigned char)temp;
return temp; } Цитата P.S. Немногие удачные сочетания (A;M) c P=M-1: (5;22), (2,29), ..., (6;41), .., (5;167), (2,5,6,8..;227)... Удачные в каком смысле? И как найдены?
|
|
|
|
Guest_TSerg_*
|
Jan 20 2014, 13:23
|
Guests

|
Сильно извиняюсь.. слегка забегаю в Инет, принимая поздравления за 58 лет  Удачные - в смысле тестирования ( автоматического подбора ) вариантов ГСП. А вообще, есть ряд достаточно объективных тестов DIEHARD, NIST - для ГСП это норма, по другому трудно судить о качестве.
|
|
|
|
Guest_TSerg_*
|
Jan 20 2014, 20:14
|
Guests

|
Спасибо за поздравление, Herz! Однако нам не пристало даже после празднования - праздновать, работаем-да  Поэтому, "special for you" - небольшой эксклюзивный тест, предложенного мной LCG-генератора. LCG/ГСП: M=83, A=2, B=0. Генерация временной последовательности порождает вот такой график: http://shot.qip.ru/00gZ9L-5OPovQkio/(изменение числа инициализации 1..82 породит только фазовый сдвиг от числа 1) Рассматривая график, понимаем, что явно присутствует зависимость ближайших от ближайших значений, а поэтому - устраиваем тест на автокорреляционную функцию: Удостоверяемся, в том, что данный ГСП не может претендовать на крипто-статус. http://shot.qip.ru/00gZ9L-6OPovQkip/С другой стороны, разговор шел, как минимум, о желательности равновероятности чисел в избранном диапазоне. Проверяем гистограмму. http://shot.qip.ru/00gZ9L-5OPovQkir/Что видим? Идеально-равномерное распределение по числам в заданном диапазоне. Т.е. каждое число из диапазона 1..81 встретилось только один раз за цикл. Что и требовалось, как понимаю. P.S. Это всего лишь небольшой экскурс в практику RNG. P.P.S. Не сомневаюсь, что здесь присутствуют специалисты более высокого класса, чем я и мои объяснения они могут трактовать по своему.
|
|
|
|
|
Jan 20 2014, 20:42
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Кстати, на сколько я помню, для любого линейно-конгруэнтного генератора справедливо вот это:
для генератора X(n)=( a*X(n-1) + b ) mod m; длина последовательности P = m тогда (и только тогда), когда:
- b и m взаимно просты (их НОД = 1) - a-1 кратно всем простым делителям m и a-1 кратно 4, если m кратно 4.
то есть, если эти условия выполнены, то a, b и m являются "удачными".
Ну и "претендовать на крипто-статус" линейно-конгруэнтный генератор не может в принципе... Это никак от АКФ не зависит, это зависит от того, на сколько сложно по какому-то количеству отсчетов генератора восстановить его функцию.
|
|
|
|
Guest_TSerg_*
|
Jan 20 2014, 20:53
|
Guests

|
Ну, так я и без претензий - просто сделал попытку объяснить/подобрать наипростейший RNG в диапазоне менее 8 бит с примитивным сохранением стат. значимости. Цитата(SM @ Jan 21 2014, 00:42)  Ну и "претендовать на крипто-статус" линейно-конгруэнтный генератор не может в принципе... Это никак от АКФ не зависит, Ишо как зависит
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|