Boost logo

Boost Users :

From: Nigel Rantor (wiggly_at_[hidden])
Date: 2005-10-19 12:15:49


Hail all,

Thanks for giving us the libraries, now only if we were all smart enough
to use them properley the world would be at peace.

As it is I've been having some problems with my own code that is wrapped
around the random library.

I'm playing around with a game I'm making and needed some randomness,
games that are predicatble are just a tad boring...

I need to generate numbers with lots of different distributions so
creating one or two won't really cut it for me, there would have to be
hundreds.

Instead I went and basically ripped the random_number_generator
described under decorators into two flavours and then created a bunch of
overloaded functions that used them.

The generators use a single real engine, currently mt19937;.

Basically, everythnig works fine, except that calling seed( n ) on the
engine doesn't effect the generators that hold a ref to it, which I
found somewhat bizzare.

So, after a few tweaks I ripped out the code and dumped it into a
minimal test case and can see that the seed( n ) method works just fine
when I pull raw numbers out of the engine, but still doesn't seem to
effect the generators I've defined.

I'm fairly sure this is my problem but I was wondering if anyone would
be good enough to take a peek and tell me why exactly this isn't working.

I did have a search on Gmane but couldn't find anything that looked
related to my problem.

I'm not sure what is the done thing on this list so I've attached
source, if you want a makefile then I can oblige but it is a fairly
small case.

The test program reads in three numbers, the seed to use, the number of
numbers to generate and the max to use when generating numbers from a
distribution.

Feeding it different seeds makes the raw number change, but not the others.

I have also included the output of two runs to show you what I mean.

TIA,

   N

seed : 42
num : 10
max : 1000
seeded rng...
10 raw numbers from rng
1608637542
3421126067
4083286876
787846414
3143890026
3348747335
2571218620
2563451924
670094950
1914837113
10 random integers using rng
795
926
666
119
485
903
904
335
227
185

seed : 727364
num : 10
max : 1000
seeded rng...
10 raw numbers from rng
3240174879
3269238853
3044917573
2953574107
2463698974
2129367301
2064401652
2079989189
3644954707
1971100779
10 random integers using rng
795
926
666
119
485
903
904
335
227
185


#include "random.h"

int random_num( int max )
{
        return int_gen( max );
}

int random_num( int min, int max )
{
        return min + random_num( max );
}

long random_num( long max )
{
        return long_gen( max );
}

long random_num( long min, long max )
{
        return min + random_num( max );
}

float random_num( float max )
{
        return float_gen( max );
}

float random_num( float min, float max )
{
        return min + random_num( max );
}

double random_num( double max )
{
        return double_gen( max );
}

double random_num( double min, double max )
{
        return min + random_num( max );
}


#ifndef RANDOM_H
#define RANDOM_H

#include <boost/random.hpp>

using namespace boost;

typedef mt19937 rng_type;

template<class RNG, class IntType = long>
class integer_random_number_generator
{
        public:

        typedef RNG base_type;
        typedef IntType argument_type;
        typedef IntType result_type;
        integer_random_number_generator( base_type& rng ) : _rng( rng ) {}

        result_type operator()( argument_type n )
        {
                typedef uniform_int<IntType> dist_type;
                return variate_generator<base_type&, dist_type>(_rng, dist_type(0, n-1))();
        }

        private:
        base_type& _rng;
};

template<class RNG, class RealType = double>
class real_random_number_generator
{
        public:

        typedef RNG base_type;
        typedef RealType argument_type;
        typedef RealType result_type;
        real_random_number_generator( base_type& rng ) : _rng( rng ) {}

        result_type operator()( argument_type n )
        {
                typedef uniform_real<RealType> dist_type;
                return variate_generator<base_type&, dist_type>(_rng, dist_type(0, n-1))();
        }

        private:
        base_type& _rng;
};

static rng_type rng;

static integer_random_number_generator<rng_type, int> int_gen( rng );

static integer_random_number_generator<rng_type, long> long_gen( rng );

static real_random_number_generator<rng_type, float> float_gen( rng );

static real_random_number_generator<rng_type, double> double_gen( rng );

int random_num( int max );

int random_num( int min, int max );

long random_num( long max );

long random_num( long min, long max );

float random_num( float max );

float random_num( float min, float max );

double random_num( double max );

double random_num( double min, double max );

#endif /* RANDOM_H */


#include "random.h"
#include <iostream>

using namespace std;

int main( int argc, char ** argv )
{
        unsigned int seed;
        int num;
        int max;
        int i;

        cin >> ws >> seed;
        cin >> ws >> num;
        cin >> ws >> max;

        cout << "seed : " << seed << endl;
        cout << "num : " << num << endl;
        cout << "max : " << max << endl;

        rng.seed( seed );

        cout << "seeded rng..." << endl;

        cout << num << " raw numbers from rng" << endl;
        
        for( i = 0; i < num; i++ )
        {
                cout << rng() << endl;
        }

        cout << num << " random integers using rng" << endl;
        
        for( i = 0; i < num; i++ )
        {
                cout << random_num( max ) << endl;
        }

        return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net