首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

任意分布隨機數生成方法:幾何面積拒絕採樣法與正態分布實作

     編輯:關於VC++

均勻分布隨機數基礎

VC rand() 產生 0~RAND_MAX (32767) 整數。轉換為任意區間 [min, max] 的浮點數 (4 位小數精度):

double AverageRandom(double min, double max) {
    int minInt = (int)(min * 10000);
    int maxInt = (int)(max * 10000);
    int randInt = rand() * rand();              // 擴大範圍至 ~10億
    int diff = maxInt - minInt;
    int result = randInt % diff + minInt;
    return result / 10000.0;
}

種子初始化:srand(GetTickCount()) 僅在批次生成前呼叫一次,避免同一毫秒內重複序列。

400個 -1~1 均勻分布

拒絕採樣法核心原理

已知機率密度函數 f(x),在包絡矩形區域均勻隨機取點 (x, y):

  • x ~ Uniform(min, max)
  • y ~ Uniform(0, f_max),其中 f_max = f(μ) (正態分布峰值)
  • 若 y ≤ f(x) 接受 x,否則拒絕重試

幾何直覺:曲線下方面積佔比即機率,接受點的 x 座標分布即為目標分布。

正態分布 PDF 公式 正態分布曲線 μ=0 σ=0.2

正態分布實作代碼

double Normal(double x, double miu, double sigma) {
    return 1.0 / sqrt(2 * PI * sigma) * exp(-(x - miu)*(x - miu) / (2 * sigma * sigma));
}

double NormalRandom(double miu, double sigma, double min, double max) {
    double x, y, dScope;
    do {
        x = AverageRandom(min, max);
        y = Normal(x, miu, sigma);
        dScope = AverageRandom(0, Normal(miu, miu, sigma)); // f_max
    } while (dScope > y); // 拒絕採樣
    return x;
}

驗證結果與分析

參數 μ=0, σ=0.2, 範圍 [-1,1],400 樣本:明顯集中於 0 附近

σ=0.2 分布圖

參數 μ=0, σ=0.05, 範圍 [-1,1],400 樣本:分布更尖峰,σ 越小越集中

σ=0.05 分布圖

4000 樣本統計直方圖 (μ=0, σ=0.2, 範圍 [0,4]):輪廓與理論 PDF 吻合

4000樣本統計

通用性與擴充

此方法僅需提供目標分布的 PDF f(x) 及其最大值 f_max,即可生成任意分布隨機數。適用於:

  • 指數分布、伽瑪分布、貝他分布等統計模擬
  • 訊號處理中的非高斯雜訊生成
  • 遊戲 AI 機率行為、粒子系統發射分布

效能提示:拒絕率 = 1 - (曲線下面積/矩形面積)。尖峰分布 (σ 小) 拒絕率高,可改用 Box-Muller 變換、Ziggurat 演算法或 Marsaglia 極座標法提升效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved