Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
RandHelper.h
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2005-2023 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
20//
21/****************************************************************************/
22#pragma once
23#include <config.h>
24#include <cassert>
25#include <vector>
26#include <map>
27#include <random>
28#include <sstream>
29#include <iostream>
30
31
32// ===========================================================================
33// class declaration
34// ===========================================================================
35
36class OptionsCont;
37
38// ===========================================================================
39// class definitions
40// ===========================================================================
46public:
47 inline void seed(const uint64_t seed) {
48 this->state[0] = splitmix64(splitmix64(seed));
49 this->state[1] = splitmix64(this->state[0]);
50 this->state[2] = splitmix64(this->state[1]);
51 this->state[3] = splitmix64(this->state[2]);
52 }
53
54 inline uint64_t operator()() {
55 const uint64_t result = rotl64(this->state[0] + this->state[3], 23) + this->state[0];
56 const uint64_t t = this->state[1] << 17;
57 this->state[2] ^= this->state[0];
58 this->state[3] ^= this->state[1];
59 this->state[1] ^= this->state[2];
60 this->state[0] ^= this->state[3];
61 this->state[2] ^= t;
62 this->state[3] = rotl64(this->state[3], 45);
63 return result;
64 }
65
66 void discard(unsigned long long skip) {
67 while (skip-- > 0) {
68 (*this)();
69 }
70 }
71
72 friend std::ostream& operator<<(std::ostream& os, const XoShiRo256PlusPlus& r) {
73 os << r.state[0] << r.state[1] << r.state[2] << r.state[3];
74 return os;
75 }
76
77 friend std::istream& operator>>(std::istream& is, XoShiRo256PlusPlus& r) {
78 is >> r.state[0] >> r.state[1] >> r.state[2] >> r.state[3];
79 return is;
80 }
81
82
83private:
84 static inline uint64_t rotl64(const uint64_t x, const int k) {
85 return (x << k) | (x >> (64 - k));
86 }
87
88 static inline uint64_t splitmix64(const uint64_t seed) {
89 uint64_t z = (seed + 0x9e3779b97f4a7c15);
90 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
91 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
92 return z ^ (z >> 31);
93 }
94
95 uint64_t state[4];
96
97};
98
99
100//class SumoRNG : public XoShiRo256PlusPlus {
101class SumoRNG : public std::mt19937 {
102public:
103 SumoRNG(const std::string& _id) : id(_id) {}
104
105 unsigned long long int count = 0;
106 std::string id;
107};
108
109
115
116public:
118 static void insertRandOptions(OptionsCont& oc);
119
121 static void initRand(SumoRNG* which = nullptr, const bool random = false, const int seed = 23423);
122
124 static void initRandGlobal(SumoRNG* which = nullptr);
125
127 static double rand(SumoRNG* rng = nullptr);
128
130 static inline double rand(double maxV, SumoRNG* rng = nullptr) {
131 return maxV * rand(rng);
132 }
133
135 static inline double rand(double minV, double maxV, SumoRNG* rng = nullptr) {
136 return minV + (maxV - minV) * rand(rng);
137 }
138
140 static inline int rand(int maxV, SumoRNG* rng = nullptr) {
141 if (rng == nullptr) {
143 }
144 unsigned int usedBits = maxV - 1;
145 usedBits |= usedBits >> 1;
146 usedBits |= usedBits >> 2;
147 usedBits |= usedBits >> 4;
148 usedBits |= usedBits >> 8;
149 usedBits |= usedBits >> 16;
150
151 // Draw numbers until one is found in [0, maxV-1]
152 int result;
153 do {
154 result = (*rng)() & usedBits;
155 rng->count++;
156 } while (result >= maxV);
157 return result;
158 }
159
161 static inline int rand(int minV, int maxV, SumoRNG* rng = nullptr) {
162 return minV + rand(maxV - minV, rng);
163 }
164
166 static inline long long int rand(long long int maxV, SumoRNG* rng = nullptr) {
167 if (maxV <= std::numeric_limits<int>::max()) {
168 return rand((int)maxV, rng);
169 }
170 if (rng == nullptr) {
172 }
173 unsigned long long int usedBits = maxV - 1;
174 usedBits |= usedBits >> 1;
175 usedBits |= usedBits >> 2;
176 usedBits |= usedBits >> 4;
177 usedBits |= usedBits >> 8;
178 usedBits |= usedBits >> 16;
179 usedBits |= usedBits >> 32;
180
181 // Draw numbers until one is found in [0, maxV-1]
182 long long int result;
183 do {
184 result = (((unsigned long long int)(*rng)() << 32) | (*rng)()) & usedBits; // toss unused bits to shorten search
185 rng->count += 2;
186 } while (result >= maxV);
187 return result;
188 }
189
191 static inline long long int rand(long long int minV, long long int maxV, SumoRNG* rng = nullptr) {
192 return minV + rand(maxV - minV, rng);
193 }
194
196 static double randNorm(double mean, double variance, SumoRNG* rng = nullptr);
197
199 static double randExp(double rate, SumoRNG* rng = nullptr);
200
202 template<class T>
203 static inline const T&
204 getRandomFrom(const std::vector<T>& v, SumoRNG* rng = nullptr) {
205 assert(v.size() > 0);
206 return v[rand((int)v.size(), rng)];
207 }
208
210 static std::string saveState(SumoRNG* rng = nullptr) {
211 if (rng == nullptr) {
213 }
214 std::ostringstream oss;
215 if (rng->count < 1000000) { // TODO make this configurable
216 oss << rng->count;
217 } else {
218 oss << (*rng);
219 }
220 return oss.str();
221 }
222
224 static void loadState(const std::string& state, SumoRNG* rng = nullptr) {
225 if (rng == nullptr) {
227 }
228 std::istringstream iss(state);
229 if (state.size() < 10) {
230 iss >> rng->count;
231 rng->discard(rng->count);
232 } else {
233 iss >> (*rng);
234 }
235 }
236
237
238protected:
241
242};
A storage for options typed value containers)
Definition OptionsCont.h:89
Utility functions for using a global, resetable random number generator.
Definition RandHelper.h:114
static SumoRNG myRandomNumberGenerator
the default random number generator to use
Definition RandHelper.h:240
static void loadState(const std::string &state, SumoRNG *rng=nullptr)
load rng state from string
Definition RandHelper.h:224
static double randExp(double rate, SumoRNG *rng=nullptr)
Access to a random number from an exponential distribution.
static long long int rand(long long int minV, long long int maxV, SumoRNG *rng=nullptr)
Returns a random 64 bit integer in [minV, maxV-1].
Definition RandHelper.h:191
static double rand(double minV, double maxV, SumoRNG *rng=nullptr)
Returns a random real number in [minV, maxV)
Definition RandHelper.h:135
static void initRand(SumoRNG *which=nullptr, const bool random=false, const int seed=23423)
Initialises the random number generator with hardware randomness or seed.
static int rand(int minV, int maxV, SumoRNG *rng=nullptr)
Returns a random integer in [minV, maxV-1].
Definition RandHelper.h:161
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
static int rand(int maxV, SumoRNG *rng=nullptr)
Returns a random integer in [0, maxV-1].
Definition RandHelper.h:140
static double randNorm(double mean, double variance, SumoRNG *rng=nullptr)
Access to a random number from a normal distribution.
static std::string saveState(SumoRNG *rng=nullptr)
save rng state to string
Definition RandHelper.h:210
static double rand(double maxV, SumoRNG *rng=nullptr)
Returns a random real number in [0, maxV)
Definition RandHelper.h:130
static void insertRandOptions(OptionsCont &oc)
Initialises the given options container with random number options.
static const T & getRandomFrom(const std::vector< T > &v, SumoRNG *rng=nullptr)
Returns a random element from the given vector.
Definition RandHelper.h:204
static long long int rand(long long int maxV, SumoRNG *rng=nullptr)
Returns a random 64 bit integer in [0, maxV-1].
Definition RandHelper.h:166
static void initRandGlobal(SumoRNG *which=nullptr)
Reads the given random number options and initialises the random number generator in accordance.
std::string id
Definition RandHelper.h:106
SumoRNG(const std::string &_id)
Definition RandHelper.h:103
unsigned long long int count
Definition RandHelper.h:105
A random number generator as proposed here https://prng.di.unimi.it/xoshiro256plusplus....
Definition RandHelper.h:45
uint64_t operator()()
Definition RandHelper.h:54
uint64_t state[4]
Definition RandHelper.h:95
friend std::ostream & operator<<(std::ostream &os, const XoShiRo256PlusPlus &r)
Definition RandHelper.h:72
friend std::istream & operator>>(std::istream &is, XoShiRo256PlusPlus &r)
Definition RandHelper.h:77
void discard(unsigned long long skip)
Definition RandHelper.h:66
static uint64_t rotl64(const uint64_t x, const int k)
Definition RandHelper.h:84
void seed(const uint64_t seed)
Definition RandHelper.h:47
static uint64_t splitmix64(const uint64_t seed)
Definition RandHelper.h:88