В небольшое приложение, написанное на C/С++, я столкнулась с проблемой с функция Рэнд
и, возможно, семя :
Мне нужно создать последовательность случайных чисел разных порядков, т. е. с разными значениями логарифма (по основанию 2). Но кажется, что все произведенные номера имеют тот же порядок, колеблясь между 2^25 и 2^30.
Это потому, что слчис()
засевают время Unix, который в относительно большом количестве? Я что-то забыла ?
Я осеменять слчис () только один раз в начале функции main()
.
Есть только 3% из числа между 1 и 2<суп>30</SUP-серфинг> не между 2<суп>25</с SUP> и 2<суп>30</суп>. Итак, это звучит вполне нормально :)
Потому что 2<суп>25</SUP-серфинг> / 2<суп>30</суп> = 2<суп>-5</суп> = 1/32 = 0.03125 = 3.125%
Светло-зеленый-это область между 0 и 2<суп>25</суп>; темный зеленый-это область между 2<суп>25</с SUP> и 2<суп>30</суп>. Клещи являются степенями 2.
Вы должны быть более точным: вы хотите, чтобы разные значения логарифма по основанию 2, но как раздача вы хотите за это? Стандартная функция RAND() функции генерации равномерного распределения, необходимо преобразовать этот вывод, используя квантиль функции, связанные с распределением, которое вы хотите.
Если вы расскажите распределения, то мы можем сказать вам функция квантиля
вам нужно.
Если вы хотите, чтобы разные порядки, почему бы просто не попробовать пр(2, слчис())
? Или, возможно, выбрать приказом непосредственно как RAND(), как Гарольд предложил?
Основной (и правильный) ответ уже был дан и принят выше: есть 10 цифр от 0 до 9, 90 чисел от 10 до 99, 900 от 100 до 999 и т. д.
Для вычислительно эффективный способ получить распределение с approximately логарифмического распределения, хочешь направо-сместить свой генератор случайных чисел, случайное число:
s = rand() & 31; // a random number between 0 and 31 inclusive, assuming RAND_MAX = 2^32-1
r = rand() >> s; // right shift
Это's не совершенный, но это'ы гораздо быстрее, чем при вычислении пр(2, слчис()*scalefactor)
. Это будет "комом" в том смысле, что распределение будет равномерным для чисел в пределах Фактора 2 (Форма для 128 до 255, половина плотность 256 до 1023, и т. д.).
Вот гистограмма частоты цифры от 0 до 31 (в 1м образцов):
@C4stor сделал большой пункт. Но, для более общего случая и понятны для человека (по основанию 10): для диапазона от 1 до 10^Н ~90% от числа от 10^(N-1) до 10^N, поэтому, ~99% чисел от 10^(н-2) до 10^Н. Продолжайте добавлять столько десятичных знаков, сколько вы хотите.
Забавная математика, если вы продолжаете делать это для n, можно увидеть, что от 1 до 10^Н, 99.9999...% = 100% из чисел от 10^0 до 10^n с помощью этого метода.
Теперь о коде, если вы хотите, чтобы случайное число случайных порядков, от 0 до 10^N, вы могли бы сделать:
Генерировать случайное число от 0 до n
Если вы знаете, что N имеет спектр, генерировать большой случайных чисел порядка 10^K, где k > Макс{Н}.
Вырезать больше случайных чисел, чтобы получить N цифр этого большого случайного числа.
Существует ровно одинаковое количество чисел между 0 и 2^29 и 2^29 и 2^30.
Другой взгляд на проблему: рассмотрим двоичное представление случайных чисел вы генерируете, вероятность того, что старший бит 1 равен 1/2, и, следовательно, вы получить заказ 29 В половине случаев. То, что вы хотите, чтобы увидеть номер, который будет ниже 2^25, а это значит, что 5 старших битов равны нулю, что бывает с низкой вероятностью 1/32. Есть вероятность, что даже если вы запустите его в течение длительного времени вы никогда не увидите порядок ниже 15 в (вероятность-это что-то вроде подвижного 6 6 раз подряд).
Теперь вторая часть вашего вопроса о семени. Нет, семя не может определить диапазон числа генерируются с, она определяет первое, начальное звено. Думаю, что ранд() как последовательность всех чисел в диапазоне (заданной перестановки). Семя определяет, где вы начинаете чисел исходя из последовательности. Именно поэтому, если вы хотите (псевдо) случайности, можно использовать текущее время для инициализации последовательности: вам не важно, что позиции вы исходите из не равномерно, все дело в том, что вы никогда не начинаете с того же места.
Если вы хотите использовать случайные числа онлайн-сервисов, вы можете использовать wget для этого, вы можете хотеть видеть вы также можете использовать услуги, такие как random.org для генерации случайных чисел , вы можете поймать их с помощью wget, а затем чтение чисел из загруженного файла
wget -q https://www.random.org/integers/?num=100&min=1&max=100&col=5&base=10&format=html&rnd=new -O new.txt
http://programmingconsole.blogspot.in/2013/11/a-better-and-different-way-to-generate.html