C++11 cung cấp thư viện <random> hiện đại, thay thế hoàn toàn rand()/srand() cũ. Thư viện này tách biệt engine (bộ sinh bit) và distribution (phân phối thống kê).
Các thành phần chính
| Loại | Ví dụ | Mô tả |
| Engine | mt19937, mt19937_64 | Mersenne Twister - nhanh, chất lượng cao, chu kỳ 2¹⁹⁹³⁷-1 |
| Engine | random_device | Nguồn entropy thật (hardware), dùng để seed |
| Distribution | uniform_int_distribution | Số nguyên phân phối đều |
| Distribution | uniform_real_distribution | Số thực phân phối đều |
| Distribution | normal_distribution | Phân phối chuẩn (Gaussian) |
Ví dụ: Số thực ngẫu nhiên [20.0, 22.0]
#include <random>
#include <iostream>
using namespace std;
int main() {
// 1. Nguồn entropy để seed
random_device rd;
// 2. Engine: Mersenne Twister 32-bit
mt19937 mt(rd());
// 3. Distribution: Số thực đều [20, 22]
uniform_real_distribution<double> dist(20.0, 22.0);
// 4. Sinh 20 số
for (int i = 0; i < 20; ++i) {
cout << dist(mt) << endl;
}
}
Kết quả mẫu
21.5311
21.7195
21.0961
21.9679
21.197
21.2989
20.6333
20.441
20.7124
20.2654
21.1877
20.4824
20.0575
20.9432
21.222
21.162
21.1029
20.2253
21.5669
20.3357
Ví dụ: Số nguyên ngẫu nhiên [1, 6] (tung xúc xắc)
#include <random>
#include <iostream>
int main() {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> die(1, 6); // [1, 6]
for (int i = 0; i < 10; ++i) {
cout << die(gen) << " ";
}
}
Ví dụ: Phân phối chuẩn (Normal/Gaussian)
#include <random>
#include <iostream>
#include <map>
int main() {
random_device rd;
mt19937 gen(rd());
normal_distribution<> dist(5.0, 2.0); // mean=5, stddev=2
map<int, int> hist;
for (int i = 0; i < 10000; ++i) {
++hist[static_cast<int>(dist(gen))];
}
for (auto [val, count] : hist) {
cout << val << ": " << string(count / 200, '*') << endl;
}
}
Best Practices
- Không tạo engine mới mỗi lần — tốn chi phí, giảm chất lượng ngẫu nhiên
- Dùng random_device để seed một lần — không seed bằng time(0)
- Thread-local engine cho multi-thread:
thread_local mt19937 gen(random_device{}());
uniform_int_distribution<> dist(1, 100);
int random_number() {
return dist(gen); // An toàn thread
}
So sánh nhanh
| Đặc điểm | rand()/srand() | <random> (C++11) |
| Chất lượng ngẫu nhiên | Thấp (LCG) | Cao (MT19937) |
| Phân phối | Chỉ đều cơ bản | Nhiều loại (normal, poisson...) |
| Thread safety | Không | Có (thread_local engine) |
| Seed | time(0) - yếu | random_device - mạnh |
| Type safety | Không | Có (template) |
Kết luận
Luôn dùng <random> cho code C++11 trở lên. Chỉ dùng rand() cho code legacy hoặc bài tập đơn giản.