Программа для генерации случайного простого числа в c? [Дубликат]

Для меня настройка политики выполнения на Unrestricted не работала. Мне пришлось отремонтировать установку vs2013, перейдя в панель управления. Ремонт установки работал для меня.

42
задан Dan D. 29 April 2012 в 04:48
поделиться

12 ответов

Вы должны засеять его. Хорошая идея:

srand()

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main ()
{
  srand ( time(NULL) );
  printf ("Random Number: %d\n", rand() %100);
  return 0;
}

Вы получаете одну и ту же последовательность, потому что rand () автоматически высевается с помощью значение 1, если вы не вызываете srand ().

Редактировать

Из-за комментариев

rand() будет верните число между 0 и RAND_MAX (определенное в стандартной библиотеке). Использование оператора modulo (%) дает остаток от деления rand()/100. Это заставит случайное число находиться в диапазоне 0-99. Например, чтобы получить случайное число в диапазоне от 0 до 999, мы применили бы rand()%1000.

72
ответ дан kjfletch 19 August 2018 в 17:46
поделиться
  • 1
    Я уже знаю это, но мой вопрос в том, почему он дает одну и ту же последовательность, когда я не использую srand? – Hannoun Yassir 10 July 2009 в 11:29
  • 2
    Потому что, если вы не засеваете его вручную, по умолчанию это ВСЕГДА посеяно до 1. См. Ответ Адити. – GManNickG 10 July 2009 в 11:41
  • 3
    Если безопасность вызывает беспокойство, то посещать ее со временем - довольно плохая идея, так как злоумышленник может часто находить или угадывать время запуска относительно легко (от нескольких десятков до нескольких сотен попыток), а затем воспроизводить вашу последовательность псевдослучайных чисел. Если возможно, попробуйте использовать источник энтропии, предоставленный операционной системой, для вашего семени. – Dave Sherohman 10 July 2009 в 11:46
  • 4
    Если безопасность является проблемой, использование rand () вообще - довольно плохая идея, независимо от того, как вы ее засеиваете. Помимо неизвестной силы алгоритма PRNG, он обычно принимает только 32 бит семени, поэтому жестокое форсирование правдоподобно, даже если вы не сделаете его излишне легким, посеяв время. Сеяние rand () с энтропийным источником для обеспечения безопасности - это как предоставление ослиных стероидов и внесение их в [Kentucky] Derby. – Steve Jessop 10 July 2009 в 12:27
  • 5
    почему существует% 100 после printf ()? – Fahad Uddin 12 October 2010 в 10:43

Цитата из man rand :

Функция srand () задает свой аргумент как семя для новой последовательности псевдослучайных целых чисел, которую нужно вернуть Rand (). Эти последовательности повторяются, вызывая srand () с тем же начальным значением.

Если не задано начальное значение, функция rand () автоматически высевается со значением 1.

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

18
ответ дан Aditya Sehgal 19 August 2018 в 17:46
поделиться
  • 1
    @matthew: Из вашей ссылки: «Если вызов rand () вызывается до того, как будут сделаны вызовы srand (), одна и та же последовательность должна быть сгенерирована так же, как при первом вызове srand () с начальным значением 1. & quot; – Aditya Sehgal 10 July 2009 в 11:25
  • 2
    Спасибо, Адитья. Моя ошибка слишком быстро. – Matthew Flaschen 10 July 2009 в 11:33

Здесь много ответов, но никто, кажется, действительно не объяснил, почему именно rand () всегда генерирует одну и ту же последовательность с тем же семенем - или даже то, что семя действительно делает. Итак, здесь идет.

Функция rand () поддерживает внутреннее состояние. Понятно, что это можно рассматривать как глобальную переменную некоторого типа rand_state. Каждый раз, когда вы вызываете rand (), он выполняет две вещи. Он использует существующее состояние для вычисления нового состояния и использует новое состояние для вычисления числа, возвращаемого вам:

state_t rand_state = INITIAL_STATE;

state_t calculate_next_state(state_t s);
int calculate_return_value(state_t s);

int rand(void)
{
    rand_state = calculate_next_state(rand_state);
    return calculate_return_value(rand_state);
}

Теперь вы можете видеть, что каждый раз, когда вы вызываете rand (), это собирается сделать rand_state перемещаться на один шаг по заранее определенному пути. Случайные значения, которые вы видите, основаны только на том, где вы находитесь по этому пути, поэтому они также будут следовать заранее определенной последовательности.

Теперь вот где происходит srand (). Это позволяет вам прыгать в другую точку на пути:

state_t generate_random_state(unsigned int seed);

void srand(unsigned int seed)
{
    rand_state = generate_random_state(seed);
}

Точные детали state_t, calculate_next_state (), calculate_return_value () и generate_random_state () могут варьироваться от платформы к платформе, но они обычно довольно просты.

Вы можете видеть из этого, что каждый раз, когда запускается ваша программа, rand_state будет начинаться с INITIAL_STATE (что эквивалентно generate_random_state (1)) - вот почему вы всегда получаете одну и ту же последовательность, если вы 't использовать srand ().

9
ответ дан caf 19 August 2018 в 17:46
поделиться

rand () возвращает следующее (псевдо) случайное число в ряду. Что происходит, вы имеете одну и ту же серию каждый раз при ее запуске (по умолчанию «1»). Чтобы засеять новую серию, вы должны вызвать srand (), прежде чем вы начнете вызывать rand ().

Если вы хотите что-то случайное каждый раз, вы можете попробовать:

srand (time (0));
2
ответ дан Chet 19 August 2018 в 17:46
поделиться

Генераторы случайных чисел на самом деле не случайны, они, как и большинство программ, полностью предсказуемы. То, что делает rand, создает различное псевдослучайное число каждый раз, когда оно называется One, которое кажется случайным. Чтобы правильно использовать его, вам нужно дать ему другую отправную точку.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main ()
{
  /* initialize random seed: */
  srand ( time(NULL) );

  printf("random number %d\n",rand());
  printf("random number %d\n",rand());
  printf("random number %d\n",rand());
  printf("random number %d\n",rand());

  return 0;
}
7
ответ дан Dave Sherohman 19 August 2018 в 17:46
поделиться

вызывать srand(sameSeed) перед вызовом rand(). Подробнее здесь .

0
ответ дан dfa 19 August 2018 в 17:46
поделиться

Кстати: факт, что rand НЕ случайный (PRNG = PSEUDO Random Number Generator, где псевдо - ключевое слово!) может быть очень полезным.

Если тот же алгоритм используется на компьютерах по сети, и если некоторые данные (например, состояние игры) вычисляются с использованием «случайных» чисел и если код на всех машинах синхронизирован, так что вызов rand вызывается в одном и том же месте / времени всеми клиентами, тогда вы можете уменьшить нагрузку на сеть, регенерируя данные / события / независимо от места.

Псевдо-случайный - это прекрасная вещь. :)


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

0
ответ дан fullreset 19 August 2018 в 17:46
поделиться
0
ответ дан James 19 August 2018 в 17:46
поделиться

Это из http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html#rand :

Объявление:

void srand(unsigned int seed); 

Эта функция сгенерирует генератор случайных чисел, используемый функцией rand. Выселение srand с тем же семенем приведет к тому, что rand вернет ту же последовательность псевдослучайных чисел. Если srand не вызывается, rand действует так, как будто srand (1) был вызван.

2
ответ дан Key 19 August 2018 в 17:46
поделиться

Присадка rand()

void srand (unsigned int seed)

Эта функция устанавливает семя в качестве семени для новой серии псевдослучайных чисел. Если вы вызываете rand до того, как семя было установлено с srand, оно использует значение 1 в качестве семени по умолчанию.

Чтобы создать различную псевдослучайную последовательность при каждом запуске вашей программы, сделайте srand (time (0))

0
ответ дан nik 19 August 2018 в 17:46
поделиться

rand () возвращает псевдослучайные числа. Он генерирует числа, основанные на заданном алгоритме. Начальная точка этого алгоритма всегда одна и та же, поэтому вы увидите ту же последовательность, сгенерированную для каждого вызова. Это удобно, когда вам нужно проверить поведение и последовательность вашей программы.

Вы можете установить «семя» случайного генератора с помощью функции srand (только один раз вызов srand в программе). Один общий способ получения разных последовательностей из генератора rand () - установить начальное значение на текущее время или идентификатор процесса:

srand (время (NULL)); или srand (getpid ()); в начале программы.

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

32
ответ дан nos 19 August 2018 в 17:46
поделиться
  • 1
    +1, особенно для упоминания, что это не хорошо для криптографических потребностей. – DevSolar 10 July 2009 в 11:48
  • 2
    +1, отметив, что на самом деле это генератор псевдослучайных чисел, поэтому всегда выдает одинаковые числа с одинаковым начальным начальным значением. – Matt 27 July 2009 в 22:50
  • 3
    Это очень полезное решение для многих пользователей, которых я считаю, потому что оно решает мою проблему генерации разных случайных чисел в случаях параллелизма. – Vijay Kumar Kanta 9 May 2016 в 08:35
  • 4
    Как мне получить getpid()? Нужна ли мне какая-либо специальная библиотека? – pushpen.paul 21 April 2018 в 13:11

Если я помню цитату из семантической работы Кнута «Искусство компьютерного программирования» в начале главы о генерации случайных чисел, она выглядит следующим образом:

«Любой, кто пытается генерировать случайные числа математически означает, технически говоря, состояние греха ».

Проще говоря, генераторы случайных чисел являются алгоритмами, математическими и на 100% предсказуемыми. Это действительно хорошо во многих ситуациях, где желательна повторяемая последовательность «случайных» чисел - например, для определенных статистических упражнений, где вы не хотите «колебаться» в результатах, которые действительно случайные данные вводят благодаря кластерные эффекты.

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

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

9
ответ дан Tim H 19 August 2018 в 17:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: