Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.16.67.13] |
|
Сообщ.
#1
,
|
|
|
интересная задачка.
у меня получается глюкавый генератор случайных чисел. дело вот в чем. если я напишу такой код: srand((unsigned)time( NULL )); void MyClass1::MyFunck1(void) { int n; for(int i = 0; i<100; i++) n = rand(); } то n будут равномерно распределенны в диапазоне 0..RAND_MAX но! если вдруг есть следующая ситуация: srand((unsigned)time( NULL )); void MyClass1::MyFunck1(void) { int n; MyClass2 mc; for(int i = rand(); --i>=0; ) { n = rand(); mc.MyFunck2(); } } void MyClass2::MyFunck2(void) { int m; for(int i = rand(); --i>=0; ) m = rand(); } то распределение n по диапазону 0..RAND_MAX уже не будет равномерным. распределение m по диапазону 0..RAND_MAX так же не будет равномерным. (особенно если переменная цикла не очень большая). Потому что в цикле так же появляются случайные числа. Случайным образом. Это от того, что в процессе можно единожды инициализировать srand(), а если затем рассмотреть случайные числа, вызванные rand(), то они будут распределены равномерно. Но если при этом мы имеем ситуацию, приведенную выше, то в каждом отдельном цикле (если значение переменных циклов не равны) rand() будут распределенны абы как. Еще хуже ситуация становиться, если мы пользуемся какой нибудь хитрой нелинейной функцией от rand(). (небольшая справка: у мена именно такая ситуация, и порою, что бы дождаться достаточного количества rand()-ов в определенном интервале (для статистики), на нелинейной шкале, мне приходится генерировать необоснованно много rand()-ов во всех диапазонах, при этом количество необоснованно сгенерированных rand()-ов превышает то, которое могло бы быть раз в 15-20, а это понижает производительность ровно во столько раз). догадываетесь к чему я клоню? я хочу получить распределение по случайной переменной равномерное в каждом отдельном классе. я представляю себе решение приблизительно так. в классах MyClass1, MyClass2 задать переменные типа Random. что бы случайные числа 2-х рандомов были независимы! я мог бы написать тип Random сам. Если бы знал, как в программе (в пределах 1-ого процесса) сделать независимо srand() (его ведь достаточно делать 1 раз). и потом независимо поднимать rand(). интересно чрезвычайно! тогда если у нас есть в MyClass1 переменная типа Random, то, во первых, ее можно независимо от всех остальных переменных подобного типа инициализировать. и независимо от остальных переменных подобного типа поднимать. Вот приблизительное определение его. class Random { private: .....// public: Random(); virtual ~Random(); void Srand(void); void Rand(); }; я мог бы написать генератор случайных чисел сам. но боюсь, что поделочка выйдет куцей. может кто нибудь знает решение этой проблемы? или может быть встречал на просторах необъятной сети? ЗЫ. Если бы речь шла только о двух, трех, четырех независимых переменных, то я бы наверное воспользовался GUID и стандартными средствами работы с ним, хотя бы тоже сначала сильно подумал. А если 20? 50? Спасибо за внимание. |
Сообщ.
#2
,
|
|
|
можно и свой ранд написать. есть алгоритмы. могу парочку простых с реализацией кидануть.
можно попробовать посмотреть на codeguru & codeproject на тему классов для генерирвоания равномерного распределения. а что до твоих циклов - ты точно уверен, что должно быть равномерное распределение? (офтоп небольшой) - сумма большого числа любых распределений стремится к нормальному распределению. у тебя такого эффетка не возникнет? |
Сообщ.
#3
,
|
|||
|
Должно же быть равномерно, почти:
|
Сообщ.
#4
,
|
|
|
Насколько качественной получится реализация, засит от
1) насколько интенсивно создаются объекты Random 2) сколько физически случайной информации (положение мыши, счетчик тиков таймера, измеренные интервалы между последними несколькими нажатиями клавиш клавиатуры, счетчики прерываний устройств и т.п.) используется при создании очередного объекта (т.е. попадает в srand() очередного объекта, который разумеется независимо хранит свое состояние). по идее, количество информации в п 2) должно быть заведомо больше количества информации, которое содержится в состоянии генератора. |
Сообщ.
#5
,
|
|||
|
Замечал только в MSSQL сервере, в C, да и в некоторых других незамечал различая, насколько быстро ? генерится след. случайное число. |
Сообщ.
#6
,
|
|
|
Да не... не "генерится следующее число", а "создается новый объект <независимый генератор>". Проблема тут в том, чтобы обеспечить независимость начальных состояний множества генераторов...
|
Сообщ.
#7
,
|
|
|
начальное состояние генератора можно генерировать произвольно, исходя из одного - главного, первого и т.п. srand
|
Сообщ.
#8
,
|
|
|
только ети начальные значения. допустим, для линейного конгруентного, дадут в результате набор "сдвинутых" последовательностей одного генератора.
Нач состояние Gi(0) = S(i) Тогда Gi(j) = G0(i+j) Для других видов генераторов зависимости будут сложнее. И нет гарантии, что ета зависимость не вылезет неподобающим образом хде-нибудь |
Сообщ.
#9
,
|
|
|
с таким же успехом можно и под любой Gi подстроиться, сам же об этом писал
|
Сообщ.
#10
,
|
|
|
Дык предполагается, что выбран определенный генератор, который удовлетворяет требованиям одномерной задачи, и необходимо его масштабировать на многомерную... А так -- да, алгоритмический генератор может давать только псевдослучайные последовательности
|
Сообщ.
#11
,
|
|
|
да ладно бы с этой псевдослучайностью.главное - что бы независимые
|
Сообщ.
#12
,
|
|
|
2AQL
ну так пост #3 не пойдет ? |
Сообщ.
#13
,
|
|
|
мда. самопально делать не хочу... хотя..
для старта последовательности можно попользовать GUID. не зря же он такой крутой придуман... а потом a = (a + SuperMega) % MegaSuper; хм, а что - можно и попробовать. Guid правда может музыку попортить, а так все пучком |