123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*
- * 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
|