使用 Monte Carlo 方法逼近 Pi 的不精确性
Imprecision in Approximating Pi using Monte Carlo Method
圆的面积 = Pi * R^2 和正方形的面积 = 4 * R^2。
如果我们用圆的面积除以正方形的面积,我们得到 Pi / 4。
让我们在里面有一个正方形和一个内切圆。我们生成具有随机坐标的点,然后计算它们在每个区域中的数量。
然后 Pi = 4 *(# 圆圈中的点)/(# 正方形中的点)。
这里尝试用上述方法逼近 Pi:
#include <iostream> /* std::cout */
#include <iomanip> /* std::setprecision */
#include <random> /* std::uniform_int_distribution; std::mt19937 */
/* Check if point (x,y) is inside a circle with radius: r, at O(0,0). */
bool isInside (double x, double y, double r) { return (x*x + y*y) <= r*r; }
double approximatePi (double s, int sample_size)
{
std::mt19937 gen; /* Generate random number in [-s/2 : s/2]. */
std::uniform_int_distribution<double> dis(-s/2, s/2);
int count = 0; /* Number of points in the circle. */
for (int i = 0; i < sample_size; ++i)
{
double x = dis(gen);
double y = dis(gen);
if (isInside(x, y, s/2)) /* Radius of inscribed circle = side / 2. */
{
++count;
}
}
/* Pi = 4 * (# points in Circle) / (# points in Square). */
return (double) 4 * count / sample_size;
}
int main()
{
double side = 10.0; /* Square side. */
int sample_size = 10000; /* Number of tries. */
std::cout <<"Pi ~ "<< std::fixed << std::setprecision(6) << approximatePi(side, sample_size) << '\n';
}
预期结果:Pi ~ 3.141592
实际结果:Pi ~ 2.611200
为什么我没有得到预期的结果?我究竟做错了什么?
std::uniform_int_distribution<double>
的效果是未定义的行为,因为double
不是整数类型。
圆的面积 = Pi * R^2 和正方形的面积 = 4 * R^2。 如果我们用圆的面积除以正方形的面积,我们得到 Pi / 4。
让我们在里面有一个正方形和一个内切圆。我们生成具有随机坐标的点,然后计算它们在每个区域中的数量。
然后 Pi = 4 *(# 圆圈中的点)/(# 正方形中的点)。
这里尝试用上述方法逼近 Pi:
#include <iostream> /* std::cout */
#include <iomanip> /* std::setprecision */
#include <random> /* std::uniform_int_distribution; std::mt19937 */
/* Check if point (x,y) is inside a circle with radius: r, at O(0,0). */
bool isInside (double x, double y, double r) { return (x*x + y*y) <= r*r; }
double approximatePi (double s, int sample_size)
{
std::mt19937 gen; /* Generate random number in [-s/2 : s/2]. */
std::uniform_int_distribution<double> dis(-s/2, s/2);
int count = 0; /* Number of points in the circle. */
for (int i = 0; i < sample_size; ++i)
{
double x = dis(gen);
double y = dis(gen);
if (isInside(x, y, s/2)) /* Radius of inscribed circle = side / 2. */
{
++count;
}
}
/* Pi = 4 * (# points in Circle) / (# points in Square). */
return (double) 4 * count / sample_size;
}
int main()
{
double side = 10.0; /* Square side. */
int sample_size = 10000; /* Number of tries. */
std::cout <<"Pi ~ "<< std::fixed << std::setprecision(6) << approximatePi(side, sample_size) << '\n';
}
预期结果:Pi ~ 3.141592
实际结果:Pi ~ 2.611200
为什么我没有得到预期的结果?我究竟做错了什么?
std::uniform_int_distribution<double>
的效果是未定义的行为,因为double
不是整数类型。