00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef ASTL_RANDOM_H
00023 #define ASTL_RANDOM_H
00024
00025 #include <astl.h>
00026 #include <cmath>
00027 #include <ctime>
00028
00029 namespace astl {
00030
00031
00032
00033
00034
00035
00036
00037
00038 class randomizer
00039 {
00040 protected:
00041 double seed_, state;
00042 static const double TEN_PI;
00043 static const double E;
00044
00045 public:
00046 randomizer(unsigned int i = time(0)) {
00047 seed(i);
00048 }
00049
00050 unsigned int seed() const {
00051 return (unsigned int) seed_;
00052 }
00053
00054 void seed(unsigned int i) {
00055 seed_ = i;
00056 state = seed_ * E;
00057 }
00058
00059 double operator()() {
00060 static double bogus;
00061 state = modf(state * TEN_PI + E, &bogus);
00062 return state;
00063 }
00064 };
00065
00066 const double randomizer::TEN_PI = 31.41592653589793;
00067 const double randomizer::E = 2.718281828459045;
00068
00069 template <typename EnumerableCharTraits>
00070 class generator_base : public forward_cursor_concept
00071 {
00072 public:
00073 typedef generator_base self;
00074 typedef unsigned int state_type;
00075 typedef empty_tag tag_type;
00076 typedef typename EnumerableCharTraits::char_type char_type;
00077 typedef EnumerableCharTraits char_traits;
00078
00079 protected:
00080 mutable randomizer gen1, gen2;
00081 int graine;
00082 state_type q;
00083 pair<typename EnumerableCharTraits::const_iterator, state_type> t;
00084 unsigned int depth;
00085 double t_prob, f_prob;
00086
00087 public:
00088 generator_base(unsigned int height, double t_probability,
00089 double f_probability, int seed = time(0))
00090 : graine(seed), depth(height), t_prob(t_probability),
00091 f_prob(f_probability)
00092 { }
00093
00094 bool src_final() const {
00095 gen2.seed(graine + q);
00096 return gen2() < f_prob;
00097 }
00098
00099 bool aim_final() const {
00100 gen2.seed(graine + t.second);
00101 return gen2() < f_prob;
00102 }
00103
00104 self& operator=(state_type p) {
00105 q = p;
00106 }
00107
00108 state_type src() const {
00109 return q;
00110 }
00111
00112 state_type aim() const {
00113 return t.second;
00114 }
00115
00116 tag_type src_tag() const {
00117 return empty_tag();
00118 }
00119
00120 tag_type aim_tag() const {
00121 return empty_tag();
00122 }
00123
00124 char_type letter() const {
00125 return *t.first;
00126 }
00127
00128 state_type sink_state() const {
00129 return state_type(0);
00130 }
00131
00132 bool sink() const {
00133 return q == sink_state();
00134 }
00135
00136 void forward() {
00137 q = t.second;
00138 --depth;
00139 }
00140
00141 bool operator==(const self& x) const {
00142 return q == x.q && t == x.t;
00143 }
00144 };
00145
00146 template <typename EnumerableCharTraits>
00147 class dag_generator : public generator_base<EnumerableCharTraits>
00148 {
00149 public:
00150 typedef dag_generator self;
00151 typedef generator_base<EnumerableCharTraits> super;
00152 typedef typename super::state_type state_type;
00153 typedef typename super::tag_type tag_type;
00154 typedef typename super::char_type char_type;
00155 typedef typename super::char_traits char_traits;
00156
00157 public:
00158 dag_generator(unsigned int height, double t_probability,
00159 double f_probability, int seed = time(0))
00160 : super(height, t_probability, f_probability, seed) {
00161 q = t.second = 1;
00162 }
00163
00164 bool first() {
00165 if (depth == 0) return false;
00166 gen1.seed(graine + q);
00167 for(t.first = EnumerableCharTraits::begin();
00168 t.first != EnumerableCharTraits::end() && gen1() >= t_prob; ++t.first);
00169 if (t.first != EnumerableCharTraits::end()) {
00170 ++t.second;
00171 return true;
00172 }
00173 return false;
00174 }
00175
00176 bool next() {
00177 for(++t.first; t.first != EnumerableCharTraits::end()
00178 && gen1() >= t_prob; ++t.first);
00179 if (t.first != EnumerableCharTraits::end()) {
00180 ++t.second;
00181 return true;
00182 }
00183 return false;
00184 }
00185
00186 protected:
00187 using super::q;
00188 using super::t;
00189 using super::depth;
00190 using super::gen1;
00191 using super::graine;
00192 using super::t_prob;
00193 };
00194
00195 template <typename EnumerableCharTraits>
00196 class tree_generator : public generator_base<EnumerableCharTraits>
00197 {
00198 public:
00199 typedef tree_generator self;
00200 typedef generator_base<EnumerableCharTraits> super;
00201 typedef typename super::state_type state_type;
00202 typedef typename super::tag_type tag_type;
00203 typedef typename super::char_type char_type;
00204 typedef typename super::char_traits char_traits;
00205
00206 protected:
00207 static state_type count;
00208
00209 public:
00210 tree_generator(unsigned int height, float t_probability,
00211 float f_probability, int seed = time(0))
00212 : super(height, t_probability, f_probability, seed) {
00213 q = ++count;
00214 }
00215
00216 bool first() {
00217 if (depth == 0) return false;
00218 gen1.seed(graine + q);
00219 for(t.first = EnumerableCharTraits::begin();
00220 t.first != EnumerableCharTraits::end() && gen1() >= t_prob; ++t.first);
00221 if (t.first != EnumerableCharTraits::end()) {
00222 t.second = ++count;
00223 return true;
00224 }
00225 return false;
00226 }
00227
00228 bool next() {
00229 if (depth == 0) return false;
00230 for(++t.first; t.first != EnumerableCharTraits::end()
00231 && gen1() >= t_prob; ++t.first);
00232 if (t.first != EnumerableCharTraits::end()) {
00233 t.second = ++count;
00234 return true;
00235 }
00236 return false;
00237 }
00238
00239 protected:
00240 using super::q;
00241 using super::t;
00242 using super::depth;
00243 using super::gen1;
00244 using super::graine;
00245 using super::t_prob;
00246 };
00247
00248 template <typename EnumerableCharTraits>
00249 typename tree_generator<EnumerableCharTraits>::state_type
00250 tree_generator<EnumerableCharTraits>::count = 0;
00251
00252 template <typename EnumerableCharTraits>
00253 class cyclic_generator : public generator_base<EnumerableCharTraits>
00254 {
00255 public:
00256 typedef cyclic_generator self;
00257 typedef generator_base<EnumerableCharTraits> super;
00258 typedef typename super::state_type state_type;
00259 typedef typename super::tag_type tag_type;
00260 typedef typename super::char_type char_type;
00261 typedef typename super::char_traits char_traits;
00262
00263 cyclic_generator(unsigned int height, float t_probability,
00264 float f_probability, int seed = time(0))
00265 : super(height, t_probability, f_probability, seed) {
00266 q = t.second = 1;
00267 }
00268
00269 bool first()
00270 {
00271 if (depth == 0) return false;
00272 gen1.seed(graine + q);
00273 for(t.first = EnumerableCharTraits::begin();
00274 t.first != EnumerableCharTraits::end() && gen1() >= t_prob; ++t.first);
00275 if (t.first != EnumerableCharTraits::end()) {
00276 t.second = ((state_type) (gen1() * (++t.second * 2))) + 1;
00277 return true;
00278 }
00279 return false;
00280 }
00281
00282 bool next()
00283 {
00284 if (depth == 0) return false;
00285 for(++t.first; t.first != EnumerableCharTraits::end()
00286 && gen1() >= t_prob; ++t.first);
00287 if (t.first != EnumerableCharTraits::end()) {
00288 t.second = ((state_type) (gen1() * (++t.second * 2))) + 1;
00289 return true;
00290 }
00291 return false;
00292 }
00293
00294 protected:
00295 using super::q;
00296 using super::t;
00297 using super::depth;
00298 using super::gen1;
00299 using super::graine;
00300 using super::t_prob;
00301 };
00302
00303 }
00304
00305
00306 #endif // GENERATOR_CURSOR_H