C++ Standard Library <random>
In the C++ standard library<random>The header file provides a set of tools for generating random numbers, covering everything from simple uniform distributions to complex discrete distributions, offering a wide range of options for applications that require random numbers. These tools are very useful in fields such as simulation, game development, and cryptographic algorithms.
<random>It not only supports generating pseudo-random numbers, but also supports seed control, various probability distributions, etc., allowing developers to flexibly generate sequences of random numbers that meet specific requirements.
<random>The library consists of the following three main components:
- Random number engine: The core of generating pseudo-random numbers, used to control the reproducibility and randomness of the generation process.
- Random number distribution: Controls the type of probability distribution that the generated values follow.
- Random number adapter: allows adjusting engine behavior, such as
discard_blockand other adapters.
In C++, random number generators (Random Number Generator, RNG) can be divided into two main categories:
- Pseudorandom number generator: They use deterministic algorithms to generate seemingly random sequences. These sequences are theoretically predictable, but are generally random enough for most applications.
- True random number generator: They generate random numbers based on physical processes (such as thermal noise, radioactive decay, etc.), but the C++ standard library does not directly provide such generators.
Common random number engines
| Engine | Description |
|---|---|
std::default_random_engine | Default random number engine, with an implementation that depends on the specific compiler. |
std::minstd_rand | Linear congruential engine, producing a uniform sequence of pseudo-random numbers. |
std::mt19937 | Mersenne Twister algorithm, suitable for general-purpose random number generation. |
std::mt19937_64 | 64-bit Mersenne Twister algorithm. |
std::ranlux24_base | Simplified subtract-with-carry engine, used for high-quality generation. |
std::knuth_b | Knuth shuffle random number generator. |
Common engines such asstd::mt19937Because of its fast generation speed and high generation quality, it is a widely recommended random number generation engine. The generator can also useseed()Method to specify the seed, facilitating the generation of reproducible pseudo-random sequences.
Random number distribution types
1. Uniform distribution
| Distribution | Description |
|---|---|
std::uniform_int_distribution | Generates a uniform distribution over a range of integers. |
std::uniform_real_distribution | Generates a uniform distribution over a range of floating-point numbers. |
std::mt19937 gen(seed); std::uniform_int_distribution<int> dist(1, 100); // 生成 1 到 100 间的整数 int random_int = dist(gen);
2. Normal distribution
| Distribution | Description |
|---|---|
std::normal_distribution | Standard normal distribution, centrally symmetric, often used to simulate natural phenomena. |
std::lognormal_distribution | Lognormal distribution. |
std::mt19937 gen(seed); std::normal_distribution<> dist(0, 1); // 平均值为0,标准差为1 double random_normal = dist(gen);
3. Discrete distribution
| Distribution | Description |
|---|---|
std::discrete_distribution | Generates random numbers as integers with a set of specific probabilities. |
std::bernoulli_distribution | Bernoulli distribution, which only generatestrueorfalse。 |
std::binomial_distribution | Binomial distribution. |
std::mt19937 gen(seed);
std::discrete_distribution<int> dist({40, 10, 50}); // 概率为40%、10%、50%
int random_discrete = dist(gen);
Syntax
Usage<random>The basic steps of the library are as follows:
- Include Header Files
<random>。 - Create a random number generator object.
- Use the distribution class to generate random numbers.
Example
Generate basic random numbers
Example
#include <random>
int main() {
// Use a random device to create a random seed
std::random_device rd;
// Use the random seed to initialize the Mersenne Twister random number generator
std::mt19937 generator(rd());
// Generate a random number
std::cout << "Random number: " << generator() << std::endl;
return 0;
}
Output result:
Random number: 3499211612
Note:Each time the program runs, the generated random numbers may be different.
Using uniform distribution
Example
#include <random>
int main() {
// Create a random number generator
std::mt19937 generator;
// Create a uniformly distributed random number generator with a range from 1 to 10
std::uniform_int_distribution<int> distribution(1, 10);
// Generate and print 5 random numbers
for (int i = 0; i < 5; ++i) {
std::cout << "Random number: " << distribution(generator) << std::endl;
}
return 0;
}
Output result:
Random number: 7 Random number: 10 Random number: 6 Random number: 2 Random number: 4
Each time the program runs, the output random number sequence may be different.
Using normal distribution
Example
#include <random>
#include <iomanip>
int main() {
// Create a random number generator
std::mt19937 generator;
// Create a normally distributed random number generator with mean 0 and standard deviation 1
std::normal_distribution<double> distribution(0.0, 1.0);
// Set the output format to two decimal places
std::cout << std::fixed << std::setprecision(2);
// Generate and print 5 random numbers
for (int i = 0; i < 5; ++i) {
std::cout << "Random number: " << distribution(generator) << std::endl;
}
return 0;
}
Random number: -0.15 Random number: 0.13 Random number: -1.87 Random number: 0.46 Random number: -0.21
Using the mt19937 engine to generate random numbers with different distributions:
Example
#include <random>
int main() {
// 1. Set the seed and random number engine
std::random_device rd; // Random device generates the seed
std::mt19937 gen(rd()); // Mersenne Twister engine
// 2. Uniformly distributed integers
std::uniform_int_distribution<> dist_int(1, 100);
std::cout << "Uniform integer: " << dist_int(gen) << std::endl;
// 3. Uniformly distributed floating-point numbers
std::uniform_real_distribution<> dist_real(0.0, 1.0);
std::cout << "Uniform real: " << dist_real(gen) << std::endl;
// 4. Normal distribution
std::normal_distribution<> dist_normal(0, 1);
std::cout << "Normal: " << dist_normal(gen) << std::endl;
// 5. Discrete distribution
std::discrete_distribution<> dist_discrete({10, 20, 70});
std::cout << "Discrete: " << dist_discrete(gen) << std::endl;
return 0;
}
Random number adapter
Random number adapters allow adjusting the generation behavior; there are two main types of adapters:
std::discard_block_engine: Discards a certain number of generated values and retains only those at specified intervals, used to reduce randomness.std::independent_bits_engine: Generates random numbers with a specified number of bits, making it easy to directly generate binary data.
Example
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::discard_block_engine<std::mt19937, 3, 2> discard_engine(gen);
std::cout << "Discard block random number: " << discard_engine() << std::endl;
return 0;
}
Common usage
- Use a seed to generate a reproducible random sequence: specifying the same seed makes each run generate the same sequence.
- Generate random numbers with different distributions: Choose a distribution function that matches the application scenario to better simulate real-world problems.
- Adjusting generator performance: Use different random engines to balance generation performance and accuracy.