![]() |
|
![]() ![]() ![]() |
|
stab |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: нет Всего: 48 |
Вот реализация Random(int) в Delphi 6:
считаем что символ PIC НЕопределен, на сколько я понял это под Kylix (GOT - global offset table, вроде это понятие из области unix-подобных систем) {$IFDEF PIC} function GetGOT: LongWord; export; begin asm MOV Result,EBX end; end; {$ENDIF} procedure _RandInt; asm { ->EAX Range } { <-EAX Result } PUSH EBX {$IFDEF PIC} PUSH EAX CALL GetGOT MOV EBX,EAX POP EAX MOV ECX,[EBX].OFFSET RandSeed IMUL EDX,[ECX],08088405H INC EDX MOV [ECX],EDX {$ELSE} // обнуляем EBX, зачем ![]() XOR EBX, EBX // перемножаем RandSeed и 134775813 (08088405H) IMUL EDX,[EBX].RandSeed,08088405H // увеличиваем на еденицу старшее двойное слово результата умножения INC EDX // сохраняем старшее двойное слово результата умножения как новый RandSeed MOV [EBX].RandSeed,EDX {$ENDIF} // умножаем преданный в качестве параметра диапазон на старшее двойное слово предыдущего результата MUL EDX // берем старшее двойное слово от предыдущего умножения, это и будет результат MOV EAX,EDX POP EBX end; знающие люди напишите формулу ![]() у мя не выходит, не дружен я с математикой ![]() -------------------- 6, 6, 6 - the number of the beast. |
|||
|
||||
maxim1000 |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 33 Всего: 110 |
часто в качестве m берут что-то вроде 2^32 по-моему, это совсем неплохо для периода
это был бы в точности тот алгоритм, который и предполагается, если последние две операции выполнялись не над старшим dword, а над младшим. в этом случае a=134775813, b=1, m=2^32 если все же операции выполнять над старшим словом, может получиться такая наприятная ситуация: пусть RandSeed=1 (должно же такое бывать) тогда 134775813*RandSeed=134775813 старшее dword результата произведения равно 0 тогда RandSeed=1 к сожалению, я не знаю этого ассемблера и ориентируюсь только по комментариям... -------------------- qqq |
||||
|
|||||
stab |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: нет Всего: 48 |
хм, я не много ошибся в разборе поцедуры. После первого умножения идет работа с младшим двойным словом. Вот верный вариант:
procedure _RandInt; asm { ->EAX Range } { <-EAX Result } PUSH EBX {$IFDEF PIC} PUSH EAX CALL GetGOT MOV EBX,EAX POP EAX MOV ECX,[EBX].OFFSET RandSeed IMUL EDX,[ECX],08088405H INC EDX MOV [ECX],EDX {$ELSE} // обнуляем EBX, зачем , можно просто IMUL EDX,[RandSeed],08088405H XOR EBX, EBX // перемножаем RandSeed и 134775813 (08088405H) IMUL EDX,[EBX].RandSeed,08088405H // увеличиваем на еденицу младшее двойное слово результата умножения INC EDX // сохраняем младшее двойное слово результата умножения как новый RandSeed MOV [EBX].RandSeed,EDX {$ENDIF} // умножаем преданный в качестве параметра диапазон на младшее двойное слово предыдущего результата MUL EDX // берем старшее двойное слово от предыдущего умножения, это и будет результат MOV EAX,EDX POP EBX end; Это сообщение отредактировал(а) cully - 22.3.2003, 03:45 -------------------- 6, 6, 6 - the number of the beast. |
|||
|
||||
stab |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: нет Всего: 48 |
и еще вопрос в догонку: чем обоснован выбор a=134775813?
-------------------- 6, 6, 6 - the number of the beast. |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 33 Всего: 110 |
От этого числа (в большей степени, чем от b) зависит равномерность распределения выходных значений. Если немного попреобразовывать эту формулу, можно прийти к линейному регистру сдвига:
x(n)=a*x(n-1)+b x(n+1)=a*x(n)+b b=x(n)-a*x(n-1) x(n+1)=a*x(n)+x(n)-a*x(n-1) ----------------------------------- x(n+1)=(a+1)*x(n)-a*x(n-1) [надеюсь я ничего не напутал ![]() (только теперь надо задавать два начальных значения) Линейные регистры сдвига довольно хорошо изучены. Известны зависимости некоторых показателей качества генерируемых ними последовательностей от коэффициентов линейного рагистра. Нам в институте дали только способ определения периода с помощью характеристических полиномов регистра, а показателей качества псевдослучайных последовательностей дали около десятка. Думаю, обоснование выбора подобных чисел можно найти в книгах по криптологии или связанным с ней дисциплинам... P.S. А первое, что приходит в голову - a не должно быть делителем m (в нашем случае оно просто должно быть нечетным), но это - лишь первый шаг для сужения области поиска подходящих чисел -------------------- qqq |
|||
|
||||
stab |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: нет Всего: 48 |
ок, все понятно, но вернемся к вопросу топика
![]() есть у меня большая выборка значений (100 000) и что делать дальше? как построить гипотезу о вожмоном устройстве датчика? ... и предсказать следуещее 100 001 значение ? ![]() Это сообщение отредактировал(а) cully - 23.3.2003, 10:34 -------------------- 6, 6, 6 - the number of the beast. |
|||
|
||||
maxim1000 |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 33 Всего: 110 |
наконец-то проделал несколько экспериментов
вот некоторые результаты: У генератора x(n+1)=a*x(n)+b есть неприятная особенность: на каждом шаге меняется четность. (это если "a" нечетное, иначе четность вообще меняться не будет)
Боюсь, что это не так. В BC++3.1 и в VC++6.0 генератор случайных чисел построен по-другому (к сожалению, не знаю как) Этот генератор я обнаружил только в Delphi (наверное, он есть и в TP7.0, но я не проверял) В C++ генератор другой, он не обладает вышеописанным свойством
Для предсказания этого генератора нужно не больше трех последовательных чисел: 1, если известны a,b 2, если известно что-то одно 3, если оба коэффициента неизвестны А вот, собственно, алгоритм предсказания: x(n+1)=a*x(n)+b mod m ![]() m=2^32 a=134775813 b=1 Возможны случаи, когда мы работаем с генератором, у которого другие коэффициенты: тогда составляем систему уравнений, использующих несколько последовательных значений из этой системы находим коэффициенты
Скорее всего, нужно перебирать все известные гипотезы, пока одна не подойдет. Состояние рассмотренного генератора полностью описывается его выходом (RandSeed) Состояние любого реккурентного регистра полностью описывается несколькими последними выходами Но ведь можно построить генератор, состояние которого будет скрыто, а за выход будет браться какая-то функция от состояния такой генератор значительно сложнее взломать. А еще достаточно добавить подходящую нелинейность, чтобы практически обезвредить весь линейный анализ.
Конечно, если есть все данные за период, можно с легкостью предсказать каждое следующее значение. Однако, почти всегда период измеряется величинами порядка 2^32. Вообще предсказание генераторов случайных чисел часто используется при взломе шифров, поэтому этих генераторов уже понапридумывали кучу, и характеристики у них значительно лучше, чем стандартных. P.S. извините за большой размер сообщения, оно все как-то само получилось -------------------- qqq |
||||||||
|
|||||||||
neutrino |
|
|||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
2maxim1000:Угу, именно этот способ я и имел в виду в начале дискуссии.
По-моему здесь имелся в виду статистический анализ. -------------------- The truth comes from within ... Покойся с миром, Vit |
|||
|
||||
Chingachguk |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 1 Всего: 18 |
srand от VC6++:
rand() от VC6++:
Другими словами, в VC6++ алгоритм у rand() такой: seed' = ( seed * 0x343FD (знаковое умножение) + 0x269EC3 ) mod 2^32; результат от ф-ции rand будет: rand() = (seed' >> 16) & 7FFFh; Если не веришь, задай конкретные значения в srand'е (0,1 ...) и проверь ;) -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
||||||
|
|||||||
neutrino |
|
|||
![]() Gothic soul ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 3041 Регистрация: 25.3.2002 Где: Верхняя Галилея, Кармиэль Репутация: нет Всего: 62 |
Тут пришел Chingachguk и все опошлил
![]()
шутка? Kstati, pro integral - ja ego privel k vidu gamma funkcii i poluchilos', chto ot 0 do +infinity budet 2 (=2*г(1)=2*0!=2) -------------------- The truth comes from within ... Покойся с миром, Vit |
|||
|
||||
Chingachguk |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 1 Всего: 18 |
Почему ? mov eax,[holdrand (00423a50)] // eax = seed' sar eax,10h // eax >> = 16 and eax,7FFFh // eax & = 0x7FFFh Так что безо всяких шуток. И в BC3.1 то же самое. Проверь так: max=0; for (i=0;i<10000;i++) { randval= rand(); if max<randval max=randval; } printf("MaxRand=%u",randval); А вот в linux совсем иначе: чаще всего процедуры типа drand/srand компилируются с дефайном MAX_BITS 48.
Так то ж ... аналитически. И зачем gamma, если такая простая подинтегральная (exp(-const*t)) ? Это сообщение отредактировал(а) Chingachguk - 24.3.2003, 22:28 -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
||||
|
|||||
remax |
|
|||
![]() Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: нет Всего: 5 |
Кстати, а какие способы оценки качества псевдослучайных последовательностей существуют?
Как, например, определить скоррелированность между последовательными значениями случайной величины? Почему то обычно оценивают взаимосвязь между различными случайными величинами (парная корреляция). Хотя, очевидно что при характеризации случайной величины важен не только вид функции распределения (равномерное, нормальное ....) но и сгруппированость значений внутри последовательности. -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
|||
|
||||
Chingachguk |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 1 Всего: 18 |
Например, автокорреляционная функция:
Но это специфическая реализация (моя) для конкретного дела, так что лучше смотреть sources ;) -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
stab |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: нет Всего: 48 |
а как быть с "Алгоритм Л'Экюера, комбинирующий две последовательности" ?
http://algolist.manual.ru/maths/generator/lequer.php -------------------- 6, 6, 6 - the number of the beast. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Алгоритмы" | |
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Алгоритмы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |