Кто-нибудь может подсказать, как реализовать rand на отрезке [l;r], где l,r приблизительно равны 10^200?
№ | Пользователь | Рейтинг |
---|---|---|
1 | tourist | 3993 |
2 | jiangly | 3743 |
3 | orzdevinwang | 3707 |
4 | Radewoosh | 3627 |
5 | jqdai0815 | 3620 |
6 | Benq | 3564 |
7 | Kevin114514 | 3443 |
8 | ksun48 | 3434 |
9 | Rewinding | 3397 |
10 | Um_nik | 3396 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 167 |
2 | Um_nik | 163 |
3 | maomao90 | 162 |
3 | atcoder_official | 162 |
5 | adamant | 159 |
6 | -is-this-fft- | 158 |
7 | awoo | 155 |
8 | TheScrasse | 154 |
9 | Dominater069 | 153 |
10 | nor | 152 |
Название |
---|
- gen == L[i] - тогда следующая цифра может быть от L[i + 1] до 9 включительно
- gen == R[i] - тогда следующая цифра может быть от 0 до R[i + 1] включительно
- L[i] < gen < R[i] - тогда все оставшиеся цифры числа произвольные
Для того, чтобы обрабатывать первые два случая, заведем переменные lower и upper.http://codeforces.me/blog/entry/2564#comment-53483
Вот да, если диапазон 09..19, то вероятность получтиь 09 будет 50% при исходном алгоритме.
А при моём, 0 -> 1 число, 1 -> 9 чисел, тогда если rand < 0.1, то выбираем 0, иначе 1.
если генерировать длину равновероятно, то сгенерированное число не будет равновероятно распределено в [L..R]. Вообще алгоритм генерируемый длину должен сильно зависеть от L и R. Если хотите получить равновероятностное распределение на [L, R], то лучше всего сгенерировать равновероятно распределенное в [0,R - L] число, и затем прибавить к нему L
мы генерируем число Y длины A бит, равновероятно распределенное на [0,2^A - 1]
и вычисляем X = Y % n. Ясно что у нас есть 2^A равновероятных возможностей выбрать число Y.
если 2^A делится на n то все круто, и числа будут выпадать с одинаковой вероятностью.
если не делиться, то обозначим остаток как d, 0 < d < n. фиксированное число из [0,d - 1]
будет выпадать в (2^A / n) + 1 случаях, а число из [d,n - 1] в 2^A / n случаях.
таким образом вероятность выпадения тех и других отличается на 1 / 2^A
R-L = 4
res = 4 * [ 0, 1 ) = случайное распределение чисел от 0 до 4.
res + L = required
Но в принципе чтобы не возиться с округлением, возможно можно предпочесть генерацию числа из диапазона, покрывающего необходимый. Если получившееся число не попадает в требуемые рамки, то повторяем процесс.
При таком подходе "неравномерность" округления переходит в "неравномерность" времени выполнения, конечно... И для любого произвольно длинного отрезка времени существует ненулевая вероятность что генерация затянется как минимум на такое время... ;-)
Тогда делаем точно так же и округляем всегда вниз - каждый полуинтервал [ T, T + 1 ) отвечает ровно за одно число T + L.
Гугли специальные криптографические генераторы.
Хотя, конечно, написание RSA - велосипед, он даже на php есть.
Практиковаться лучше на не математическом кодировании.
Попробуй, например, написать какие-нибудь крестики-нолики на большом поле с plaggable AI или в духе. А потом нормальный AI для него :)
Согласно теореме из теории вероятностей, берем генератор с любым известным непрерывным распределением, и легким движением руки (с помощью функции, обратной к функции распределения) превращаем его в равномерное сначала на [0,1], а потом и на [a,b] (банальным домножением, например). Оно конечно, будут получаться числа с почти что 200 нулями на конце, но если не трогать первые штук 10, а остальные рандомно поменять, то будет нечто вполне похожее на требуемое (как известно, первая цифры равномерно распределенного числа не будет равномерно распределена, распределение второй уже гораздо ближе к равномерному и т.д. )