在所有蒙特卡罗示例代码中,我发现了哪个计算pi,x和y都是在0和1之间随机生成的。例如,示例代码看起来像
Ran rdm(time(NULL));
double x, y;
int sum=0;
for(int i=0;i<N;i++)
{
x=rdm.doub(); // Both x and y are generated randomly
y=rdm.doub();
if(x*x+y*y<1)
sum++;
}
return 4.*sum/N;
我不明白随机生成两个轴的重点是什么,而不是选择一个固定且统一的x列表,然后只生成y随机,就像下面的示例代码一样。
Ran rdm(time(NULL));
double x=0.5/N, dx=1./N, y; //x is a fixed sequential list
int sum=0;
for(int i=0;i<N;i++)
{
y=rdm.doub(); // only y is generated randomly
if(x*x+y*y<1)
sum++;
x+=dx;
}
return 4.*sum/N;
我尝试了两个例子。两种方法都以速度~1 / sqrt(N)收敛。第二种方法的错误略小,第二种方法的运行速度稍快。所以在我看来第二种方法更好。对于更高维空间的采样,我认为总是可以在一个维度中选择固定列表并在其他维度中随机采样。这是真的吗?
是否有任何参考可以证明固定的x方法也是正确的?
如果固定的x方法更好,为什么我从未见过以这种方式编写的任何示例代码?它与自适应重要性抽样有关吗?
答案 0 :(得分:0)
您计算π的方法确实有效。我确信math.SE会给你一个清晰的证明,但它基本上是(1)单位盘是Riemann可积(2)每个切片的指标变量有正确的期望(3)Hoeffding的不等(例如)到显示总和的概率收敛。
事实是,这种方法不适用于非Riemann可积的集合。例如,考虑一下集合([0,1] - Q )×([0,1] - Q ),它的度量为1但是你的方法就是将始终采样不在集合中的有理x列。
另请参阅low-discrepancy sequences,您的想法更进了一步。
答案 1 :(得分:0)
我相信即使x和y均匀生成也会有效。在这种情况下,你将布置一个统一的点网格,看看哪些点落在圆圈内。
我认为你是对的,对于给定数量的点,均匀采样将与随机采样一样准确,但速度要快得多。
但是如果你不知道应该使用的分数呢?在这种情况下,我认为随机抽样更好,因为你可以继续添加点,直到整体价值变化很小。如果使用统一分布,则不能简单地增加点数。每次增加点数时,都必须创建一个完整的网格。