changing probability of getting a random number

前端 未结 7 1517
南方客
南方客 2020-12-09 22:15

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

相关标签:
7条回答
  • 2020-12-09 22:38

    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.

    0 讨论(0)
  • 2020-12-09 22:39

    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.

    0 讨论(0)
  • 2020-12-09 22:47

    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.

    0 讨论(0)
  • 2020-12-09 22:48

    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.

    0 讨论(0)
  • 2020-12-09 22:48

    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.

    0 讨论(0)
  • 2020-12-09 22:52

    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.)

    0 讨论(0)
提交回复
热议问题