Метод Монте-Карло

http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9C%D0%BE%D0%BD%D1%82%D0%B5-%D0%9A%D0%B0%D1%80%D0%BB%D0%BE

        static void Main(string[] args)

        {

            int radius = 9000;

            Trace.WriteLine(CircleAreaByMonteCarlo(radius, 10000));

            Trace.WriteLine(Math.PI * radius * radius);

 

 

            Func<double, double, double, bool> limFunc = (x, y, max) => (x * x + y * y) < max;

 

            Trace.WriteLine(MonteCarlo(radius, radius, limFunc, 10000));

 

 

            Console.ReadKey();

        }

 

        /// <summary>

        /// S = Ssq * K / N

        /// </summary>

        /// <param name="r">radius</param>

        /// <returns>Area of circle calculated by the Monte-Carlo method</returns>

        static double CircleAreaByMonteCarlo(double radius, int number)

        {

            double max = radius * radius;

            Random rnd = new Random((int)DateTime.Now.Ticks >> 32);

 

            var k = (double)Enumerable.Repeat(0, number).

                                    Select(x => new { x = rnd.Next(0, (int)radius), y = rnd.Next((int)radius) }).

                                    Count(coord => (coord.x * coord.x + coord.y * coord.y) < max);

           

            return  4 * max  * k / number;

        }

 

        /// <summary>

        /// Calculates the area of a shape by Monte-Carlo method (S = Ssq * K / N)

        /// </summary>

        /// <param name="maxX">maximum of X</param>

        /// <param name="maxY">maximum of Y</param>

        /// <param name="limFunc">the function which describes a shape</param>

        /// <param name="number">number of iterations</param>

        /// <returns>Calculated area</returns>

        static double MonteCarlo(double maxX, double maxY, Func<double, double, double, bool> limFunc, int number)

        {           

            Random rnd = new Random((int)DateTime.Now.Ticks >> 32);

 

            var k = Enumerable.Repeat(0, number).

                                    Select(x => new { x = rnd.Next(0, (int)maxX), y = rnd.Next((int)maxY) }).

                                    Count(coord => limFunc(coord.x, coord.y, maxX * maxY));

 

            return 4 * maxX * maxY * k / number;

        }

 

254761200

254469004,940773

253368000

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s