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-2025 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
25#include <cassert>
26#include <vector>
27#include <map>
28#include <random>
29#include <sstream>
30#include <iostream>
31#include <algorithm>
32
33// TODO make this configurable
34#define SAVE_ONLY_COUNT 1000000
35
36// ===========================================================================
37// class declaration
38// ===========================================================================
39
40class OptionsCont;
41
42// ===========================================================================
43// class definitions
44// ===========================================================================
50public:
51 inline void seed(const uint64_t seed) {
52 this->state[0] = splitmix64(splitmix64(seed));
53 this->state[1] = splitmix64(this->state[0]);
54 this->state[2] = splitmix64(this->state[1]);
55 this->state[3] = splitmix64(this->state[2]);
56 }
57
58 inline uint64_t operator()() {
59 const uint64_t result = rotl64(this->state[0] + this->state[3], 23) + this->state[0];
60 const uint64_t t = this->state[1] << 17;
61 this->state[2] ^= this->state[0];
62 this->state[3] ^= this->state[1];
63 this->state[1] ^= this->state[2];
64 this->state[0] ^= this->state[3];
65 this->state[2] ^= t;
66 this->state[3] = rotl64(this->state[3], 45);
67 return result;
68 }
69
70 void discard(unsigned long long skip) {
71 while (skip-- > 0) {
72 (*this)();
73 }
74 }
75
76 friend std::ostream& operator<<(std::ostream& os, const XoShiRo256PlusPlus& r) {
77 os << r.state[0] << r.state[1] << r.state[2] << r.state[3];
78 return os;
79 }
80
81 friend std::istream& operator>>(std::istream& is, XoShiRo256PlusPlus& r) {
82 is >> r.state[0] >> r.state[1] >> r.state[2] >> r.state[3];
83 return is;
84 }
85
86
87private:
88 static inline uint64_t rotl64(const uint64_t x, const int k) {
89 return (x << k) | (x >> (64 - k));
90 }
91
92 static inline uint64_t splitmix64(const uint64_t seed) {
93 uint64_t z = (seed + 0x9e3779b97f4a7c15);
94 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
95 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
96 return z ^ (z >> 31);
97 }
98
99 uint64_t state[4];
100
101};
102
103
104//class SumoRNG : public XoShiRo256PlusPlus {
105class SumoRNG : public std::mt19937 {
106public:
107 SumoRNG(const std::string& _id) : id(_id) {}
108
109 unsigned long long int count = 0;
110 std::string id;
111};
112
113
119
120public:
122 static void insertRandOptions(OptionsCont& oc);
123
125 static void initRand(SumoRNG* which = nullptr, const bool random = false, const int seed = 23423);
126
128 static void initRandGlobal(SumoRNG* which = nullptr);
129
131 static double rand(SumoRNG* rng = nullptr);
132
134 static inline double rand(double maxV, SumoRNG* rng = nullptr) {
135 return maxV * rand(rng);
136 }
137
139 static inline double rand(double minV, double maxV, SumoRNG* rng = nullptr) {
140 return minV + (maxV - minV) * rand(rng);
141 }
142
144 static inline int rand(int maxV, SumoRNG* rng = nullptr) {
145 if (rng == nullptr) {
147 }
148 unsigned int usedBits = maxV - 1;
149 usedBits |= usedBits >> 1;
150 usedBits |= usedBits >> 2;
151 usedBits |= usedBits >> 4;
152 usedBits |= usedBits >> 8;
153 usedBits |= usedBits >> 16;
154
155 // Draw numbers until one is found in [0, maxV-1]
156 int result;
157 do {
158 result = (*rng)() & usedBits;
159 rng->count++;
160 } while (result >= maxV);
161 return result;
162 }
163
165 static inline int rand(int minV, int maxV, SumoRNG* rng = nullptr) {
166 return minV + rand(maxV - minV, rng);
167 }
168
170 static inline long long int rand(long long int maxV, SumoRNG* rng = nullptr) {
171 if (maxV <= std::numeric_limits<int>::max()) {
172 return rand((int)maxV, rng);
173 }
174 if (rng == nullptr) {
176 }
177 unsigned long long int usedBits = maxV - 1;
178 usedBits |= usedBits >> 1;
179 usedBits |= usedBits >> 2;
180 usedBits |= usedBits >> 4;
181 usedBits |= usedBits >> 8;
182 usedBits |= usedBits >> 16;
183 usedBits |= usedBits >> 32;
184
185 // Draw numbers until one is found in [0, maxV-1]
186 long long int result;
187 do {
188 result = (((unsigned long long int)(*rng)() << 32) | (*rng)()) & usedBits; // toss unused bits to shorten search
189 rng->count += 2;
190 } while (result >= maxV);
191 return result;
192 }
193
195 static inline long long int rand(long long int minV, long long int maxV, SumoRNG* rng = nullptr) {
196 return minV + rand(maxV - minV, rng);
197 }
198
200 static double randNorm(double mean, double variance, SumoRNG* rng = nullptr);
201
203 static double randExp(double rate, SumoRNG* rng = nullptr);
204
206 template<class T>
207 static inline const T&
208 getRandomFrom(const std::vector<T>& v, SumoRNG* rng = nullptr) {
209 assert(v.size() > 0);
210 return v[rand((int)v.size(), rng)];
211 }
212
214 static std::string saveState(SumoRNG* rng = nullptr) {
215 if (rng == nullptr) {
217 }
218 std::ostringstream oss;
219 oss << rng->count;
220 if (rng->count >= SAVE_ONLY_COUNT) {
221 oss << " " << (*rng);
222 }
223 return oss.str();
224 }
225
227 static void loadState(const std::string& state, SumoRNG* rng = nullptr) {
228 if (rng == nullptr) {
230 }
231 std::istringstream iss(state);
232 iss >> rng->count;
233 if (rng->count < SAVE_ONLY_COUNT) {
234 rng->discard(rng->count);
235 } else {
236 iss >> (*rng);
237 }
238 }
239
240 template<class T>
241 static void shuffle(std::vector<T>& v, SumoRNG* rng = nullptr) {
242 for (int i = (int)(v.size() - 1); i > 0; --i) {
243 std::swap(*(v.begin() + i), *(v.begin() + rand(i, rng)));
244 }
245 }
246
247 static long long int count() {
249 }
250
251protected:
254
255};
#define SAVE_ONLY_COUNT
Definition RandHelper.h:34
A storage for options typed value containers)
Definition OptionsCont.h:89
Utility functions for using a global, resetable random number generator.
Definition RandHelper.h:118
static SumoRNG myRandomNumberGenerator
the default random number generator to use
Definition RandHelper.h:253
static void loadState(const std::string &state, SumoRNG *rng=nullptr)
load rng state from string
Definition RandHelper.h:227
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:195
static double rand(double minV, double maxV, SumoRNG *rng=nullptr)
Returns a random real number in [minV, maxV)
Definition RandHelper.h:139
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:165
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:144
static double randNorm(double mean, double variance, SumoRNG *rng=nullptr)
Access to a random number from a normal distribution.
static long long int count()
Definition RandHelper.h:247
static std::string saveState(SumoRNG *rng=nullptr)
save rng state to string
Definition RandHelper.h:214
static double rand(double maxV, SumoRNG *rng=nullptr)
Returns a random real number in [0, maxV)
Definition RandHelper.h:134
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:208
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:170
static void shuffle(std::vector< T > &v, SumoRNG *rng=nullptr)
Definition RandHelper.h:241
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:110
SumoRNG(const std::string &_id)
Definition RandHelper.h:107
unsigned long long int count
Definition RandHelper.h:109
A random number generator as proposed here https://prng.di.unimi.it/xoshiro256plusplus....
Definition RandHelper.h:49
uint64_t operator()()
Definition RandHelper.h:58
uint64_t state[4]
Definition RandHelper.h:99
friend std::ostream & operator<<(std::ostream &os, const XoShiRo256PlusPlus &r)
Definition RandHelper.h:76
friend std::istream & operator>>(std::istream &is, XoShiRo256PlusPlus &r)
Definition RandHelper.h:81
void discard(unsigned long long skip)
Definition RandHelper.h:70
static uint64_t rotl64(const uint64_t x, const int k)
Definition RandHelper.h:88
void seed(const uint64_t seed)
Definition RandHelper.h:51
static uint64_t splitmix64(const uint64_t seed)
Definition RandHelper.h:92
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.hpp:21884