doc and implementation brought in sync: added access to seed

This commit is contained in:
Bernd Gärtner 2008-11-13 14:40:48 +00:00
parent c016346985
commit fe6d6e97b0
4 changed files with 67 additions and 16 deletions

View File

@ -26,11 +26,13 @@ It can be used as the random number generating function object in the
Instances of \ccClassName\ can be seen as input streams. Different Instances of \ccClassName\ can be seen as input streams. Different
streams are \emph{independent} of each other, i.e.\ the sequence of streams are \emph{independent} of each other, i.e.\ the sequence of
numbers from one stream does \emph{not} depend upon how many numbers numbers from one stream does \emph{not} depend upon how many numbers
were extracted from the other streams. were extracted from the other streams. At each time, an instance has
a \emph{state} that uniquely determines the subsequent numbers being
produced.
It can be very useful, e.g.\ for debugging, to reproduce a sequence of It can be very useful, e.g.\ for debugging, to reproduce a sequence of
random numbers. This can be done by either initialising random numbers. This can be done by either initialising with a fixed
deterministically or using the state functions as described below. seed, or by using the state functions as described below.
\ccInclude{CGAL/Random.h} \ccInclude{CGAL/Random.h}
@ -38,25 +40,22 @@ deterministically or using the state functions as described below.
\ccTypes \ccTypes
\ccUnchecked \ccUnchecked
\ccNestedType{State}{State type.} \ccNestedType{State}{The State type.}
% ----------------------------------------------------------------------------- % -----------------------------------------------------------------------------
\ccCreation \ccCreation
\ccCreationVariable{random} \ccCreationVariable{random}
\ccConstructor{ Random( );}{ \ccConstructor{ Random( );}{
introduces a variable \ccVar\ of type \ccClassTemplateName.} introduces a variable \ccVar\ of type \ccClassTemplateName. The
seed is chosen ``randomly'', depending on the system time.}
\ccConstructor{ Random( long seed);}{ \ccConstructor{ Random( unsigned int seed);}{
introduces a variable \ccVar\ of type \ccClassTemplateName\ introduces a variable \ccVar\ of type \ccClassTemplateName\
and initializes its internal state using \ccc{seed}. Equal and initializes its internal state using \ccc{seed}. Equal
values for \ccc{seed} result in equal sequences of random values for \ccc{seed} result in equal sequences of random
numbers.} numbers.}
\ccConstructor{ Random( State state);}{
introduces a variable \ccVar\ of type \ccClassTemplateName\
and initializes its internal state with \ccc{state}.}
% ----------------------------------------------------------------------------- % -----------------------------------------------------------------------------
\ccOperations \ccOperations
@ -81,7 +80,10 @@ deterministically or using the state functions as described below.
returns \ccVar\ccc{.get_int( 0, upper)}.} returns \ccVar\ccc{.get_int( 0, upper)}.}
% ----------------------------------------------------------------------------- % -----------------------------------------------------------------------------
\ccHeading{State Functions} \ccHeading{Seed and State Functions}
\ccMemberFunction{ unsigned int get_seed() const;}{
returns the seed used for initialization.}
\ccMemberFunction{ void save_state( State& state) const;}{ \ccMemberFunction{ void save_state( State& state) const;}{
saves the current internal state in \ccc{state}.} saves the current internal state in \ccc{state}.}
@ -99,9 +101,9 @@ deterministically or using the state functions as described below.
% ----------------------------------------------------------------------------- % -----------------------------------------------------------------------------
\ccImplementation \ccImplementation
We use the C library function \ccc{erand48} to generate the random We use the C library function \ccc{rand} to generate the random
numbers, \textit{i.e.}, the sequence of numbers depends on the implementation numbers, \textit{i.e.}, the sequence of numbers depends on the implementation
of \ccc{erand48} on your specific platform. of \ccc{rand} on your specific platform.

View File

@ -24,21 +24,32 @@
#ifndef CGAL_RANDOM_H #ifndef CGAL_RANDOM_H
#define CGAL_RANDOM_H #define CGAL_RANDOM_H
#include <utility>
#include <CGAL/basic.h> #include <CGAL/basic.h>
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE
class Random { class Random {
public: public:
// types
typedef std::pair<unsigned int, unsigned int> State;
// creation // creation
Random( ); Random( );
Random( unsigned int seed); Random( unsigned int seed);
// seed
unsigned int get_seed ( ) const;
// operations // operations
bool get_bool ( ); bool get_bool ( );
int get_int ( int lower, int upper); int get_int ( int lower, int upper);
double get_double( double lower = 0.0, double upper = 1.0); double get_double( double lower = 0.0, double upper = 1.0);
// state
void save_state( State& state) const;
void restore_state( const State& state);
// Computes a random int value smaller than 2^b. // Computes a random int value smaller than 2^b.
// It's supposed to be fast, useful for randomized algorithms. // It's supposed to be fast, useful for randomized algorithms.
// The distribution is not perfectly flat, but this is a sacrifice against // The distribution is not perfectly flat, but this is a sacrifice against
@ -70,6 +81,7 @@ class Random {
const double rand_max_plus_1; const double rand_max_plus_1;
unsigned int random_value; // Current 15 bits random value. unsigned int random_value; // Current 15 bits random value.
unsigned int val; // random_value shifted by used bits. unsigned int val; // random_value shifted by used bits.
unsigned int seed;
}; };
// Global variables // Global variables

View File

@ -37,7 +37,7 @@ Random( )
// get system's time // get system's time
std::time_t s; std::time_t s;
std::time( &s); std::time( &s);
unsigned int seed = s; seed = s;
// initialize random numbers generator // initialize random numbers generator
std::srand( seed); std::srand( seed);
@ -45,14 +45,35 @@ Random( )
} }
Random:: Random::
Random( unsigned int seed) Random( unsigned int _seed)
: rand_max_plus_1( RAND_MAX+1.0), val(0) : rand_max_plus_1( RAND_MAX+1.0), val(0), seed(_seed)
{ {
// initialize random numbers generator // initialize random numbers generator
std::srand( seed); std::srand( seed);
random_value = get_int(0, 1<<15); random_value = get_int(0, 1<<15);
} }
// seed
unsigned int
Random::get_seed () const
{
return seed;
}
// state
void
Random::save_state( Random::State& state) const
{
state = Random::State(random_value, val);
}
void
Random::restore_state( const Random::State& state)
{
random_value = state.first;
val = state.second;
}
// Global variables // Global variables
// ================ // ================
Random default_random; Random default_random;

View File

@ -93,6 +93,22 @@ main()
assert( ( 0 <= i) && ( i < 5555)); assert( ( 0 <= i) && ( i < 5555));
} }
// test get_seed()
{
CGAL::Random r (53);
assert (r.get_seed() == 53);
}
// test save/restore state
{
CGAL::Random r1(17);
CGAL::Random r2(23);
CGAL::Random::State s;
r1.save_state(s);
r2.restore_state(s);
assert (r1 == r2);
}
return( 0); return( 0);
} }