Генерация случайных чисел с заданным дискретным распределением

5065584

И снова с вами человек, которого не учили программированию и который не знает математику. Вопрос: как генерировать случайные целые числа с заданным дискретным распределением? Ну то есть, я хочу, чтобы у меня выпадали числа, например, из диапазона 1-5 включительно, причем каждое - с заданной вероятностью, например, 1 - 10%, 2 - 40%, 3 - 20%, 4 - 25%, 5 - 5%. Про непрерывные распределения информация находится, а про дискретные, определяемые таким образом, нет.

uncle17

а кто тебе мешает непрерывные числа в целые превращать?
Человек, которого не учили программированию и который не знает математику, но у которого уже лет десять в трудовой стоит "программист"

khachin

Числа, генерируемые функцией random.random (у Python'а, да равномерно распределяются, то есть вероятность обнаружить случайное число в любой точке этого интервала одинакова.
Вывод: генерировать числа от 0 до 100.
При [0-10) возвращать 1, при [10-50) — 2...при [95-100) — 5

5065584

Ну...положим, я об этом смутно подозревал. А можно ли это сделать красиво, без прорвы условных операторов?

rosali

> без прорвы условных операторов?
Да, сложить своё распределение в отсортированный вектор, и вызывать от него std::lower_bound. Ну или в std::map, если там не 1-2-3-4-5, а с большими пропусками.
Там конешно тоже будут условные операторы, но всего лишь в количестве логарифм.

khachin

Например так
from random import random
# один раз объявляем все числа и вес их вероятности
chances = {1:10, 2:40, 3:20, 4:25, 5:5, 6:46}
# остальная часть опирается на словарь
boundary = 0
rnd = random * sum(chances.values
for n in sorted(chances):
boundary += chances[n]
if rnd < boundary:
print n
break

Это набросок, но суть, думаю, ясна.

Dmitriy82

Весьма детальный разбор: http://www.keithschwarz.com/darts-dice-coins/ .
Там в частности это делают за константное время (с линейным препроцессингом).

vall

генерировать числа от 0 до 100
тут это самая сложная часть, если конечно делать правильно :grin:

digenet


import numpy as np

def draw_i(q = [0.1, 0.4, 0.2, 0.25, 0.05], n = 10):
q = np.array(q)
Q = np.cumsum(q)
indices = np.searchsorted(Q, np.random.uniform(0, 1, size = n
if n == 1:
return indices[0]
else:
return indices

indices = draw_i(q = [0.1, 0.4, 0.2, 0.25, 0.05], n=100)
vals = [1,2,3,4,5]
print [vals[idx] for idx in indices]

видел где-то в книге: http://www.quant-econ.net/

Dmitriy82


if n == 1:
return indices[0]
else:
return indices
Вот не надо так делать, не для того динамическая типизация в питоне!
Оставить комментарий
Имя или ник:
Комментарий: