工程模擬、加密系統常需大量高品質隨機數。標準 `rand()` 週期短、相關性強、種子敏感。本文提出「預計算隨機池 + 索引跳躍」混合策略:離線用 Matlab 生成高品質隨機數表,線上 O(1) 存取,兼顧統計特性與效能。
0.1234 0.5678 0.9012 ... (10 個/行)
0.3456 0.7890 0.2345 ...
...
共 100 行 = 1000 個數值,索引 0~999
void CRandomArrayFromTxt::GetRandomArrayFromTxt(
int count, double* output,
int lines, int cols, int spacing)
{
CStdioFile file("random_pool.txt", CFile::modeRead | CFile::typeText);
srand((unsigned)time(NULL));
int startIdx = rand() % lines; // 0~999
int startRow = startIdx / cols;
int startCol = startIdx % cols;
int rowsNeeded = (count + startCol - 1) / cols + 1;
// 定位到起始行
CString line;
for (int i = 0; i < startRow; i++) file.ReadString(line);
int collected = 0;
for (int r = 0; r < rowsNeeded && collected < count; r++) {
if (startRow + r >= lines) file.SeekToBegin(); // 循環
file.ReadString(line);
// 解析行內數值 (固定間距分隔)
int col = (r == 0) ? startCol : 0;
for (; col < cols && collected < count; col++) {
int pos = line.Find(" "); // 3 空格分隔
output[collected++] = atof(pos == -1 ? line : line.Left(pos));
if (pos != -1) line = line.Right(line.GetLength() - pos - spacing);
}
}
file.Close();
}
| 參數 | 說明 | 建議值 |
|---|---|---|
| 池大小 | 總隨機數量 | ≥ 10000 (視應用規模) |
| 分佈類型 | 常態/均勻/指數等 | 按領域需求 |
| 行列結構 | 便於索引計算 | 100×100 或 1000×10 |
| 分隔符 | 固定寬度解析 | 3~4 空格或 Tab |
// 讀取值作為下一輪種子
unsigned seed = (unsigned)time(NULL);
for (int i = 0; i < count; i++) {
srand(seed);
int idx = rand() % POOL_SIZE;
output[i] = pool[idx];
seed = (unsigned)(pool[idx] * 1e9); // 浮點數轉種子
}
優點:打破線性讀取模式,殘餘週期極長。缺點:需浮點轉整數,微幅效能損耗。
| 適用 | 不適用 |
|---|---|
| 蒙地卡羅模擬、測試資料生成 | 密碼學級亂數 (需 CSPRNG) |
| 遊戲掉寶/程序生成 | 高安全性金鑰生成 |
| 嵌入式系統無硬體 RNG | 需嚴格可重現性的科學計算 |
完整 MFC 類別實作 (`CRandomArrayFromTxt`)、Matlab 生成腳本、測試專案已附於配套資源。