Change the probability of getting a random number

I would like to create a random number from 0 to 3, and in my code there is the following:

int random = rand() % 4; 

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

What is the best way to do this? What are the names of common algorithms to solve this problem?

+6
source share
7 answers

Here is one way. Suppose you want 0, 1, 2, 3 to have a distribution of 5%, 20%, 30%, 45%.
You can do it as follows:

 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, this does not need to be done with a floating point. I just made it this way because it is more intuitive.

+15
source

You can use the discrete_distribution class from a 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 cannot use C ++ 11, these classes also exist in boost.

+6
source

You did not give the exact proportions, but assume that you want 1, 2, and 3 to each account for 32% of the time, and 0 to the other 4%. Then you can write:

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

(Obviously, you need to tune this for different proportions. And above is just one approach, many similar approaches may work.)

+1
source

how many numbers have you checked? if this is true, you can instead generate a range from 0 β†’ 3999 using a = rand()%4000 and use int = a/1000 , this should remove the weight, apparently under a null result.

0
source

I would just dial more values ​​to 1,2,3 from a larger set. For example: 9 and a mapping 1,2,3 => 1, 3,4,5 => 2, 6,7,8 => 3 and 0 for zero. There are other ways, but I work within your question.

0
source

Just enter exactly what you want:

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

You can change the percentage of the zero point in time that will be returned to you, what you want.

0
source

You need to find a probability distribution that works for your case. Since you are only talking about numbers 0-3, it is quite simple, you can call rand() again if the first result is 0, or you can use weight:

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

It is not particularly elegant, but I hope it shows you how you can create a custom distribution to suit your needs.

0
source

Source: https://habr.com/ru/post/903886/


All Articles