SoFunction
Updated on 2025-04-11

C++ implements modern packaging for random number generation

Background knowledge

Generation of random numbers

The C++ standard library provides a powerful and flexible random number tool, mainly composed of the following parts:

  • Random number engine:For examplestd::mt19937, generate a sequence of pseudo-random numbers.
  • distributed:For examplestd::uniform_int_distribution, perform distribution conversion on random numbers.
  • Random number seeds: Used to initialize the random number engine to ensure randomness.

Class design principles

When designing a general random tool class, we can encapsulate common random operations, such as:

  • Generates integers or floating-point numbers in the specified range.
  • Generates boolean values ​​by probability.
  • Randomly disrupt the container.

Class definition and functional decomposition

The following isRandomComplete definition of class:

#include <chrono>
#include <iostream>
#include <random>
#include <algorithm>

struct Random {
    std::mt19937 rnd;

    Random()
        : rnd(std::chrono::steady_clock::now().time_since_epoch().count()) {}
    
    void setSeed(unsigned int seed) {  
        (seed);  
    }

    int operator()(int l, int r) {
        return std::uniform_int_distribution(l, r)(rnd);
    }

    double operator()(double l, double r) {
        return std::uniform_real_distribution(l, r)(rnd);
    }

    bool operator()(double p) {
        return std::bernoulli_distribution(p)(rnd);
    }

    template<typename T>
    void operator()(std::vector<T>& vec) {  
        std::shuffle((), (), rnd);  
    }
};

Below, we will disassemble and explain its core parts one by one.

Initialization of random number engine

Random()
    : rnd(std::chrono::steady_clock::now().time_since_epoch().count()) {}
  • std::mt19937
    std::mt19937It is a pseudo-random number generator based on Mason's rotation algorithm, with good performance and randomness. Its name comes from the generation of a periodic sequence of 19937 bits.

  • Initialize seeds

    • The current timestamp (in nanoseconds) is used as the seed by default.
    • Timestamp passstd::chrono::steady_clockGet to ensure that the seeds are out of sync.

Set random number seeds

void setSeed(unsigned int seed) {  
    (seed);  
}
  • Seed control randomness
    • Given the same seed, the random number generation sequence is deterministic.
    • This feature is ideal for debugging and reproducible experiments.

Generate random integers

int operator()(int l, int r) {
    return std::uniform_int_distribution(l, r)(rnd);
}
  • std::uniform_int_distribution

    • Used to generate uniformly distributed integers.
    • The constructor parameters are upper and lower bounds[l, r]
  • Call method
    Distribute objectsdistis a callable object. By passing in the random enginernd, a random number can be generated.

Example:

Random random;
int number = random(1, 10); // Generate random integers in the range [1, 10]

Generate random floating point numbers

double operator()(double l, double r) {
    return std::uniform_real_distribution(l, r)(rnd);
}
  • std::uniform_real_distribution
    • Used to generate uniformly distributed floating point numbers.
    • The constructor parameters are upper and lower bounds[l, r), that is, the lower realm is closed and the upper realm is opened.

Example:

Random random;
double value = random(0.0, 1.0); // Generate random floating point numbers in the range [0.0, 1.0)

Generate boolean values ​​by probability

bool operator()(double p) {
    return std::bernoulli_distribution(p)(rnd);
}
  • std::bernoulli_distribution
    • According to the given probabilitypreturntrueorfalse
    • Constructor parameterspIndicates returntrueThe probability of  , range[0, 1]

Example:

Random random;
bool result = random(0.7); // 70% probability returns true, 30% probability returns false

Randomly disrupt containers

template<typename T>
void operator()(std::vector<T>& vec) {  
    std::shuffle((), (), rnd);  
}
  • std::shuffle

    • Random arrangement of container elements.
    • userndEngine, ensure pseudo-randomity.
  • Template design
    Allow for anystd::vector<T>Types of containers operate.

Example:

Random random;
std::vector&lt;int&gt; vec = {1, 2, 3, 4, 5};
random(vec); // Random disrupt vec

Use scenarios

Random assignment of tasks

Suppose there are 10 tasks that need to be randomly assigned to 3 employees:

Random random;
std::vector<int> tasks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
random(tasks);

for (int i = 0; i < (); ++i) {
    std::cout << "Task " << tasks[i] << " -> Employee " << random(1, 3) << "\n";
}

Simulation coin toss

Random random;
int heads = 0, tails = 0;

for (int i = 0; i &lt; 100; ++i) {
    if (random(0.5)) {
        ++heads; // front    } else {
        ++tails; // The opposite    }
}

std::cout &lt;&lt; "Heads: " &lt;&lt; heads &lt;&lt; ", Tails: " &lt;&lt; tails &lt;&lt; "\n";

summary

Through the analysis of this article, we have a deeper understanding of the following aspectsRandomClass design and implementation:

  • usestd::mt19937The random number engine generates high-quality pseudo-random numbers.
  • Generate random numbers of specific ranges or distributions using distribution objects in the C++ standard library.
  • Encapsulate commonly used random functions to improve code readability and reusability.

This is the end of this article about C++'s modern packaging for random number generation. For more relevant content on C++'s modern packaging, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!