我在编码相当缺乏经验,但我已成功地写:我怎么能优化这个算法近似pi?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PiApprox
{
public class PiApprox
{
//side of the rectangle
public static int s;
//radius of the circle
public static int r;
//indexers of the coordinates, points
public static int ix;
public static int iy;
//current y
public static decimal cury;
//without rounding
public static decimal wcury;
//amounts of points relative to the circle
public static decimal inAmount;
public static decimal onAmount;
public static decimal outAmount;
//amount of all points
public static decimal allAmount;
//short for inAmount and on onAmount,
//used to make the calculations clearer in the final part
public static decimal inanon;
//final result, crude approximation of pi
public static decimal piApprox;
public static void Main()
{
while (true)
{
Calculate();
}
}
public static void Calculate()
{
s = Convert.ToInt32(Console.ReadLine());
//calculate the radius of the circle
r = s/2;
//calculate the total amount of points in the grid
//rectangle area
allAmount = (decimal) Math.Pow(s, 2);
//reset values
inAmount = 0;
onAmount = 0;
outAmount = 0;
//main loop
//iterate for y, from up to down
for (ix = -r; ix <= 0; ix++)
{
wcury = (decimal) Math.Sqrt(Math.Pow(r, 2) - Math.Pow(ix, 2));
cury = Math.Floor(wcury);
outAmount += r - (int)cury;
if (wcury == cury)
{
onAmount++;
}
if (wcury == cury)
{
inAmount += (int)cury;
}
else
{
inAmount += (int)cury + 1;
}
Result();
}
Result();
}
public static void Result()
{
//total amount of points
inanon = 4 * (onAmount + inAmount - (r + 1)) + 1;
//proportion
piApprox = 4 * (inanon/allAmount);
Console.SetCursorPosition(1, 0);
Console.WriteLine(piApprox);
}
}
}
蒙特卡罗原理很简单;我计算了y值 的绘图f(x)= sqrt(r^2 - ix^2),它们代表了圆的第一个四分之一。然后我计算圆内的点并在最后输出。线上的乘法piApprox = 4 *(inanon/allAmount); (pi * r^2)/((2r)^ 2) - > (pi * r^2)/(4 * r^2) - > pi/4
有什么我可以做的,以加快计算?
如果您有很多事情可以加快代码的执行速度,尤其是如果您对编程不熟悉并且没有努力加速代码的话,我不会感到惊讶。缺乏具体的问题陈述,这个问题对于Stack Overflow来说太广泛了。它可能适用于codereview.stackexchange.com;你可以尝试在那里发布。如果你想在这里得到答案,你需要解释你试图加快代码的速度,你如何衡量性能,你试图满足什么特定的,可衡量的性能目标,以及为什么你认为它可以被满足。 –
为什么在循环中调用Result()'_every time_? 'WriteLine''每次都需要花费大量的时间,所以随着点数的增加而减少输出的速率 – 2015-11-07 01:12:08
这不是Monte-Carlo,这个算法没有任何随机性。这只是使用最基本的积分方法在区间'[0,r]'上积分曲线'sqrt(r * r-x * x)'。探索Simpson方法或Romberg方法以获得更好的集成精度。 – LutzL