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
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.
how many numbers have you tested this on? if it is actually true you can instead generate a range from say 0->3999 using a = rand()%4000
and use int = a/1000
this should remove the weight of the apparently under produced zero.
You need to find a probability distribution that works for your case. Since you're only talking about the numbers 0-3 this is quite easy, you could either call rand()
again if the first result is a 0, or you could use weights:
int random = rand() % 16;
if(random > 10)
{
random = 3;
}
else if(random > 5)
{
random = 2;
}
else if(random > 0)
{
random = 1;
}
This isn't a particularly elegant, but hopefully it shows you how you can create a custom distribution to fit your needs.
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.
Just code 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 time zero is returned to whatever you want.
You didn't give exact proportions, but suppose you want 1, 2, and 3 to each occur 32% of the time, and 0 to occur the other 4%. Then you could write:
int random = rand() % 25;
if(random > 0)
random = random % 3 + 1;
(Obviously you'd need to adjust that for different proportions. And the above is just one approach; many similar approaches could work.)