Search code examples
c++algorithmcounterfrequencyfrequency-distribution

Efficient algorithm for counting frequency of numbers in an intervals


I need to build a bar gragh that illustrate a distribution of pseudorandom numbers that determined by linear congruential method

Xn+1 = (a * Xn + c) mod m
U = X/m

on the interval [0,1]

For example:

Interval           Frequency     
[0;0,1]            0,05
[0,1;0,2]          0,15
[0,2;0,3]          0,1
[0,3;0,4]          0,12
[0,4;0,5]          0,1
[0,5;0,6]          0,15
[0,6;0,7]          0,05
[0,7;0,8]          0,08
[0,8;0,9]          0,16
[0,9;1,0]          0,4

I used such a method:

float mas[10] = {0,0,0,0,0,0,0,0,0,0};
void metod1()
{
    int x=-2, m=437, a=33, c=61;
    float u;
    for(int i=0;i<m;i++){
        x=(a*x + c) % m;
        u=(float)x/(float)m;
        int r;
        r = ceil(u*10);
        mas[r] = mas[r] + 1;
    }
    for(i=0;i<10;i++) cout<<"["<<(float)i/10<<";"<<(float)(i+1)/10<<"]"<<" | "<<mas[i]<<"\n-----------------"<<endl;
    return;
}

If you know another officient methods for this problem, that are not straitforward, i would appreciate it.


Solution

  • Your code currently has a much larger problem the efficiency. Assuming you've defined mas as something like int mas[10];, it has undefined behavior.

    To see the problem, let's modify your code to print out the values of r that it generates:

    void metod1() {
        int mas[11] = { };
        int x = -2, m = 437, a = 33, c = 61;
        float u;
        for (int i = 0; i < m; i++) {
            x = (a*x + c) % m;
            u = (float)x / (float)m;
            int r;
            r = ceil(u * 10);
            //mas[r] = mas[r] + 1;
            std::cout << r << '\t';
        }
    //    for (i = 0; i < 10; i++) cout << "[" << (float)i / 10 << ";" << (float)(i + 1) / 10 << "]" << " | " << mas[i] << "\n-----------------" << endl;
        return;
    }
    

    Then let's look at the results:

    0       -2      -7      -4      -7      -7      -6      0       -6      -1
    -5      -6      -1      -9      -7      -2      -7      -3      0       -6
    0       -8      -5      -6      -8      -6      -7      0       -2      -6
    -7      -6      -2      -4      -9      0       -4      -5      -1      -2
    -5      0       -2      -1      -4      -8      -5      -2      -8      -5
    -9      -4      -5      -7      -9      -8      -3      -9      -9      -9
    -3      -4      -5      -3      -9      -6      -5      -3      -1      0
    -5      -5      -6      -7      -9      -5      -4      -1      -5      -1
    -9      -2      0       -9      -6      -7      -5      -5      -3      -3
    -9      -3      0       -4      -1      -1      0       -8      -4      -4
    -2      -7      0       -6      -6      -8      -4      -8      -2      -8
    -8      -2      -4      -7      -1      -6      -1      -3      -7      -3
    -5      -9      -8      -5      -8      -7      -4      -1      -8      -7
    -7      -2      -9      -5      -3      0       2       8       8       2
    6       8       7       1       5       2       8       4       1       5
    10      1       3       6       4       10      5       6       6       10
    

    [more elided]

    It doesn't look like you've planned for the fact that you'll be producing negative numbers, and if you fail to do so, the result is undefined behavior when you index outside the bounds of mas.