Monte Carlo İntegrali Alan Hesabı
Bir eğrinin altında yer alan alanı istatiksel bir yöntemle hesaplamak için Monte Carlo integral algoritması kullanılabilir. Bu algoritma ile, rasgele üretilen N adet noktanın kaç tanesinin fonksiyon eğrisinin altında yer aldığına bakılır. Rasgele seçilen noktaların yüzde kaçının eğri altında yer aldığına bakılarak, yaklaşık olarak alan hesabı yapılabilir.
Algoritma adımları aşağıdaki şekilde sıralanabilir:
- Fonksiyonun verilen aralıktaki tüm değerlerini içine alacak şekilde bir dikdörtgen belirlenir.
- Bu dörtgen içerisinde, N adet nokta rastgele olarak oluşturulur.
- Bu noktaların ne kadarının, fonksiyonun belirlediği alanın altında olduğuna bakılır.
- N değerinin, eğri altında olan nokta sayısına oranı, bize yaklaşık olarak, dikdörtgenin alanın fonksiyon eğrisi alanına oranını verecektir.
Aşağıda, Monte Carlo algoritmasının C# dilinde yazılmış kaynak kodu yer almaktadır.
using System; namespace SG.Algoritma { partial class MonteCarlo { // Deneme adet public uint N { get; set; } public MonteCarlo(uint n) { if (n == 0) { throw new ArgumentException(nameof(N)); } this.N = n; } /// <summary> /// Verilen fonksiyon eğrisinin altında bulunan alan hesaplanıyor. /// </summary> /// <param name="func">Fonksiyon</param> /// <param name="x1">X ekseni üzerinde, aralık başlangıcı</param> /// <param name="x2">Aralık bitiş</param> public double CalculateArea(Func<double, double> func, double x1, double x2) { // Verilen aralıkta, fonksiyonun aldığı minimum ve maksimum değerler double min; double max; // Fonksiyonun minimum ve maksimum değeri hesaplanıyor this.CalculateMinMaxValue(func, x1, x2, out min, out max); // Denemelerden kaç tanesi, fonksiyon eğrisinin altında var hit = 0; // Rasgele sayı üretici var rand = new Random(); // N adet dememe yap for (int i = 0; i < this.N; i++) { // Dikdörtgen içerisinde rasgele bir nokta üret var x = x1 + (x2 - x1) * rand.NextDouble(); var y = min + (max - min) * rand.NextDouble(); // Rasgele seçilen nokta ve fonksiyonun değeri, eğrinin aynı tarafındaysa. (İki negatif sayının çarpımı pozitiftir) if (func(x) * y > 0) { // Fonksiyon değeri pozitifse if (func(x) > 0) { // Rasgele üretilen y değeri fonsiyon eğrisinin altındaysa if (func(x) > y) hit++; } else { // Rasgele üretilen y değeri fonsiyon eğrisinin üstündeyse if (y < 0 && func(x) < y) hit++; } } } var areaRectangle = Math.Abs(x2 - x1) * (max - min); // Seçilen rasgelen noktaların yüzde hit / N kadarı dikdörtgenin içerisinde. // Noktaların yüzde kaçının dikdörtgen içerisinde olduğuna bakılarak alan hesabı yapılıyor. return areaRectangle * (double)hit / this.N; } /// <summary> /// Verilen aralıkta, fornksiyonun minimum ve maksimum değerleri hesaplanıyor. /// </summary> /// <param name="func">Fonksiyon</param> /// <param name="x1">Aralık başlangıç</param> /// <param name="x2">Aralık bitiş</param> /// <param name="min">Hesaplanan minimum değer</param> /// <param name="max">Hesaplanan maksimum değer</param> private void CalculateMinMaxValue(Func<double, double> func, double x1, double x2, out double min, out double max) { min = double.MaxValue; max = double.MinValue; // Aralık N parçaya bölünüyor. var h = (x2 - x1) / this.N; // Verilen aralıkta, N adet nokta için, her bir noktanın fonksiyon değeri hesaplanıyor. for (int i = 0; i <= this.N; i++) { var x = x1 + i * h; var y = func(x); if (y < min) min = y; if (y > max) max = y; } } } }
Monte Carlo alan hesabı algoritması ile, istediğiniz fonksiyon grafiği altında yer alan bölgenin alanını çok rahat bir şekilde hesaplayabiliriz. Fonksiyonun ne kadar karmaşık olduğunu bir önemi yok. Örneğin f(x) = x - sin(x) - 1
fonksiyon eğrisinin x ekseni {0,3} aralığındaki alanı hesaplamak için, alan hesaplama metodunu aşağıdaki gibi çalıştırabiliriz.
var mc = new MonteCarlo(1000); var area = mc.CalculateArea(x => x - Math.Sin(x) - 1, 0, 3);
Bu durumda aşağıdaki eğri altında yer alan alan yaklaşık olarak hesaplanacaktır. Daha hassas bir hesaplamak için N değerinin artırılması gerekmektedir.
Aynı algoritmada yapılacak küçük bir değişiklikle, fonksiyonun integral değeri de rahatlıkla hesaplanabilir. İntegral hesabında, pozitif alanlardan negatif alanlar çıkarılacağı için, bu alanlara düşen noktalar ayrı ayrı sayılır.