2011-12-16 4 views
6

Я хотел бы, чтобы сгенерировать случайное число в диапазоне от 0 до 3, и я следующий в моем коде:изменение вероятности получения случайного числа

int random = rand() % 4; 

Это прекрасно работает, но я хотел бы, чтобы произвести 1, 2 и 3 в большинстве случаев и 0 только изредка.

Каков наилучший способ для этого? Каковы названия общих алгоритмов для решения этой проблемы?

+0

Это не случайное число. Это распределение вероятности, которое является видом противоположности случайным (предсказуемость ужасна, когда вы говорите о RNG). –

ответ

15

Вот один из способов. Предположим, вы хотите, чтобы 0, 1, 2, 3 имели распределение 5%, 20%, 30%, 45%.
Вы можете сделать это следующим образом:

double val = (double)rand()/RAND_MAX; 

int random; 
if (val < 0.05)  // 5% 
    random = 0; 
else if (val < 0.25) // 5% + 20% 
    random = 1; 
else if (val < 0.55) // 5% + 20% + 30% 
    random = 2; 
else 
    random = 3; 

Конечно, это не должно быть сделано с плавающей точкой. Я просто сделал это так, потому что это более интуитивно.

+0

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

0

Сколько номеров вы проверили? если это действительно так, вы можете вместо этого генерировать диапазон от 0-03999, используя a = rand()%4000 и использовать int = a/1000, это должно удалить вес, по-видимому, под нулевым результатом.

+1

Я думаю, вы неправильно поняли вопрос, задавая точную противоположность тому, что это такое. ОП говорит, что 'rand()% 4' равномерно распределяет числа, но он (и) хочет, чтобы ноль происходил реже. – ruakh

+1

Я думаю, что OP * хочет * недоработанного нуля. Это не наблюдение, это требование. –

+0

ах мой плохой как-то я пропустил слова «я бы хотел» в этом предложении – smitec

0

Я бы просто нарисовал больше значений до 1,2,3 от большего набора. Например: 9 и отображение 1,2,3 => 1, 3,4,5 => 2, 6,7,8 => 3 и 0 для нуля. Есть и другие способы, но я работаю в пределах вашего вопроса.

0

Просто код именно то, что вы хотите:

int myrand(void) 
{ 
    const int percentZero = 10; 
    if ((rand()%100) < percentZero) return 0; 
    return 1 + (rand() % 3); 
} 

Вы можете изменить процент времени, возвращается ноль все, что вы хотите.

1

Вы не указали точные пропорции, но предположите, что вы хотите, чтобы каждый из 1, 2 и 3 составлял 32% времени, а 0 - другие 4%. Тогда вы могли бы написать:

int random = rand() % 25; 
if(random > 0) 
    random = random % 3 + 1; 

(Очевидно, что вы должны были бы настроить, что для различных пропорций и выше только один подход, многие подобные подходы могли бы работать.).

0

Вы должны найти вероятность которое работает для вашего дела. Так как вы только говорите о количестве 0-3 это довольно легко, вы можете либо позвонить rand() снова, если первый результат является 0, или вы можете использовать гири:

int random = rand() % 16; 

if(random > 10) 
{ 
    random = 3; 
} 
else if(random > 5) 
{ 
    random = 2; 
} 
else if(random > 0) 
{ 
random = 1; 
} 

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

6

Вы можете использовать класс discrete_distribution из случайной библиотеки.

#include <iostream> 
#include <random> 
#include <ctime> 

int main() 
{ 
    std::discrete_distribution<> dist({ 1.0, 4.0, 4.0, 4.0 }); 
    std::mt19937 eng(std::time(0)); 
    for (int i=0; i<100; ++i) 
     std::cout << dist(eng); 
} 

Демо: http://ideone.com/z8bq4

Если вы не можете использовать C++ 11, эти классы существуют в импульс.

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