00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __RANDOM_UTIL_H
00034 #define __RANDOM_UTIL_H
00035
00036 #include <stdarg.h>
00037 #include <vector>
00038
00049
00050 class RandomUtil {
00051 protected:
00052 static RandomUtil* _inst;
00053 RandomUtil() { }
00054 static RandomUtil& Instance();
00055
00056 public:
00057
00058 virtual unsigned randIntImpl();
00059 virtual unsigned randIntImpl(unsigned max);
00060 virtual unsigned randIntImpl(unsigned max, unsigned first, va_list ap);
00061 virtual unsigned randIntImpl(const std::vector<unsigned>& weights) {
00062 unsigned max = 0;
00063 for(std::vector<unsigned>::const_iterator i = weights.begin(); i != weights.end(); i++) {
00064 max += *i;
00065 }
00066 unsigned rand = randIntImpl(max);
00067 std::vector<unsigned>::const_iterator j;
00068 unsigned current;
00069 unsigned pos;
00070 for(j = weights.begin(), current = *j, pos = 0; j != weights.end() && rand >= current; ++j, pos++, current += *j);
00071 return pos;
00072 }
00073
00074 static void seedRandom(unsigned int s);
00075 static unsigned randInt() { return Instance().randIntImpl(); }
00076
00077 static unsigned randInt(unsigned max) {
00078 return Instance().randIntImpl(max);
00079 }
00081 static unsigned randInt(unsigned max, unsigned first ...) {
00082 va_list ap;
00083 va_start(ap, first);
00084 unsigned r = Instance().randIntImpl(max, first, ap);
00085 va_end(ap);
00086 return r;
00087 }
00089 static unsigned vrandInt(unsigned max, unsigned first, va_list ap) {
00090 return Instance().randIntImpl(max, first, ap);
00091 }
00093 static unsigned randInt(std::vector<unsigned> weights) {
00094 return Instance().randIntImpl(weights);
00095 }
00096
00098 template <typename T> static const typename T::key_type& random(const T& map) {
00099 ASSERT(!map.empty());
00100 std::vector<unsigned> weights;
00101 for(typename T::const_iterator i = map.begin(); i != map.end(); i++) {
00102 weights.push_back(i->second);
00103 }
00104 unsigned pos = Instance().randIntImpl(weights);
00105 typename T::const_iterator j = map.begin();
00106 for(unsigned i = 0; i < pos && j != map.end(); i++, j++);
00107 ASSERT(j != map.end());
00108 return j->first;
00109 }
00110
00111 virtual ~RandomUtil() {}
00112
00113 private:
00114 static bool srandInit;
00115 };
00116
00120 #endif