int rand(void):返回 [0, RAND_MAX] 偽隨機數 (RAND_MAX 通常 2147483647)。void srand(unsigned seed):設置種子,**全程序只需調用一次**。time_t time(time_t *t):獲取當前秒級時間戳,常作種子來源。
// 錯誤示範
for (int i=0; i<10000; i++) {
srand((unsigned)time(NULL)); // time() 精度 1秒,循環極快 → 種子相同
printf("%d\n", rand()); // 輸出全是同一個數!
}
#include
#include
#include
int main() {
srand((unsigned)time(NULL)); // 僅一次!
for (int i=0; i<10; i++)
printf("%d\n", rand());
return 0;
}
[a, b] (含端點)
int rand_int(int a, int b) {
return a + rand() / (RAND_MAX / (b - a + 1) + 1);
// 或簡單但略有偏差:a + rand() % (b - a + 1)
}
取模法在 RAND_MAX 非 (b-a+1) 倍數時分布不均,除法法更均勻。
[a, b)
double rand_double(double a, double b) {
return a + (double)rand() / RAND_MAX * (b - a);
}
需從 N 個數中無放回抽取 k 個:
// 生成 0..N-1 的隨機排列,取前 k 個
void shuffle(int *arr, int n) {
for (int i = n-1; i > 0; i--) {
int j = rand_int(0, i);
int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
}
// 使用
int pool[10000];
for (int i=0; i<10000; i++) pool[i] = i;
shuffle(pool, 10000);
// pool[0..k-1] 即為 k 個不重複隨機數
k << N 時可用蓄水池采樣 O(k) 空間。rand_r / drand48_r
unsigned int seed = (unsigned)time(NULL);
int r = rand_r(&seed); // 可重入,每線程獨立 seed
/dev/urandom / C++11 rand()**,讀 /dev/urandom 或用 std::mt19937。rand_s (Windows) / getrandom() (Linux)。main 開頭。rand_r 或 C++ 。