2016-01-30 2 views
-1

Я студент C++, и я работаю над созданием генератора случайных чисел.Как улучшить этот код генератора случайных чисел в C++?

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

Я пишу это только из-за моего любопытства.

Я не оспариваю существующие функции библиотеки.

Я всегда использую библиотечные функции при написании приложений на основе случайности, но я снова заявляю, что я просто хочу сделать это из-за моего любопытства.

Я также хотел бы знать, есть ли что-то не так с моим алгоритмом или с моим подходом. Поскольку я искал работу PRNG, и на некоторых сайтах они сказали, что существует математический алгоритм, а предопределенная серия чисел и семя просто устанавливает указатель в другую точку в серии, и через несколько секунд последовательность повторяется.

Мой алгоритм просто начинает перемещаться туда и обратно в массиве возможных значений, и семя каждый раз прерывает цикл с разными значениями. Я не понимаю, что этот подход неправильный. Я получил ответы, предлагающие другой алгоритм, но они не объяснили Что случилось с моим текущим алгоритмом?

Да, там была проблема с моего семени, как это было не точным и сделал результат немного предсказуем, как здесь: -

соиЬ < < р-н (50100);

Результаты в четыре раза превышают 74,93,56,79.

См. Схему «возрастающего порядка».

И для образцов большого диапазона можно было легко увидеть. Я получил ответ на получение хороших семян, но также рекомендовал новый алгоритм (но не сказал почему?).

Альтернативный способ может состоять в случайном перемещении массива, произвольно генерирующего новую последовательность каждый раз. И шаблон растущего порядка будет отключен. Любая помощь с этой перестановкой тоже будет хорошей. Вот код ниже. И если моя функция невозможно, пожалуйста, сообщите мне.

Спасибо вам в ожидании.

int rn(int lowerlt, int upperlt) 
{ 
    /* Over short ranges, results are satisfactory. 
    * I want to make it effective for big ranges. 
    */ 

    const int size = upperlt - lowerlt; // Constant size of the integer array. 

    int ar[size]; // Array to store all possible values within defined range. 
    int i, x, ret; // Variables to control loops and return value. 
    long pointer = 0; //pointer variable. The one which breaks the main loop. 


    // Loop to initialize the array with possible values.. 
    for (i=0, x=lowerlt; x <= upperlt; i++, x++) 
     ar[i]=x; 

    long seed = time(0); 

    //Main loop . To find the random number. 
    for (i=0; pointer <= seed; i++, pointer++) 
    { 
     ret = ar[i]; 
     if (i == size-1) 
     { 
      // Reverse loop. 
      for (; i >= 0; i--) 
      { 
       ret=ar[i]; 
      } 
     } 
    } 

    return ret; 
} 
+3

«Основная проблема» является то, что писать ГСЧ трудно, и нет ничего, в частности, рекомендовать подход вы принять. Ответ на этот вопрос будет состоять только в том, чтобы предложить другой, существующий алгоритм, который вы также можете найти для себя, с большей пользой. – EJP

+0

@ EJP Building RNG сложно или нет, поиск решений важен. Я знаю об библиотечных функциях. Я просто прошу о помощи. Мне просто интересно узнать о различных методах программирования. Я здесь новичок. – anjanik012

+0

Так что найдите один, как я и рекомендовал. Вместо того, чтобы начинать с догадок. Вы узнаете много. – EJP

ответ

0

Оговорка: С вашего поста, кроме вашего алгоритма случайного генератора, один из ваших проблем получить хорошее начальное значение, поэтому я буду решать эту часть.

Чтобы получить начальное значение, вы можете использовать /dev/random. Это было бы прекрасным местом для начала [и было бы достаточно само по себе], но можно было бы считать «обманом» с некоторой точки зрения.

Итак, вот некоторые другие источники «энтропии»:

использовать более высокое время разрешения источника тактового дня: gettimeofday или clock_gettime(CLOCK_REALTIME,...) называют его «cur_time». Используйте только микросекунду или наносекундную часть соответственно, назовите ее «cur_nano». Обратите внимание, что cur_nano обычно довольно случайный сам по себе.

Сделайте getpid(2). У этого есть несколько непредсказуемых бит, потому что между вызовами запускаются другие программы, и мы не знаем, сколько.

Создайте новый файл temp и получите номер inode файла [и удалите его]. Со временем это изменяется медленно. Это может быть одинаково при каждом вызове [или нет]

Получите высокое разрешение для системного времени суток, когда система была загружена, назовите ее «sysboot».

Получить значение высокого разрешения для времени начала вашей «сессии»: когда начальная оболочка вашей программы была запущена, назовите ее «shell_start».

Если вы используете Linux, вы можете вычислить контрольную сумму /proc/interrupts, поскольку это всегда меняется. Для других систем получить некоторый хэш количества прерываний различных типов [должен быть доступен из какого-либо типа syscall].

Теперь создайте некоторый хэш всего вышеперечисленного (например):

dev_random * cur_nano * (cur_time - sysboot) * (cur_time - shell_start) * 
getpid * inode_number * interrupt_count 

Это простое уравнение. Вы можете улучшить его с помощью некоторых операций XOR и/или sum. Экспериментируйте, пока не получите тот, который работает на вас.

Примечание: Это дает вам только начальное значение для вашего PRNG. Вы должны создать свой ПГСЧ от чего-то другого (например, линейный алгоритм Графский)

0
unsigned int Random::next() { 
    s = (1664525 * s + 1013904223); 
    return s; 
} 

«s» растет с каждым вызовом этой функции. Correct является

unsigned int Random::next() { 
    s = (1664525 * s + 1013904223) % xxxxxx; 
    return s; 
} 

Возможно использовать эту функцию

long long Factor = 279470273LL, Divisor = 4294967291LL; 
long long seed; 
next() 
{ 
    seed = (seed * Factor) % Divisor; 
} 
Смежные вопросы