C++11stlintermediate
Random Engines (C++11 Addition)
C++11 · Modern Revolution · Compiler flag: -std=c++11
Explanation
C++11 provides several random engine types including `linear_congruential_engine`, `mersenne_twister_engine`, `subtract_with_carry_engine`, and engine adaptors like `discard_block_engine`, `independent_bits_engine`, and `shuffle_order_engine`. Predefined typedefs include `minstd_rand0`, `minstd_rand`, `ranlux24_base`, `ranlux48_base`, `ranlux24`, `ranlux48`, and `knuth_b`.
Real-World Scenario
Choose between lightweight (LCG) and high-quality (Mersenne Twister) engines based on performance versus quality requirements.
Quick Snippet
snippet.cpp
#include <random>
std::minstd_rand lcg(42); // lightweight LCG engine
std::ranlux24 rl(42); // higher quality, slower
std::knuth_b kb(42); // shuffle-order adaptor
int a = lcg(), b = rl(), c = kb();Full Example
random_engines.cpp
// CodeNebula - C++11 Example: Random Engines (linear_congruential, subtract_with_carry, adaptors)
// Compile: g++ -std=c++11 -Wall -Wextra -o example random_engines.cpp
// C++11 provides three engine families and two adaptors. Each offers
// different trade-offs in speed, quality, and state size. The predefined
// typedefs (minstd_rand, ranlux24, etc.) are ready to use.
#include <iostream>
#include <random>
#include <iomanip>
#include <vector>
// Helper: print 5 values from any engine
template<typename Engine>
void show_values(const char* name, Engine eng) {
std::cout << name << ": ";
for (int i = 0; i < 5; ++i) {
std::cout << eng() << " ";
}
std::cout << std::endl;
}
int main() {
const unsigned seed = 42;
// === Linear Congruential Engines ===
// Formula: x(n+1) = (a * x(n) + c) mod m
// Fast, small state (single integer), lower quality
std::cout << "=== Linear Congruential ===" << std::endl;
show_values("minstd_rand0", std::minstd_rand0(seed));
show_values("minstd_rand ", std::minstd_rand(seed));
// Custom linear congruential engine
using my_lcg = std::linear_congruential_engine<
unsigned long, 16807, 0, 2147483647>;
show_values("custom LCG ", my_lcg(seed));
// === Subtract-with-Carry Engines ===
// Lagged Fibonacci variant; larger state, better quality
std::cout << "\n=== Subtract-with-Carry ===" << std::endl;
// ranlux24_base: underlying engine for ranlux24
std::ranlux24_base rwc24(seed);
std::cout << "ranlux24_base: ";
for (int i = 0; i < 5; ++i) std::cout << rwc24() << " ";
std::cout << std::endl;
// ranlux48_base: 48-bit subtract_with_carry
std::ranlux48_base rwc48(seed);
std::cout << "ranlux48_base: ";
for (int i = 0; i < 5; ++i) std::cout << rwc48() << " ";
std::cout << std::endl;
// === Discard Block Adaptor ===
// Improves quality by generating P values and keeping R
std::cout << "\n=== Discard Block Adaptor ===" << std::endl;
std::ranlux24 rl24(seed); // discard_block_engine<ranlux24_base, 223, 23>
std::cout << "ranlux24: ";
for (int i = 0; i < 5; ++i) std::cout << rl24() << " ";
std::cout << std::endl;
std::ranlux48 rl48(seed); // discard_block_engine<ranlux48_base, 389, 11>
std::cout << "ranlux48: ";
for (int i = 0; i < 5; ++i) std::cout << rl48() << " ";
std::cout << std::endl;
// === Shuffle Order Adaptor ===
// Maintains a table of K values, outputs randomly selected entries
std::cout << "\n=== Shuffle Order Adaptor ===" << std::endl;
std::knuth_b kb(seed); // shuffle_order_engine<minstd_rand0, 256>
std::cout << "knuth_b: ";
for (int i = 0; i < 5; ++i) std::cout << kb() << " ";
std::cout << std::endl;
// === Comparison: distribution quality ===
std::cout << "\n=== Distribution Test [0,9] histogram ===" << std::endl;
std::minstd_rand lcg(seed);
std::uniform_int_distribution<int> dist(0, 9);
std::vector<int> counts(10, 0);
for (int i = 0; i < 10000; ++i) ++counts[dist(lcg)];
for (int i = 0; i < 10; ++i) {
std::cout << " " << i << ": " << std::setw(4) << counts[i]
<< " " << std::string(counts[i] / 100, '#') << std::endl;
}
return 0;
}
// Expected output (exact values depend on seed):
// === Linear Congruential ===
// minstd_rand0: <5 values>
// minstd_rand : <5 values>
// custom LCG : <5 values>
//
// === Subtract-with-Carry ===
// ranlux24_base: <5 values>
// ranlux48_base: <5 values>
//
// === Discard Block Adaptor ===
// ranlux24: <5 values>
// ranlux48: <5 values>
//
// === Shuffle Order Adaptor ===
// knuth_b: <5 values>
//
// === Distribution Test [0,9] histogram ===
// 0: ~1000 ##########
// 1: ~1000 ##########
// ...
Run command
g++ -std=c++11 -Wall -Wextra -o example random_engines.cpp