Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

changing probability of getting a random number

Tags:

c++

random

I would like to generate a random number between 0 and 3 and I have the following in my code:

int random = rand() % 4;

This works fine but I would like it to generate 1, 2, and 3 most of the time and 0 only occasionally.

What is the best way to go about this? What are the names of common algorithms to address this problem?

like image 232
user974967 Avatar asked Dec 16 '11 04:12

user974967


People also ask

Can you manipulate a random number generator?

With some random number generators, it's possible to select the seed carefully to manipulate the output. Sometimes this is easy to do. Sometimes it's hard but doable. Sometimes it's theoretically possible but practically impossible.

How do you generate random numbers with probability?

Generate random value with probability Select a blank cell which you will place the random value at, type this formula =INDEX(A$2:A$8,COUNTIF(C$2:C$8,"<="&RAND())+1), press Enter key. And press F9 key to refresh the value as you need.

Why is 17 the most common random number?

Seventeen is: Described at MIT as 'the least random number', according to the Jargon File. This is supposedly because in a study where respondents were asked to choose a random number from 1 to 20, 17 was the most common choice. This study has been repeated a number of times.

Can you generate the same random numbers everytime?

random seed() example to generate the same random number every time. If you want to generate the same number every time, you need to pass the same seed value before calling any other random module function.


2 Answers

Here's one way. Suppose you want 0, 1, 2, 3 to have a distribution of 5%, 20%, 30%, 45%.
You could do it like this:

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;

Of course it doesn't have to be done with floating-point. I just did it this way since it's more intuitive.

like image 50
Mysticial Avatar answered Oct 24 '22 02:10

Mysticial


You can use the discrete_distribution class from the random library.

#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);
}

Demo: http://ideone.com/z8bq4

If you can't use C++11, these classes also exist in boost.

like image 30
Benjamin Lindley Avatar answered Oct 24 '22 02:10

Benjamin Lindley