Cách truyền thống sinh số ngẫu nhiên trong C++ sử dụng rand() và srand() từ thư viện C (<cstdlib>, <ctime>).
Cơ chế
srand(seed): Khởi tạo seed cho bộ sinh số ngẫu nhiên
rand(): Trả về số pseudo-random trong khoảng [0, RAND_MAX]
RAND_MAX: Hằng số tối thiểu 32767
Ví dụ cơ bản: Số ngẫu nhiên 0-99
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
int max = 100;
srand(time(0)); // Seed bằng thời gian hiện tại
cout << "So ngau nhien: " << rand() % max << endl;
}
Kết quả (mỗi lần chạy khác nhau)
So ngau nhien: 51
So ngau nhien: 29
So ngau nhien: 47
Hàm sinh số trong khoảng [min, max]
int random_in_range(int min, int max) {
return min + rand() % (max - min + 1);
}
Nhược điểm của rand()/srand()
| Vấn đề | Mô tả |
| Chất lượng thấp | Thường dùng Linear Congruential Generator (LCG) kém |
| Phân phối không đều | Modulo bias khi dùng % |
| Không an toàn cho crypto | Dễ dự đoán |
| Trạng thái toàn cục | Không thread-safe, khó quản lý nhiều generator |
| RAND_MAX nhỏ | Thường chỉ 32767 |
Cách hiện đại: C++11 <random> (Khuyến nghị)
#include <iostream>
#include <random>
using namespace std;
int main() {
// Engine: Mersenne Twister 19937 - chất lượng cao
random_device rd; // Seed thật ngẫu nhiên (hardware)
mt19937 gen(rd()); // Generator
// Distribution: Phân phối đều [1, 100]
uniform_int_distribution<> dist(1, 100);
for (int i = 0; i < 5; ++i) {
cout << dist(gen) << " ";
}
}
Các phân phối phổ biến
| Phân phối | Dùng cho |
uniform_int_distribution | Số nguyên đều |
uniform_real_distribution | Số thực đều |
normal_distribution | Phân phối chuẩn (Gaussian) |
bernoulli_distribution | True/False với xác suất p |
poisson_distribution | Số sự kiện trong khoảng thời gian |
Tóm tắt
- Code cũ/đơn giản:
srand(time(0)) + rand() % N
- Code hiện đại/chuyên nghiệp:
random_device + mt19937 + uniform_int_distribution
- Luôn tách biệt engine (sinh bit ngẫu nhiên) và distribution (biến đổi phân phối)