Search code examples
c++randomsrand

srand not random at all - alternatives?


I was toying around with arrays, populating with pseudo random numbers, finding minimum and maximum values and their indices and number of occurrences and I noticed something strange - when using srand seeded with time the number of minimum and maximum value occurrences is ALWAYS equal. This doesn't seem very random to me.

Is there an alternative way of getting a DIFFERENT number of minimum and maximum value occurrences, as one would expect with random numbers?

Here is my code (I am learning so it may be messy and inefficient, recommendations are welcome)

#include <cstdlib>
#include <iostream>
#include <time.h>

using namespace std;

void findExtremes( const int[], int); 

int main()
{
    const int lenght = 2000; //define lenght

    int array1[lenght];

    srand(time(0)); 

    for ( int i = 0; i < lenght; i++) //populate array with random numbers and print them out
    {
        array1[i] = rand() % 3000;
        cout << "Index " << i << " = " << array1[i] << endl;
    }

    findExtremes(array1, lenght);   // call fn

    return 0;
}

void findExtremes( const int array[], int size)
{
     int maxV, minV, maxI, minI;
     maxV = array[0];
     minV = array[0];
     minI = 0;
     maxI = 0;

     for ( int i = 1; i < size; i++)
     {
         if ( array[i] > maxV)
            {
                maxV = array[i];
                maxI = i;
            }
         if ( array[i] < minV)
            {
                minV = array[i];
                minI = i;
            }
     }

     //find the number of occurances for min and max values

     int minOcc = 0;
     int maxOcc = 0;

     for ( int i = 1; i < size; i++)
     {
             if (array[i] == minV)
                 minOcc++;
             if (array[i] == minV)
                 maxOcc++;
     }

     //output

     cout << "\nMinmim value is index " << minI << " with value " << minV << " and " << minOcc << " occurances" << endl;
     cout << "\nMaxium value is index " << maxI << " with value " << maxV << " and " << maxOcc << " occurances" << endl << "\n";  
}

Solution

  • For a start, they're actually pseudo random numbers, not random numbers. In any case, it may be that a a truly random sequence has that exact property that you're seeing :-) The sequence 1,1,1,1,1 is as equally likely to occur in a truly random set as much as 5,2,4,2,99.

    If you want a "more random" random sequence, I wouldn't be using the normal ones shipped with C libraries (unless those libraries were written by people who understand randomness) - you should look into things like the Mersenne Twister, using /dev/random (if under Linux) and so on.

    You may also want to look at this snippet of your code.

    if (array[i] == minV)
        minOcc++;
    if (array[i] == minV)
        maxOcc++;
    

    I believe that last if should be comparing with maxV rather than minV. Otherwise there is zero chance that your minimum and maximum counts will be different.

    When I make that change (and change % 3000 to % 30, to get a range of duplicates), I see:

    Minmim value is index 112 with value 0 and 65 occurances
    Maxium value is index 24 with value 29 and 58 occurances
    

    And, not that it really matters in terms of this question, you may want to clean up your spelling somewhat:

    • lenght -> length.
    • minmum -> minimum
    • maxium -> maximum
    • occurances -> occurrences