Ответы пользователя по тегу Случайные числа
  • Как реализовать такую вероятность random?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Подход у вас верный, вроде бы.

    Если нужно случайно выбрать одно из N событий, у каждого своя вероятность – то сложить их в одну линию от 0 до N. Взять случайное от 0 до N и посмотреть на чей отрезок попадает.

    Например три события с вероятностями:
    А: 30%
    B: 65%
    С: 5%
    Отрезок получится: [0..30) [30..95) [95..100)
    Взять случайное от 0 до 100 и посмотреть, куда попало.
    Ответ написан
  • Как можно добиться разнообразия рандомности в PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Рандомность нельзя разнообразить, т.к. в ней каждое следующее выпадающее число
    никак не зависит от того, что выпадало ранее.

    Интуитивно понятно, что хочется, чтобы каждое следующее число, скорее всего, отличалось бы от предыдущего чем больше, тем лучше. Но это уже не настоящая рандомность.

    Можно сымитировать такое поведение. Проще всего жёстко запретить ближе, чем, допустим, 40 от предыдущего.
    Значит, из отрезка значений выпадает отрезок длиной 40 + 1 + 40 = 81
    Первый вызов вернёт честно-случайное mt_rand(322, 595)
    А следующий только mt_rand(322, 514)
    И надо будет его скорректировать, в зависимости от предыдущего. Грубо, так:
    $a = 322;
    $b = 595;
    $m = 40;
    
    // первый раунд
    $rnd = mt_rand($a, $b);
    $prev = $rnd;
    // ... что-то происходит
    
    // второй и последующие раунды
    $rnd = mt_rand($a, $b - 2 * $m - 1);
    if ($rnd > $prev - $m) $rnd += 2 * $m + 1;
    if ($rnd > $b) $rnd -= ($b - $a);
    $prev = $rnd;
    // ...
    Ответ написан
    5 комментариев
  • Сгенерировать M уникальных случайных чисел в диапазоне от 1..N. Быстрый алгоритм есть?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Нужна функция биективной (1:1) проекции упорядоченных чисел от 1 до N на такой же диапазон.

    Самый простой пример, чтобы понятно представить идею, это зеркалирование порядка битов в числе:
    0 000 -> 000 0
    1 001 -> 100 4
    2 010 -> 010 2
    3 011 -> 110 6
    4 100 -> 001 1
    5 101 -> 101 5
    6 110 -> 011 3
    7 111 -> 111 7

    Теперь, чтобы получить очередное случайное, просто берите подряд следующее.

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

    Так не придётся хранить, перемешивать, генерировать случайные. Для "псевдослучайности" можно варьировать функцию. Например, не зеркалить порядок битов, а перемешивать биты как-то иначе. Каждый вариант перемешки битов создаёт новый «перемешанный массив» всех возможных значений.

    Главное, это быстро вычисляется и требует минимальных ресурсов.
    Ответ написан
    Комментировать
  • Как получить случайные числа с линейным сдвигом вероятности?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Интуиция
    Представьте, что у вас барабан рулетки, и шарик равновероятно попадает на любой сектор.
    Чтобы на таком реализовать вашу задачу, нужно на числа от А до X выделить по 1 ячейке.
    И на числа от X до B, на каждое, выделить не по 1, а по F ячеек.

    Реализация
    Длина "рулетки" получается (X-A) + F * (B-X)
    Получите случайное целое на этом диапазоне. Если оно попало выше X, остаётся поделить на F разницу выпавшего числа и X.
    Ответ написан
    Комментировать