Python random.uniform () в C ++? - PullRequest
       29

Python random.uniform () в C ++?

1 голос
/ 06 мая 2011

Я какое-то время рвал на себе волосы с этими случайными числами в C ++.

В Python у меня было потрясающее:

random.uniform(0, 1)

, которое произвело новыйслучайное число каждый раз, когда я его называю.

C ++ имеет , чтобы иметь что-то вроде этого.Я долго гуглил и нашел erand48(), который планирую внедрить в свой raytracer (я перевожу его с Python на C ++).

Я пробовал простой тестовый пример, но надеялсясоздать функцию random_uniform(), которая всегда выдает новое случайное число (использование time() не сработает AFAICT, так как это будет работать действительно быстро)

unsigned short Xi[3] = {0, 1, 27};
std::cout << erand48(Xi);

И вывод был (и будет каждый раз, когда я вызываю программу):

0.174529

Я пытался использовать предыдущий вывод в качестве нового Xi, например, (было определено начальное значение Xi s)):

float random_uniform() {
  long generated = erand48(Xi);
  int temp = generated * 1000000;

  unsigned short Xi[3] = {temp - 16, temp - 7, temp - 18};

  return generated;
}

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

Можно ли как-нибудь сделать функцию, которая каждый раз выплевывает новое случайное число?

Ответы [ 4 ]

3 голосов
/ 06 мая 2011

Не знаком с python, я собираюсь предположить, что random.uniform (0, 1) выплевывает случайное число из равномерного распределения между 0 и 1?

Если это так, попробуйте следующее:

srand(time(NULL));
float myRand = ((float) rand( )) / RAND_MAX;

Обратите внимание, что ваш пробег может отличаться, хотя - rand () не гарантированно является источником случайных чисел очень высокого качества.Вы можете получить визуальные артефакты в зависимости от реализации и способа ее использования.Я использую генератор случайных чисел Мерсенна Твистера в моем raytracer.

РЕДАКТИРОВАТЬ: Просто, чтобы быть немного яснее, это:

...
void init_program ( )
{
    ...
    srand(time(NULL));
    ...
}
...
float random_uniform ( )
{
    return ((float) rand( )) / RAND_MAX;
}
...

Если вы позвоните как srand и rand вв то же время, вы, вероятно, будете получать одно и то же «случайное» число каждый раз, потому что, если time не изменилось за это время, вы запустите генератор с точно таким же начальным числом и, следовательно, получите точно такое же первое случайное числочисло.

2 голосов
/ 06 мая 2011

Есть ли причина, по которой вы не просто используете rand(), который является частью стандартной библиотеки C ++?Функция, на которую вы ссылаетесь, является частью спецификации Single UNIX, но, вероятно, она не переносима ...

Причина, по которой вы получаете одно и то же значение снова и снова, заключается в том, что вы не заполняете генератор случайных чиселтак ведет себя детерминистически.Используйте srand() или srand48(), если вы в порядке с функциями, специфичными для UNIX, и нуждаетесь в 48-битной точности. Вызывайте его только один раз в начале вашей программы и передавайте time(NULL).Не беспокойтесь об использовании time(), поскольку вы вызываете эту функцию только один раз, вам не нужно беспокоиться о том, чтобы всегда получать одно и то же значение времени.

Вы также можете обратиться к этой страницео том, как взять возвращаемое значение из rand() и масштабировать его до нужного вам диапазона:

ИСПОЛЬЗОВАТЬ C ИЛИ C ++ rand () ФУНКЦИЯ


РЕДАКТИРОВАТЬ: Вернитесь и прочитайте документы для erand48 снова.Вы заметите, что он возвращает удвоение в диапазоне [0, 1).Вы помещаете это в long, поэтому, вероятно, вы всегда видите ноль (значение усекается до целого числа).Я также думаю, что он, вероятно, обновляет значения массива unsigned long для вас с текущим номером в последовательности - вы предоставляете хранилище, оно использует его для «отслеживания» последовательности.

Попробуйте:

unsigned short xsubi[3] = { 0, 1, 27 };
for (int i = 0; i < 10; ++i)
{
   double value = erand48(xsubi);
   printf("%f\n", value);
}
1 голос
/ 06 мая 2011

Возможно, захотите взглянуть на Boost.Random .

1 голос
/ 06 мая 2011

Да, он называется std::rand(), поставляется в стандартной комплектации и поставляется в <cstdlib>.

http://msdn.microsoft.com/en-us/library/398ax69y(v=VS.100).aspx

...