2015-02-11 1 views
-4

У меня есть два числа 1,2 с вероятностями .7 и, соответственно 3. Как я могу забрать один номер в соответствии с заданными вероятностями ..Как подобрать число из массива с заданными вероятностями

+0

Что вы пробовали до сих пор? У вас есть какая-то конкретная проблема? Кроме того, вы должны искать «распространение Бернулли» в Википедии, это должно помочь вам. – Yellows

+0

Я пробовал, но не добился успеха .. как я могу использовать процесс bernoulli, чтобы забрать номер. – mohamed

ответ

4

прямой реализации

Что вам нужно, это уменьшенная Бернулли генератор случайных чисел. Оригинальный Бернулли случайная величина 0 или 1, и вам нужно 1 или 2. Таким образом, следующий код должен работать:

a = binornd(1,0.3)+1; 

первый аргумент размер (здесь 1 см MATLAB документации), то второй из них является вероятность получения 1. При добавлении 1 это становится вероятностью получения 2.

ВНИМАНИЕ: Остальная часть ответа не рекомендуется для людей без юмора.

Реализация Geeky

Вы можете использовать единообразный генератор случайных чисел и настроить его:

a = rand; %in (0,1) range 
result = 1*(a<=0.7) + 2*(a>0.7); 

уборщицу пути (спасибо Luis Mendo):

result = 1 + (rand>.7); 

Реализация Über-Geeky

Предполагая некоторую цифру дробной части в tic...toc равномерно случайным образом:

tic 
A = rand(12060, 4400); 
B = rand(12000, 4430); 
t=toc; 
t=round(t*10^3); 
t = mod(t, 10); 
randVal = (t<=6)*1 + (t>6)*2; 

Расширенная Убер-Geeky Реализация

Расширение предыдущего подхода, но на этот раз с использованием псевдо-случайным образом 32 (каждый бит генерируется как в предыдущем методе), деля его на максимальное значение, таким образом получая приблизительно равномерно распределенную переменную между 0 и 1.

randNum = 0; 
for i=0:31 
    tic 
    A = rand(12000, 4400); 
    B = rand(12000, 4400); 
    t=toc; 
    t=round(t*10^3); 
    randNum = randNum + mod(t,2)*2^i; 
end 
%randNum is a uniformly distributed number between 0 and 2^32 - 1 

randNum = randNum/(2^32); 

final = (randNum<=0.7)*1 + (randNum>0.7)*2; 
+1

Чистая необработанная сырость. +1. – rayryeng

+0

Обычно я не отвечаю на самые плохие вопросы, но я не мог пройти, хорошую работу. – runDOSrun

+1

@runDOSrun - Я обычно тоже этого не делаю, но если ответ действительно хороший, и если человек, который написал ответ, показал много усилий, а также разъяснил некоторые запутанные части вопроса, они, безусловно, получили мое преимущество. – rayryeng

0

Основная проблема выбора числа с определенным распределением довольно распространена. Ваш пример - очень простая форма, хотя название вопроса подразумевает, что вас интересует общее решение.

Вот простая функция, которая работает, выбирая случайное число от 0 до 1. Затем оно перебирает значения в массиве распределения, аккумулируя их из cdf дистрибутива. Когда значение в аккумуляторе превышает случайное значение, возвращается индекс.

function idx = randWithDist(dist) 
    r = rand; 
    a = 0; 
    idx = 0; 
    while(r > a) 
     idx = idx + 1; 
     a = a + dist(idx); 
    end 
end 

Это избыточно для вашего примера 2-значения, но вы бы использовать его как это: randWithDist([.7 .3])

Если вы используете эту функцию, чтобы выбрать значения из произвольного массива (например, ваш вопрос подразумевает), просто использовать возвращаемое значение как индекс в массив:

dist = [.2 .3 .4 .1]; 
val = [1 2 10 11]; 

samples = []; 
for i=1:10000 
    samples = [samples val(randWithDist(dist))]; 
end 

histogram(samples); 

Это должно выбрать 1 с .2 вероятностью, 2 с .3, 10 с.4 и 11 с .1. График гистограммы показывает, что он работает правильно.

histogram plot from above code

Другой твик я бы к нему для того, чтобы она могла обрабатывать более общие входы изменяет первую строку r = rand * sum(dist). Это автоматически нормализует распределение, поэтому его не нужно суммировать до 1.

Смежные вопросы