Random Number Not Seeding

J

Jack

I have two files:

sort_comparison.c++
my_sort.h

sort_comparison.c++ calls this code in my_sort.h:

void my_sort::fillArray(int arr[],int n)
{
// const int random_number_range=1000000;
const int random_number_range=100;
int number,xcell;
randomNumber rnd;
for (xcell=0;xcell<n;xcell++)
{
number=rnd.random(random_number_range);
arr[xcell]=rnd.random(number);
// arr[xcell]=rand();
}
}

The problem is that every array gets filled with the exact same data...
If I comment out:

number=rnd.random(random_number_range);
arr[xcell]=rnd.random(number);

and replace it with

arr[xcell]=rand();

I get random data in my arrays... The complete code for both files is
below. Can anyone tell me why

number=rnd.random(random_number_range);
arr[xcell]=rnd.random(number);

doesn't generate randomized data like "arr[xcell]=rand();"? Thanks.

////////////////////////////////////////////////////////////////////

//begin sort_comparison.c++
#include <ctime>
#include <iostream>
#include <string>
#include "../ftsoftds/include/d_random.h"
#include "../ftsoftds/include/d_sort.h" // Contains
selectionSort
//#include "../ftsoftds/include/d_timer.h"
#include "my_sort.h" // My sorting library.

using namespace std;

void printArray(string name,int arr[],int n)
{
int cell;
cout<<name<<" Sort Array..."<<endl;
for(cell=0;cell<n;cell++)
{
printf("%d ",arr[cell]);
}
cout<<endl;
}
////////////////////////////////////////////////////////////////////////////////
int main ()
{
// Declare five (5) integer arrays. Final array_size is 10,000 (ten
thousand).
const int array_size=25;
const int xrandom_number_range=100;
int
array_selection_sort[array_size],array_insertion_sort[array_size],
array_bubble_sort[array_size],array_exchange_sort[array_size],
array_shell_sort[array_size];
// Declare my_sort.h object (Did I reference this comment
correctly?).
my_sort my;
int cell,xnumber;
randomNumber xrnd;

/*
for(cell=0;cell<array_size;cell++)
{
xnumber=xrnd.random(xrandom_number_range);
array_selection_sort[cell]=xnumber;
}
for(cell=0;cell<array_size;cell++)
{
printf("%d ",array_selection_sort[cell]);
}
cout<<endl;




for(cell=0;cell<array_size;cell++)
{
xnumber=xrnd.random(xrandom_number_range);
array_insertion_sort[cell]=xnumber;
}
for(cell=0;cell<array_size;cell++)
{
printf("%d ",array_insertion_sort[cell]);
}
cout<<endl;

for(cell=0;cell<array_size;cell++)
{
array_exchange_sort[cell]=4;
}
for(cell=0;cell<array_size;cell++)
{
printf("%d ",array_exchange_sort[cell]);
}
cout<<endl;
*/
my.fillArray(array_selection_sort,array_size);
my.fillArray(array_insertion_sort,array_size);
my.fillArray(array_bubble_sort,array_size);
my.fillArray(array_exchange_sort,array_size);
my.fillArray(array_shell_sort,array_size);
// array_exchange_sort[0]=99;

selectionSort(array_selection_sort,array_size);
insertionSort(array_insertion_sort,array_size);

// The following is used to verify that the arrays contain like data...
printArray("Selection",array_selection_sort,array_size);
printArray("Insertion",array_insertion_sort,array_size);
printArray("Bubble",array_bubble_sort,array_size);
printArray("Exchange",array_exchange_sort,array_size);
printArray("Shell",array_shell_sort,array_size);

return 0;
}
//end sort_comparison.c++

///////////////////////////////////////////////////////////////////////

//begin my_sort.h
class my_sort
{
int x, y;
public:
void bubbleSort(int arr[],int n);
void fillArray(int arr[],int n);
};

void my_sort::bubbleSort(int arr[],int n)
{
int i,j;
for(i = 0; i < n; i++)
for(j = i+1; j < n; j++)
if (arr > arr[j]) { // swap arr and arr[j]
int tmp = arr;
arr = arr[j];
arr[j] = tmp;
}
}
////////////////////////////////////////////////////////////////////////////////
void my_sort::fillArray(int arr[],int n)
{
// const int random_number_range=1000000;
const int random_number_range=100;
int number,xcell;
randomNumber rnd;
for (xcell=0;xcell<n;xcell++)
{
number=rnd.random(random_number_range);
arr[xcell]=rnd.random(number);
// arr[xcell]=rand();
}
}
//end my_sort.h
 
V

Victor Bazarov

Jack said:
I have two files:

sort_comparison.c++
my_sort.h

sort_comparison.c++ calls this code in my_sort.h:

void my_sort::fillArray(int arr[],int n)
{
// const int random_number_range=1000000;
const int random_number_range=100;
int number,xcell;
randomNumber rnd;
for (xcell=0;xcell<n;xcell++)
{
number=rnd.random(random_number_range);
arr[xcell]=rnd.random(number);
// arr[xcell]=rand();
}
}

The problem is that every array gets filled with the exact same data...
If I comment out:

number=rnd.random(random_number_range);
arr[xcell]=rnd.random(number);

and replace it with

arr[xcell]=rand();

I get random data in my arrays... The complete code for both files is
below. Can anyone tell me why

number=rnd.random(random_number_range);
arr[xcell]=rnd.random(number);

doesn't generate randomized data like "arr[xcell]=rand();"? Thanks.

[...]

'rand' is a standard function. Its seed is controlled by another standard
function, 'srand'. Any program that doesn't call 'srand' behaves as if
it was called with the argument 0.

Now, we can tell you some things about 'srand' and 'rand', but apparently,
they work fine for you. You OTOH have a problem with 'rnd', which is
an object of type 'randomNumber'. This is not a standard class. So you
would have to tell us what it is before we can explain what the difference
is between it and the standard library functions.

One speculation I'll allow myself: it is possible that you are supposed to
have only one 'randomNumber' object in your program. It _probably_ seeds
itself with something upon creation, and then the sequence sustains itself
somehow. If you keep recreating that object every time you call your
function, it's possible that it just restarts the sequence...

V
 
J

Jack

Ahhh, your reference to 'srand' makes sense. Below is the code to
'd_random.h' which contains the 'randomNumber' class. Can you take a
look at it and make any recommendations on possibly adding 'srand'? I'm
not a hardcore C++ coder... Thanks.

$ cat d_random.h
#include <iostream>
#include <time.h>

using namespace std;

// generate random numbers
class randomNumber
{
public:
// initialize the random number generator
randomNumber(long s = 0);

// return a 32-bit random integer m, 1 <= m <= 2^31-2
long random();

// return a 32-bit random integer m, 0 <= m <= n-1,
// where n <= 2^31-1
long random(long n);

// return a real number x, 0 <= x < 1
double frandom();

private:
static const long A;
static const long M;
static const long Q;
static const long R;

long seed;
};

const long randomNumber::A = 48271;
const long randomNumber::M = 2147483647;
const long randomNumber::Q = M / A;
const long randomNumber::R = M % A;

randomNumber::randomNumber(long s)
{
if (s < 0)
s = 0;

if (s == 0)
{
// get time of day in seconds since 12:00 AM,
// January 1, 1970
long t_time = time(NULL);

// mix-up bits by squaring
t_time *= t_time;
// result can overflow. handle cases
// > 0, < 0, = 0
if (t_time > 0)
s = t_time ^ 0x5EECE66DL;
else if (t_time < 0)
s = (t_time & 0x7fffffff) ^ 0x5EECE66DL;
else
s = 0x5EECE66DL;
}

seed = s;
}

long randomNumber::random()
{
long tmpSeed = A * ( seed % Q ) - R * ( seed / Q );

if( tmpSeed >= 0 )
seed = tmpSeed;
else
seed = tmpSeed + M;

return seed;
}

long randomNumber::random(long n)
{
double fraction = double(random())/double(M);

return int(fraction * n);
}

double randomNumber::frandom()
{
return double(random())/double(M);
}
 
V

Victor Bazarov

Jack said:
Ahhh, your reference to 'srand' makes sense. Below is the code to
'd_random.h' which contains the 'randomNumber' class. Can you take a
look at it and make any recommendations on possibly adding 'srand'?

AFAICS, there is no need for it. The constructor argument plays the
seed role. Construction of an object with the default argument value
(zero, 0) seeds the generator with the time, any other positive value
is kept as the seed.

I still think you should have a global object of type 'randomNumber'
in your program to keep the sequence instead of restarting it every
time when your function 'fillArray' is called. It is quite possible
that while creating new 'randomNumber' object _might_ generate the
sequence of pseudo-random numbers different every time, if all calls
happen to be within the same second (which is not unreasonable in our
times, when computers are fast), then the sequence generated would
be exactly the same for every call to 'fillArray'.

I recommend just modifying your definition of 'rnd' object in your
'fillArray' function to 'static':

void my_sort::fillArray(int arr[],int n)
{
// const int random_number_range=1000000;
const int random_number_range=100;
int number,xcell;
static randomNumber rnd;
...


Victor

> I'm
not a hardcore C++ coder... Thanks.

Neither am I, really... No, honestly, I am not... I swear!
 
J

Jack

Dude! Sweet! The "static" did the trick... Now I have to read what
that's doing :) .

What you said about all calls happening in the same second made sense
too. So I put a few second loop between two fills, and what do you
know... Random data...

Most cool!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top