В небольшом приложении, написанном на C / C ++, я столкнулся с проблемой с rand
функцией и, возможно, с семенем:
Я хочу создать последовательность случайных чисел, которые имеют разные порядки, то есть с различными значениями логарифма (основание 2). Но кажется, что все произведенные числа имеют один и тот же порядок, колеблющийся между 2 ^ 25 и 2 ^ 30.
Это потому, что rand()
засеян со временем Unix, которое сейчас является относительно большим числом? Что я забыл? Я сею rand()
только один раз в начале main()
.
rand()
возвращения равномерно распределенных чисел (об этом явно говорится в документации с высоким рейтингом Google), я не думаю, что этот вопрос будет полезен для будущих читателей. Вот почему проголосуйте, но не позволяйте этому отговорить вас от использования SO.Ответы:
Есть только 3% чисел между 1 и 2 30, которые НЕ между 2 25 и 2 30 . Итак, это звучит довольно нормально :)
Из - 2 25 /2 30 = 2 -5 = 1/32 = 0,03125 = 3,125%
источник
>>
сдвига битов - это даст вам меньшие числа. (Или принимая модуль с%
.)0
и если каждый бит случайный ...Светло-зеленый - это область от 0 до 2 25 ; темно-зеленый - область между 2 25 и 2 30 . Клещи имеют степень 2.
источник
Вам нужно быть более точным: вам нужны разные значения логарифма по основанию 2, но какое распределение вы хотите для этого? Стандартные функции rand () генерируют равномерное распределение, вам нужно преобразовать этот вывод, используя функцию квантиля, связанную с желаемым распределением.
Если вы сообщите нам о дистрибутиве, то мы можем сообщить вам нужную вам
quantile
функцию.источник
Если вы хотите разные порядки, почему бы просто не попробовать
pow(2, rand())
? Или, возможно, выбрать порядок непосредственно как rand (), как предложил Гарольд?источник
rand()
может доходить доRAND_MAX
, вам действительно нужно масштабировать ваше случайное число, чтобы результат не переполнялся ...@ C4stor сделал замечательную мысль. Но для более общего случая и более понятного для человека (база 10): для диапазона от 1 до 10 ^ n, ~ 90% чисел составляют от 10 ^ (n-1) до 10 ^ n, следовательно, ~ 99% чисел идут от 10 ^ (n-2) до 10 ^ n. Продолжайте добавлять столько десятичных знаков, сколько вы хотите.
Забавная математика, если вы продолжаете делать это для n, вы можете видеть, что с этим методом от 1 до 10 ^ n, 99,9999 ...% = 100% чисел от 10 ^ 0 до 10 ^ n.
Теперь о коде, если вы хотите случайное число со случайными порядками величин от 0 до 10 ^ n, вы можете сделать:
Генерация небольшого случайного числа от 0 до n
Если вы знаете диапазон, который имеет n, сгенерируйте большое случайное число порядка 10 ^ k, где k> max {n}.
Вырежьте длинное случайное число, чтобы получить n цифр этого большого случайного числа.
источник
Основной (и правильный) ответ уже был дан и принят выше: имеется 10 чисел от 0 до 9, 90 чисел от 10 до 99, 900 от 100 до 999 и т. Д.
Для эффективного с точки зрения вычислений способа получения распределения с приблизительно логарифмическим распределением вы хотите сдвинуть случайное число вправо на случайное число:
Это не идеально, но это гораздо быстрее, чем вычисления
pow(2, rand()*scalefactor)
. Это будет «комом» в том смысле, что распределение будет равномерным для чисел с коэффициентом 2 (равномерно для 128–255, половина плотности для 256–1023 и т. Д.).Вот гистограмма частоты чисел от 0 до 31 (в 1М выборках):
источник
rand()>>(rand()&31);
можно было бы интуитивно ожидать, что 1/32 числа будет иметь 32 бита, а 1/32 числа будет иметь 31 бит, а 1/32 числа будет иметь 30 бит и т. д. Но это не результаты, которые вы получаете, только около 1/64 числа будет иметь 32 бита, а почти половина должна быть 0. Поскольку моя математическая математика не согласна с вашими измерениями, мне придется делать свои собственные измерения, чтобы вычислить это изЧисло от 0 до 2 ^ 29 и от 2 до 29 и от 2 до 30 точно совпадают.
Другой способ взглянуть на проблему: рассмотрите двоичное представление генерируемого вами случайного числа, вероятность того, что старший бит равен 1, равна 1/2, и, следовательно, вы получите порядок 29 в половине случаев. Вам нужно увидеть число, которое будет меньше 2 ^ 25, но это означает, что 5 старших битов равны нулю, что происходит с низкой вероятностью 1/32. Скорее всего, даже если вы запустите его в течение длительного времени, вы никогда не увидите порядок ниже 15 (вероятность - что-то вроде 6 6 раз подряд).
Теперь часть вашего вопроса о семени. Нет, начальное число не может определить диапазон, из которого генерируются числа, оно просто определяет первый, начальный элемент. Думайте о rand () как о последовательности всех возможных чисел в диапазоне (предопределенная перестановка). Семя определяет, где вы начнете рисовать числа из последовательности. Вот почему, если вы хотите (псевдо) случайности, вы используете текущее время для инициализации последовательности: вам все равно, что позиция, с которой вы начинаете, распределена неравномерно, все, что имеет значение, это то, что вы никогда не начинаете с одной и той же позиции.
источник
Используйте
pow(2,rand())
это даст ответы в порядке желаемой величины!источник
Если вы хотите использовать случайные числа из онлайн-сервиса, для этого вы можете использовать wget, возможно, вы захотите использовать такие сервисы, как random.org, для генерации случайных чисел, вы можете поймать их, используя wget, и затем читать числа из загруженный файл
http://programmingconsole.blogspot.in/2013/11/a-better-and-different-way-to-generate.html
источник