1D 蒙特卡洛积分解释¶
来源: Monte Carlo Integration Explanation in 1D - The blog at the bottom of the sea
1. 引言¶
我们考虑一个简单的问题:想知道函数
\[
y = \sin^2(x)
\]
在区间 \(x \in [0,\pi]\) 下,曲线下面积是多少。
用传统的微积分可以精确解出为
\[
\int_0^{\pi} \sin^2(x)\,dx = \frac{\pi}{2}
\]
2. 示例问题¶
我们希望计算:
\[
I = \int_{0}^{\pi} \sin^2(x)\,dx
\]
解析答案为:
\[
I = \frac{\pi}{2} \approx 1.5708
\]
3. 基本蒙特 卡罗积分方法¶
方法思路如下:
- 在区间 [0, π] 内均匀随机抽取 \(x_i\)。
- 对每个样本计算 \(y_i = f(x_i) = \sin^2(x_i)\)。
- 计算平均值:
\[
\bar{y} = \frac{1}{N}\sum_{i=1}^{N} y_i
\]
- 将平均值乘以区间宽度得到积分估计:
\[
I \approx (b-a)\cdot\bar{y} = (\pi - 0)\cdot \bar{y}
\]
完整表达式为
\[
\int_{a}^{b} f(x)\,dx \approx (b-a)\cdot \frac{1}{N}\sum_{i=1}^{N} f(x_i)
\]
4. 示例代码(C++)¶
double SimpleMonteCarlo()
{
double rangeMin = 0;
double rangeMax = 3.14159265359; // π
size_t numSamples = 10000;
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<double> dist(rangeMin, rangeMax);
double ySum = 0.0;
for (size_t i = 0; i < numSamples; ++i)
{
double x = dist(mt);
double y = sin(x) * sin(x);
ySum += y;
}
double yAverage = ySum / double(numSamples);
double width = rangeMax - rangeMin;
return width * yAverage;
}
5. 样本数与误差关系¶
误差大约随下式衰减:
\[
\text{误差} \propto \frac{1}{\sqrt{N}}
\]
要让误差减半,需要 4 倍样本数。
虽然收敛慢,但它的优点是收敛速率与维度无关。
6. 抽样策略优化¶
为减少方差,可采用以下抽样优化方法:
- 蓝噪声 (Blue Noise):避免样本聚集。
- 低差异序列 (Low Discrepancy Sequences):如 Sobol、Halton 序列。
- 分层抽样 (Stratified Sampling):
\[
I \approx (b-a)\cdot\frac{1}{M}\sum_{k=1}^{M} f(x_k)
\]
保证每个子区间都有样本。
7. 任意分布抽样(PDF 抽样)¶
如果从任意分布 \(p(x)\) 抽样:
\[
\int_a^b f(x)\,dx = \int_a^b \frac{f(x)}{p(x)}\,p(x)\,dx
\approx \frac{1}{N}\sum_{i=1}^N \frac{f(x_i)}{p(x_i)}, \quad x_i \sim p(x)
\]
当 \(p(x)\) 与 \(f(x)\) 形状接近时,可显著降低方差。
这就是重要抽样 (Importance Sampling)。
8. 总结¶
核心思想:
\[
\int f(x)\,dx \approx \text{期望}[f(x)]
\]
| 优点 | 缺点 |
|---|---|
| 实现简单、通用、高维有效 | 收敛慢、噪声大 |