Eclipse SUMO - Simulation of Urban MObility
RandHelper.h
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2005-2022 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// ===========================================================================
34// class definitions
35// ===========================================================================
41public:
42 inline void seed(const uint64_t seed) {
43 this->state[0] = splitmix64(splitmix64(seed));
44 this->state[1] = splitmix64(this->state[0]);
45 this->state[2] = splitmix64(this->state[1]);
46 this->state[3] = splitmix64(this->state[2]);
47 }
48
49 inline uint64_t operator()() {
50 const uint64_t result = rotl64(this->state[0] + this->state[3], 23) + this->state[0];
51 const uint64_t t = this->state[1] << 17;
52 this->state[2] ^= this->state[0];
53 this->state[3] ^= this->state[1];
54 this->state[1] ^= this->state[2];
55 this->state[0] ^= this->state[3];
56 this->state[2] ^= t;
57 this->state[3] = rotl64(this->state[3], 45);
58 return result;
59 }
60
61 void discard(unsigned long long skip) {
62 while (skip-- > 0) {
63 (*this)();
64 }
65 }
66
67 friend std::ostream& operator<<(std::ostream& os, const XoShiRo256PlusPlus& r) {
68 os << r.state[0] << r.state[1] << r.state[2] << r.state[3];
69 return os;
70 }
71
72 friend std::istream& operator>>(std::istream& is, XoShiRo256PlusPlus& r) {
73 is >> r.state[0] >> r.state[1] >> r.state[2] >> r.state[3];
74 return is;
75 }
76
77
78private:
79 static inline uint64_t rotl64(const uint64_t x, const int k) {
80 return (x << k) | (x >> (64 - k));
81 }
82
83 static inline uint64_t splitmix64(const uint64_t seed) {
84 uint64_t z = (seed + 0x9e3779b97f4a7c15);
85 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
86 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
87 return z ^ (z >> 31);
88 }
89
90 uint64_t state[4];
91
92};
93
94
95//class SumoRNG : public XoShiRo256PlusPlus {
96class SumoRNG : public std::mt19937 {
97public:
98 SumoRNG(const std::string& _id) : id(_id) {}
99
100 unsigned long long int count = 0;
101 std::string id;
102};
103
104
110public:
112 static void insertRandOptions();
113
115 static void initRand(SumoRNG* which = nullptr, const bool random = false, const int seed = 23423);
116
118 static void initRandGlobal(SumoRNG* which = nullptr);
119
121 static double rand(SumoRNG* rng = nullptr);
122
124 static inline double rand(double maxV, SumoRNG* rng = nullptr) {
125 return maxV * rand(rng);
126 }
127
129 static inline double rand(double minV, double maxV, SumoRNG* rng = nullptr) {
130 return minV + (maxV - minV) * rand(rng);
131 }
132
134 static inline int rand(int maxV, SumoRNG* rng = nullptr) {
135 if (rng == nullptr) {
137 }
138 unsigned int usedBits = maxV - 1;
139 usedBits |= usedBits >> 1;
140 usedBits |= usedBits >> 2;
141 usedBits |= usedBits >> 4;
142 usedBits |= usedBits >> 8;
143 usedBits |= usedBits >> 16;
144
145 // Draw numbers until one is found in [0, maxV-1]
146 int result;
147 do {
148 result = (*rng)() & usedBits;
149 rng->count++;
150 } while (result >= maxV);
151 return result;
152 }
153
155 static inline int rand(int minV, int maxV, SumoRNG* rng = nullptr) {
156 return minV + rand(maxV - minV, rng);
157 }
158
160 static inline long long int rand(long long int maxV, SumoRNG* rng = nullptr) {
161 if (maxV <= std::numeric_limits<int>::max()) {
162 return rand((int)maxV, rng);
163 }
164 if (rng == nullptr) {
166 }
167 unsigned long long int usedBits = maxV - 1;
168 usedBits |= usedBits >> 1;
169 usedBits |= usedBits >> 2;
170 usedBits |= usedBits >> 4;
171 usedBits |= usedBits >> 8;
172 usedBits |= usedBits >> 16;
173 usedBits |= usedBits >> 32;
174
175 // Draw numbers until one is found in [0, maxV-1]
176 long long int result;
177 do {
178 result = (((unsigned long long int)(*rng)() << 32) | (*rng)()) & usedBits; // toss unused bits to shorten search
179 rng->count += 2;
180 } while (result >= maxV);
181 return result;
182 }
183
185 static inline long long int rand(long long int minV, long long int maxV, SumoRNG* rng = nullptr) {
186 return minV + rand(maxV - minV, rng);
187 }
188
190 static double randNorm(double mean, double variance, SumoRNG* rng = nullptr);
191
193 static double randExp(double rate, SumoRNG* rng = nullptr);
194
196 template<class T>
197 static inline const T&
198 getRandomFrom(const std::vector<T>& v, SumoRNG* rng = nullptr) {
199 assert(v.size() > 0);
200 return v[rand((int)v.size(), rng)];
201 }
202
204 static std::string saveState(SumoRNG* rng = nullptr) {
205 if (rng == nullptr) {
207 }
208 std::ostringstream oss;
209 if (rng->count < 1000000) { // TODO make this configurable
210 oss << rng->count;
211 } else {
212 oss << (*rng);
213 }
214 return oss.str();
215 }
216
218 static void loadState(const std::string& state, SumoRNG* rng = nullptr) {
219 if (rng == nullptr) {
221 }
222 std::istringstream iss(state);
223 if (state.size() < 10) {
224 iss >> rng->count;
225 rng->discard(rng->count);
226 } else {
227 iss >> (*rng);
228 }
229 }
230
231
232protected:
235
236};
Utility functions for using a global, resetable random number generator.
Definition: RandHelper.h:109
static SumoRNG myRandomNumberGenerator
the default random number generator to use
Definition: RandHelper.h:234
static void loadState(const std::string &state, SumoRNG *rng=nullptr)
load rng state from string
Definition: RandHelper.h:218
static double randExp(double rate, SumoRNG *rng=nullptr)
Access to a random number from an exponential distribution.
Definition: RandHelper.cpp:150
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:185
static double rand(double minV, double maxV, SumoRNG *rng=nullptr)
Returns a random real number in [minV, maxV)
Definition: RandHelper.h:129
static void initRand(SumoRNG *which=nullptr, const bool random=false, const int seed=23423)
Initialises the random number generator with hardware randomness or seed.
Definition: RandHelper.cpp:74
static int rand(int minV, int maxV, SumoRNG *rng=nullptr)
Returns a random integer in [minV, maxV-1].
Definition: RandHelper.h:155
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
static int rand(int maxV, SumoRNG *rng=nullptr)
Returns a random integer in [0, maxV-1].
Definition: RandHelper.h:134
static double randNorm(double mean, double variance, SumoRNG *rng=nullptr)
Access to a random number from a normal distribution.
Definition: RandHelper.cpp:137
static void insertRandOptions()
Initialises the given options container with random number options.
Definition: RandHelper.cpp:58
static std::string saveState(SumoRNG *rng=nullptr)
save rng state to string
Definition: RandHelper.h:204
static double rand(double maxV, SumoRNG *rng=nullptr)
Returns a random real number in [0, maxV)
Definition: RandHelper.h:124
static const T & getRandomFrom(const std::vector< T > &v, SumoRNG *rng=nullptr)
Returns a random element from the given vector.
Definition: RandHelper.h:198
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:160
static void initRandGlobal(SumoRNG *which=nullptr)
Reads the given random number options and initialises the random number generator in accordance.
Definition: RandHelper.cpp:87
std::string id
Definition: RandHelper.h:101
SumoRNG(const std::string &_id)
Definition: RandHelper.h:98
unsigned long long int count
Definition: RandHelper.h:100
A random number generator as proposed here https://prng.di.unimi.it/xoshiro256plusplus....
Definition: RandHelper.h:40
uint64_t operator()()
Definition: RandHelper.h:49
uint64_t state[4]
Definition: RandHelper.h:90
friend std::ostream & operator<<(std::ostream &os, const XoShiRo256PlusPlus &r)
Definition: RandHelper.h:67
friend std::istream & operator>>(std::istream &is, XoShiRo256PlusPlus &r)
Definition: RandHelper.h:72
void discard(unsigned long long skip)
Definition: RandHelper.h:61
static uint64_t rotl64(const uint64_t x, const int k)
Definition: RandHelper.h:79
void seed(const uint64_t seed)
Definition: RandHelper.h:42
static uint64_t splitmix64(const uint64_t seed)
Definition: RandHelper.h:83