Генератор случайных чисел с более высокой вероятностью выдачи низких значений?

Как сгенерировать псевдослучайное число (желательно на Lua), где у генератора большая вероятность выдать маленькие числа?

В моем случае я хочу дать случайный результат в игре, где обычно получают более низкие баллы, но более высокие появляются редко. Я видел взвешенные генераторы случайных чисел, которые используют таблицу, но это не соответствует моему плану. Я просто хочу указать минимум (0) максимум (переменная) и убедиться, что большинство чисел остаются низкими.

Я уверен, что это возможно с помощью простой математической операции, но я не могу вспомнить, какая именно. Например, для фильтрации обычного вывода math.random нет необходимости в генераторе действительно случайных чисел.


person viktorry    schedule 12.12.2010    source источник


Ответы (5)


Это может быть не то, что вы ищете, так как это не плавно смещенная кривая колокола, но почему бы не создать два шага? Определите вероятность получения оценки более низкого диапазона, и если вы соответствуете ей, ваш диапазон является нижним диапазоном. В противном случае ваш диапазон находится от вершины нижнего диапазона до конца верхнего диапазона.

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

Что вы думаете?

person Robert    schedule 12.12.2010

Попробуйте math.floor(minscore+(maxscore-minscore)*math.random()^2). Отрегулируйте мощность в соответствии с желаемым распределением.

person lhf    schedule 12.12.2010

Я нашел Ihf answer очень полезно, и я создаю для него метод С#:

    private int GetRandomNumber(int max, int min, double probabilityPower = 2)
    {
        var randomizer = new Random();
        var randomDouble = randomizer.NextDouble();

        var result = Math.Floor(min + (max + 1 - min) * (Math.Pow(randomDouble, probabilityPower)));
        return (int) result;
    }

Если probabilityPower больше 1, более низкие значения будут встречаться чаще, чем более высокие. Если он находится в диапазоне от 0 до 1, более высокие значения будут более распространены, чем более низкие. Если это 1, результаты будут в общей случайности.

Примеры (все с 1 миллионом итераций, min = 1, max = 20):


вероятность = 1,5

1: 135534 (13.5534%)
2: 76829 (7.6829%)
3: 68999 (6.8999%)
4: 60909 (6.0909%)
5: 54595 (5.4595%)
6: 53555 (5.3555%)
7: 48529 (4.8529%)
8: 44688 (4.4688%)
9: 43969 (4.3969%)
10: 44314 (4.4314%)
11: 40123 (4.0123%)
12: 39920 (3.992%)
13: 40466 (4.0466%)
14: 35821 (3.5821%)
15: 37862 (3.7862%)
16: 35222 (3.5222%)
17: 35902 (3.5902%)
18: 35202 (3.5202%)
19: 33961 (3.3961%)
20: 33600 (3.36%)

вероятность = 4

1: 471570 (47.157%)
2: 90114 (9.0114%)
3: 60333 (6.0333%)
4: 46574 (4.6574%)
5: 38905 (3.8905%)
6: 32379 (3.2379%)
7: 28309 (2.8309%)
8: 27906 (2.7906%)
9: 22389 (2.2389%)
10: 21524 (2.1524%)
11: 19444 (1.9444%)
12: 19688 (1.9688%)
13: 18398 (1.8398%)
14: 16870 (1.687%)
15: 15517 (1.5517%)
16: 15871 (1.5871%)
17: 14550 (1.455%)
18: 14635 (1.4635%)
19: 13399 (1.3399%)
20: 11625 (1.1625%)

вероятность = 1

1: 51534 (5.1534%)
2: 49239 (4.9239%)
3: 50955 (5.0955%)
4: 47992 (4.7992%)
5: 48971 (4.8971%)
6: 50456 (5.0456%)
7: 49282 (4.9282%)
8: 51344 (5.1344%)
9: 50841 (5.0841%)
10: 48548 (4.8548%)
11: 49294 (4.9294%)
12: 51795 (5.1795%)
13: 50583 (5.0583%)
14: 51020 (5.102%)
15: 51060 (5.106%)
16: 48632 (4.8632%)
17: 48568 (4.8568%)
18: 50039 (5.0039%)
19: 49863 (4.9863%)
20: 49984 (4.9984%)

вероятность = 0,5

1: 3899 (0.3899%)
2: 5818 (0.5818%)
3: 12808 (1.2808%)
4: 17880 (1.788%)
5: 23109 (2.3109%)
6: 26469 (2.6469%)
7: 33435 (3.3435%)
8: 35243 (3.5243%)
9: 42276 (4.2276%)
10: 47235 (4.7235%)
11: 52907 (5.2907%)
12: 58107 (5.8107%)
13: 63719 (6.3719%)
14: 66266 (6.6266%)
15: 72708 (7.2708%)
16: 79257 (7.9257%)
17: 81830 (8.183%)
18: 87243 (8.7243%)
19: 90958 (9.0958%)
20: 98833 (9.8833%)

вероятность = 0,4

1: 917 (0.0917%)
2: 3917 (0.3917%)
3: 3726 (0.3726%)
4: 10679 (1.0679%)
5: 13092 (1.3092%)
6: 17306 (1.7306%)
7: 22838 (2.2838%)
8: 29221 (2.9221%)
9: 35832 (3.5832%)
10: 38422 (3.8422%)
11: 47800 (4.78%)
12: 53431 (5.3431%)
13: 63791 (6.3791%)
14: 69460 (6.946%)
15: 75313 (7.5313%)
16: 86536 (8.6536%)
17: 95082 (9.5082%)
18: 103440 (10.344%)
19: 110203 (11.0203%)
20: 118994 (11.8994%)
person yellowblood    schedule 31.08.2011

Я бы просто преобразовал значения стандартной случайной функции, например:

r1=math.random(0,255)
r2=math.exp(math.random(0,255))

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

person jpjacobs    schedule 12.12.2010

function weighted_random (weights)
    local summ = 0
    for i, weight in pairs (weights) do
        summ = summ + weight
    end
    local value = math.random (summ)
    summ = 0
    for i, weight in pairs (weights) do
        summ = summ + weight
        if value <= summ then
            return i, weight
        end
    end
end

Как позвонить:

local elements = {"a", "b", "c", "d"} -- elements
local weights = {40, 24, 22, 14} -- weights of elements
local n = weighted_random (weights) -- returns 1, 2, 3 or 4
local element = elements[n] -- returns "a", "b", "c" or "d" 
-- with chances: 40/100, 24/100, 22/100, 14/100, as in weights
person darkfrei    schedule 05.06.2021