Non_pseudo_random_number_generator - 2

Тема в разделе "WASM.BEGINNERS", создана пользователем turistti, 19 дек 2006.

  1. turistti

    turistti New Member

    Публикаций:
    0
    Регистрация:
    22 ноя 2006
    Сообщения:
    7
    Уважаемые....

    посмотрите пожалуйста.... кусок кода...
    Код (Text):
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <stddef.h>
    4. #include <errno.h>
    5. #include <string.h>
    6. #include <math.h>
    7. typedef unsigned long ulong;
    8. typedef unsigned int  uint;
    9.  
    10. typedef struct {
    11.     const char * P_Name;
    12.     uint Max;
    13.     uint Min;
    14.     size_t Size;
    15.     void (* P_Set) (void * P_State, uint Seed);
    16.     uint (* P_Get) (void * P_State);
    17.     double (* P_GetDouble) (void * P_State);
    18.   } RngType;
    19.  
    20. typedef struct {
    21.     const RngType * P_Type;
    22.     void * P_State;
    23.   } Rng;
    ......
    Код (Text):
    1. int main()
    2. {
    3.     double k = 0, mu = 9000;
    4.     int i = 0, n = 10, ok = 1;
    5.     const RngType * p_type = 0;
    6.     Rng * p_rng = 0;
    7.     RandNumbGen generator;
    8.  
    9.     uint max_gen, min_gen;
    10.  
    11.  
    12.     RngEnvSetup();
    13.     p_type = RngDefault;
    14.     p_rng = RngAlloc(p_type);
    15.     max_gen = p_rng->P_Type->Max;
    16.     min_gen = p_rng->P_Type->Min;
    17.  
    18.     for (i = 0; i < n; i++)
    19.     {
    20.         k = generator.RanExponential(p_rng, mu);
    21.         printf("%u \n", k);
    22.     }
    23.     printf("min_gen = %u \n", min_gen);
    24.     printf("max_gen = %u \n", max_gen);
    25.     return ok;
    26. }
    так все работает, все генерируется...
    но есть одно но! мне надо каким-то образом вот эти p_rng->P_Type->Max и p_rng->P_Type->Min (то бишь максимум и минимум генератора) задать вручную....
    если делать так
    Код (Text):
    1. uint max_gen, min_gen;
    2. ....
    3. p_rng->P_Type->Max = max_gen;
    4. p_rng->P_Type->Min = min_gen;
    и переменным max_gen, min_gen присвоить какое-либо значение хоть жестко в программе, хоть вводя с коммандной строки, все равно, компилятор ругаетс... выдает ошибку....
    cannot modify a const object
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Код (Text):
    1. /* Получаем текущие максимальное и минимальное значения */
    2. max_gen = p_rng->P_Type->Max;
    3. min_gen = p_rng->P_Type->Min;
    4.  
    5. new_max_gen = 100; /* Пример нового максимального значения */
    6. new_min_gen = 3; /* Пример нового минимального значения */
    7.  
    8. max_gen -= min_gen;
    9. new_max_gen -= new_min_gen;
    10.  
    11. /* Генерируем случайное число */
    12. k = generator.RanExponential(p_rng, mu);
    13.  
    14. /* Подстраиваем под новый диапазон */
    15. k -= min_gen;
    16. k = (uint)(((double)k) * new_max_gen / max_gen);
    17. k += new_min_gen;
    Лучше, конечно, разобрать исходники генератора, чтобы можно было изменять Max и Min.
     
  3. turistti

    turistti New Member

    Публикаций:
    0
    Регистрация:
    22 ноя 2006
    Сообщения:
    7
    Quantum
    спасибо, попробую так...
    посмотрим, что получится... если что, сообщу. только уже завтра.... :)
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    модификатор const убери в структуре Rng.
     
  5. turistti

    turistti New Member

    Публикаций:
    0
    Регистрация:
    22 ноя 2006
    Сообщения:
    7
    Quantum
    Вариант, который вы предложили не работает... все к получаются равными нулю.
    Давайте попробуем разобраться в исходниках генератора.
    Суть вот в чем.
    Код (Text):
    1. // установка генератора
    2. //Descr: эта функция считывает переменные окружения RNG_TYPE (имя генератора,
    3. //   по умолчанию mt19937) и RNG_SEED (начальное число генератора, по умолчанию 0)
    4. //   и использует из значения для установки соответствующей библиотеки переменных.
    5. RngEnvSetup();
    6. //Desr: тип устанавливаемого генератор апо умолчанию
    7. p_type = RngDefault;
    8. //Descr: эта фукция возвращает указатель на новосозданный генератор случайных чисел.
    9. //   Генератор автоматически запускается со значения начального числа по умолчанию
    10. //   (равно 0)
    11. p_rng = RngAlloc(p_type);
    12. //Descr: эта функция возвращает случайные величины по экспоненциональному
    13. //   распределению со средним значением mu.
    14. k = generator.Exponential(p_rng, mu);
    ниже описаны функции, используемые выше.
    Код (Text):
    1. const RngType * RngEnvSetup()
    2. {
    3.     uint seed = 0;
    4.     const char *p = getenv("RNG_TYPE");
    5.     if (!p) {
    6.         RngDefault = Rng_Mt_19937;
    7.     }
    8.     p = getenv ("RNG_SEED");
    9.     if (p)
    10.     {
    11.         seed = strtoul (p, 0, 0);
    12.         /*fprintf (stderr, "RNG_SEED=%lu\n", seed);*/
    13.     };
    14.     RngDefaultSeed = seed;
    15.     return RngDefault;
    16. }
    17.  
    18. static const RngType MtType =
    19. {
    20.     "Mt_19937",     //name
    21.     0xffffffffUL,       //RAND_MAX
    22.     0,          //RAND_MIN
    23.     sizeof (MtStateT),
    24.     &MtSet,
    25.     &MtGet,
    26.     &MtGetDouble
    27. };
    28.  
    29. const RngType * RngDefault = &MtType;
    30. uint RngDefaultSeed = 0;
    31.  
    32. void RngSet (const Rng * pR, uint seed) {(pR->P_Type->P_Set) (pR->P_State, seed);}
    33. Rng * RngAlloc (const RngType * pT)
    34. {
    35.     Rng * pR = (Rng *) malloc (sizeof (Rng));
    36.     /*if (pR == 0) {
    37.         ERROR_VAL ("failed to allocate space for rng struct", ENOMEM, 0);
    38.     };*/
    39.     pR->P_State = malloc (pT->Size);
    40.     if (pR->P_State == 0) {
    41.         free (pR);      //exception in constructor, avoid memory leak
    42.         /*ERROR_VAL ("failed to allocate space for rng state", ENOMEM, 0);*/
    43.     };
    44.     pR->P_Type = pT;
    45.     RngSet (pR, RngDefaultSeed);    //seed the generator
    46.     return pR;
    47. }
    48.  
    49. double RandNumbGen::Exponential(const Rng * P_r, const double mu)
    50. {
    51.     double u = RngUniformPos(P_r);
    52.     return -mu * log(u);
    53. }
    вот надо как-то задать мининимум и максимум для генерируемых значений.

    учитывая, что
    Код (Text):
    1. typedef struct {
    2.     const char * P_Name;
    3.     uint Max;
    4.     uint Min;
    5.     size_t Size;
    6.     void (* P_Set) (void * P_State, uint Seed);
    7.     uint (* P_Get) (void * P_State);
    8.     double (* P_GetDouble) (void * P_State);
    9.   } RngType;
    10.  
    11. typedef struct {
    12.     const RngType * P_Type;
    13.     void * P_State;
    14.   } Rng;
    15.  
    16. VAR const RngType * Rng_Mt_19937;
     
  6. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    turistti
    new_max_gen и/или max_gen в предпоследней строчке тоже нужно к double приводить. Иначе компилятор задействует целочисленное деление.