185 lines
3.7 KiB
C
185 lines
3.7 KiB
C
|
/*
|
||
|
* File: Random.h
|
||
|
* Project: DUtils library
|
||
|
* Author: Dorian Galvez-Lopez
|
||
|
* Date: April 2010, November 2011
|
||
|
* Description: manages pseudo-random numbers
|
||
|
* License: see the LICENSE.txt file
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#pragma once
|
||
|
#ifndef __D_RANDOM__
|
||
|
#define __D_RANDOM__
|
||
|
|
||
|
#include <cstdlib>
|
||
|
#include <vector>
|
||
|
|
||
|
namespace DUtils {
|
||
|
|
||
|
/// Functions to generate pseudo-random numbers
|
||
|
class Random
|
||
|
{
|
||
|
public:
|
||
|
class UnrepeatedRandomizer;
|
||
|
|
||
|
public:
|
||
|
/**
|
||
|
* Sets the random number seed to the current time
|
||
|
*/
|
||
|
static void SeedRand();
|
||
|
|
||
|
/**
|
||
|
* Sets the random number seed to the current time only the first
|
||
|
* time this function is called
|
||
|
*/
|
||
|
static void SeedRandOnce();
|
||
|
|
||
|
/**
|
||
|
* Sets the given random number seed
|
||
|
* @param seed
|
||
|
*/
|
||
|
static void SeedRand(int seed);
|
||
|
|
||
|
/**
|
||
|
* Sets the given random number seed only the first time this function
|
||
|
* is called
|
||
|
* @param seed
|
||
|
*/
|
||
|
static void SeedRandOnce(int seed);
|
||
|
|
||
|
/**
|
||
|
* Returns a random number in the range [0..1]
|
||
|
* @return random T number in [0..1]
|
||
|
*/
|
||
|
template <class T>
|
||
|
static T RandomValue(){
|
||
|
return (T)rand()/(T)RAND_MAX;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a random number in the range [min..max]
|
||
|
* @param min
|
||
|
* @param max
|
||
|
* @return random T number in [min..max]
|
||
|
*/
|
||
|
template <class T>
|
||
|
static T RandomValue(T min, T max){
|
||
|
return Random::RandomValue<T>() * (max - min) + min;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a random int in the range [min..max]
|
||
|
* @param min
|
||
|
* @param max
|
||
|
* @return random int in [min..max]
|
||
|
*/
|
||
|
static int RandomInt(int min, int max);
|
||
|
|
||
|
/**
|
||
|
* Returns a random number from a gaussian distribution
|
||
|
* @param mean
|
||
|
* @param sigma standard deviation
|
||
|
*/
|
||
|
template <class T>
|
||
|
static T RandomGaussianValue(T mean, T sigma)
|
||
|
{
|
||
|
// Box-Muller transformation
|
||
|
T x1, x2, w, y1;
|
||
|
|
||
|
do {
|
||
|
x1 = (T)2. * RandomValue<T>() - (T)1.;
|
||
|
x2 = (T)2. * RandomValue<T>() - (T)1.;
|
||
|
w = x1 * x1 + x2 * x2;
|
||
|
} while ( w >= (T)1. || w == (T)0. );
|
||
|
|
||
|
w = sqrt( ((T)-2.0 * log( w ) ) / w );
|
||
|
y1 = x1 * w;
|
||
|
|
||
|
return( mean + y1 * sigma );
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
/// If SeedRandOnce() or SeedRandOnce(int) have already been called
|
||
|
static bool m_already_seeded;
|
||
|
|
||
|
};
|
||
|
|
||
|
// ---------------------------------------------------------------------------
|
||
|
|
||
|
/// Provides pseudo-random numbers with no repetitions
|
||
|
class Random::UnrepeatedRandomizer
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* Creates a randomizer that returns numbers in the range [min, max]
|
||
|
* @param min
|
||
|
* @param max
|
||
|
*/
|
||
|
UnrepeatedRandomizer(int min, int max);
|
||
|
~UnrepeatedRandomizer(){}
|
||
|
|
||
|
/**
|
||
|
* Copies a randomizer
|
||
|
* @param rnd
|
||
|
*/
|
||
|
UnrepeatedRandomizer(const UnrepeatedRandomizer& rnd);
|
||
|
|
||
|
/**
|
||
|
* Copies a randomizer
|
||
|
* @param rnd
|
||
|
*/
|
||
|
UnrepeatedRandomizer& operator=(const UnrepeatedRandomizer& rnd);
|
||
|
|
||
|
/**
|
||
|
* Returns a random number not given before. If all the possible values
|
||
|
* were already given, the process starts again
|
||
|
* @return unrepeated random number
|
||
|
*/
|
||
|
int get();
|
||
|
|
||
|
/**
|
||
|
* Returns whether all the possible values between min and max were
|
||
|
* already given. If get() is called when empty() is true, the behaviour
|
||
|
* is the same than after creating the randomizer
|
||
|
* @return true iff all the values were returned
|
||
|
*/
|
||
|
inline bool empty() const { return m_values.empty(); }
|
||
|
|
||
|
/**
|
||
|
* Returns the number of values still to be returned
|
||
|
* @return amount of values to return
|
||
|
*/
|
||
|
inline unsigned int left() const { return m_values.size(); }
|
||
|
|
||
|
/**
|
||
|
* Resets the randomizer as it were just created
|
||
|
*/
|
||
|
void reset();
|
||
|
|
||
|
protected:
|
||
|
|
||
|
/**
|
||
|
* Creates the vector with available values
|
||
|
*/
|
||
|
void createValues();
|
||
|
|
||
|
protected:
|
||
|
|
||
|
/// Min of range of values
|
||
|
int m_min;
|
||
|
/// Max of range of values
|
||
|
int m_max;
|
||
|
|
||
|
/// Available values
|
||
|
std::vector<int> m_values;
|
||
|
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|