На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> class Random; , независимые случайные числа.
    интересная задачка.
    у меня получается глюкавый генератор случайных чисел.
    дело вот в чем.

    если я напишу такой код:

    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?

    Спасибо за внимание.
      можно и свой ранд написать. есть алгоритмы. могу парочку простых с реализацией кидануть.

      можно попробовать посмотреть на codeguru & codeproject на тему классов для генерирвоания равномерного распределения.

      а что до твоих циклов - ты точно уверен, что должно быть равномерное распределение?

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


        ...
        const static RAND_MAX= ...; или #define RAND_MAX...
        ...

        srand( ...

        MyClass1 mc1;
        MyClass2 mc2;

        mc1.MyFunc1( random( RAND_MAX ) );
        mc2.MyFunc2( random( RAND_MAX ) );

        ...

        void MyClass1::MyFunc1( UINT RAND_COUNT ){
         int n;
         while( RAND_COUNT-- ){
           n = random( RAND_MAX );
         }
        }




          Насколько качественной получится реализация, засит от

          1) насколько интенсивно создаются объекты Random
          2) сколько физически случайной информации (положение мыши, счетчик тиков таймера, измеренные интервалы между последними несколькими нажатиями клавиш клавиатуры, счетчики прерываний устройств и т.п.) используется при создании очередного объекта (т.е. попадает в srand() очередного объекта, который разумеется независимо хранит свое состояние).

          по идее, количество информации в п 2) должно быть заведомо больше количества информации, которое содержится в состоянии генератора.
            Цитата
            Visitor, 10.12.03, 11:46
            1) насколько интенсивно создаются объекты Random


            Замечал только в MSSQL сервере, в C, да и в некоторых других незамечал различая, насколько быстро ? генерится след. случайное число.
              Да не... не "генерится следующее число", а "создается новый объект <независимый генератор>". Проблема тут в том, чтобы обеспечить независимость начальных состояний множества генераторов...
                начальное состояние генератора можно генерировать произвольно, исходя из одного - главного, первого и т.п. srand
                  только ети начальные значения. допустим, для линейного конгруентного, дадут в результате набор "сдвинутых" последовательностей одного генератора. smile.gif

                  Нач состояние Gi(0) = S(i)
                  Тогда Gi(j) = G0(i+j) smile.gif

                  Для других видов генераторов зависимости будут сложнее. И нет гарантии, что ета зависимость не вылезет неподобающим образом хде-нибудь smile.gif
                    с таким же успехом можно и под любой Gi подстроиться, сам же об этом писал smile.gif
                      Дык предполагается, что выбран определенный генератор, который удовлетворяет требованиям одномерной задачи, и необходимо его масштабировать на многомерную... smile.gif А так -- да, алгоритмический генератор может давать только псевдослучайные последовательности smile.gif
                        да ладно бы с этой псевдослучайностью.главное - что бы независимые
                          2AQL

                          ну так пост #3 не пойдет ?
                            мда. самопально делать не хочу... хотя..
                            для старта последовательности можно попользовать GUID. не зря же он такой крутой придуман...
                            а потом

                            a = (a + SuperMega) % MegaSuper;

                            хм, а что - можно и попробовать. Guid правда может музыку попортить, а так все пучком
                            1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                            0 пользователей:


                            Рейтинг@Mail.ru
                            [ Script execution time: 0,4482 ]   [ 15 queries used ]   [ Generated: 18.05.24, 06:04 GMT ]