Generating random integer from a range

前端 未结 13 1699
失恋的感觉
失恋的感觉 2020-11-22 03:12

I need a function which would generate a random integer in given range (including border values). I don\'t unreasonable quality/randomness requirements, I have four requirem

13条回答
  •  傲寒
    傲寒 (楼主)
    2020-11-22 03:59

    If your compiler supports C++0x and using it is an option for you, then the new standard header is likely to meet your needs. It has a high quality uniform_int_distribution which will accept minimum and maximum bounds (inclusive as you need), and you can choose among various random number generators to plug into that distribution.

    Here is code that generates a million random ints uniformly distributed in [-57, 365]. I've used the new std facilities to time it as you mentioned performance is a major concern for you.

    #include 
    #include 
    #include 
    
    int main()
    {
        typedef std::chrono::high_resolution_clock Clock;
        typedef std::chrono::duration sec;
        Clock::time_point t0 = Clock::now();
        const int N = 10000000;
        typedef std::minstd_rand G;
        G g;
        typedef std::uniform_int_distribution<> D;
        D d(-57, 365);
        int c = 0;
        for (int i = 0; i < N; ++i) 
            c += d(g);
        Clock::time_point t1 = Clock::now();
        std::cout << N/sec(t1-t0).count() << " random numbers per second.\n";
        return c;
    }
    

    For me (2.8 GHz Intel Core i5) this prints out:

    2.10268e+07 random numbers per second.

    You can seed the generator by passing in an int to its constructor:

        G g(seed);
    

    If you later find that int doesn't cover the range you need for your distribution, this can be remedied by changing the uniform_int_distribution like so (e.g. to long long):

        typedef std::uniform_int_distribution D;
    

    If you later find that the minstd_rand isn't a high enough quality generator, that can also easily be swapped out. E.g.:

        typedef std::mt19937 G;  // Now using mersenne_twister_engine
    

    Having separate control over the random number generator, and the random distribution can be quite liberating.

    I've also computed (not shown) the first 4 "moments" of this distribution (using minstd_rand) and compared them to the theoretical values in an attempt to quantify the quality of the distribution:

    min = -57
    max = 365
    mean = 154.131
    x_mean = 154
    var = 14931.9
    x_var = 14910.7
    skew = -0.00197375
    x_skew = 0
    kurtosis = -1.20129
    x_kurtosis = -1.20001
    

    (The x_ prefix refers to "expected")

提交回复
热议问题