В общем, я сконструировал свой конгруэнтный генератор на основе мултипликативного и AWC-генератора. Он немного быстрее и немного чотче хл2шного, а главное - никаких копирайтов, можно вешать свой. Шутко. На самом деле главное - это период. У бетковского он 2^32, а у меня 2^32*2^58=2^90. Серии должны быть гораздо длиннее. Осталось его как следует потестить. И я не совсем уверен в правильности выбора стартовых семечек, возможно, этот момент можно сделать лучше.
Если кому интересно - могу выложить с пояснениями.
Ему три сида надо, я их делаю из одного (time(NULL)) путём прогона через вариант мультипликативного генератора, и вот не совсем уверен, нормально ли это. Впрочем, сиды мало на что влияют, распределение всегда вполне равномерное.
Я не перестал, просто в свое время читал какие-то статьи по теме, но в итоге решил не заморачиваться и свою имплементацию пока не писать, а просто поставил заглушку с rand() - для игрушек хватает, для более серьезных проектов придется переписывать конечно.
Цитата:
XaeroX писал: А у тебя статьи случаем нет, что я в первом посте упомянул? Раз интересовался, то наверняка же читал что-то по теме?
Читал да, но искомой статьи не припомню. У меня были какие-то статьи в PDF, надо бы глянуть. Ну я Кнута еще читал, но там как-раз про ЛКМ.
do randNumber = xrxRand(); while ( randNumber > maxAcceptable );
62
63
return low + ( randNumber % randRange );
64
}
65
66
float Com_RandomFloat( float low, float high )
67
{
68
staticbool init = false;
69
float randNumber;
70
float randRange = high - low;
71
72
assert( high >= low );
73
74
if ( randRange <= 0 )
75
return low;
76
77
if ( !init ) {
78
xrxSRand( 0 );
79
init = true;
80
}
81
82
randNumber = 0.2328306437e-9f * xrxRand();
83
return low + randNumber * randRange;
84
}
Из комментариев должно быть понятно, что и как работает.
Этот генератор примерно на 7% быстрее хл2шного (мелочи, ок) и более чем в 2 раза быстрее CRT-шного rand().
Но код, полагаю, намного понятнее и читабельнее.
Если что, задавайте вопросы. Если что-то не работает, или заметили косяк/опечатку - сообщайте.
Извиняюсь за анальную лицензию, но мало ли кто этот код нагуглит... время нынче непростое.
Потом, когда волатила станет GPL, этот код тоже будет GPL, а пока вот так.
XaeroX писал: Что ты понимаешь под "предиктабельным"?
Очень просто, при одинаковом заданном диапазоне и совпадающем сиде всегда будет генерироваться одно и то же псевдослучайное число.
Для чего это нужно ты и сам знаешь - предиктинг випонсов, травку расставлять, да мало ли. Точнее тут смысл в том даже, что не просто одинаковое случайное число. Одна и та же последовательность случайных чисел. Это важнейшее свойство любого генератора такого типа.
Дядя Миша писал: Очень просто, при одинаковом заданном диапазоне и совпадающем сиде всегда будет генерироваться одно и то же псевдослучайное число.
Ну это само собой.
Цитата:
Дядя Миша писал: Для чего это нужно ты и сам знаешь
Знаю, в волатиле юзается предиктабельный рандом.
Я просто подумал, что это какой-то математический термин.
Цитата:
Дядя Миша писал: А RandomFloat?
Пока не написал.
Позже будет. Он всё равно основывается на этой же функции.
Добавлено 21-01-2014 в 02:01:
Ага, дописал RandomFloat, обновил пост.
Она, кстати, немного медленнее, чем хл2шная (примерно на те же 7%, причём загадка, из-за чего, видимо, компилятор чудит при генерации кода), но всё равно быстрее rand().
Кстати в C++11 появилась отличная библиотека <random> с кучей алгоритмов и распределений (и возможностью подключать свои), собственно там весьма винрарный вихрь мерсенна идет из коробки.
Производительность только надо б замерить, но мне чет лень.
thambs
В исходниках - можешь прям эту ссылку в комментариях и разместить.
В статье - ссылайся на оригинальные работы. Моя реализация, по сути, на основе их идей.
Цитата:
Press, W. H. and S. A. Teukolsky (1992). "Portable Random Number Generators." Comput. Phys. 6(5): 522-524.
Marsaglia, G. and A. Zaman (1994). "Some portable very-long-period random number generators." Comput. Phys. 8(1): 117-121.