Форум программистов, компьютерный форум CyberForum.ru

Вычисление числа Пи методом Монте-Карло - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 61, средняя оценка - 4.89
isaak
101 / 38 / 9
Регистрация: 17.10.2010
Сообщений: 634
05.11.2012, 13:09     Вычисление числа Пи методом Монте-Карло #1
Всем доброго время суток. Написать программу для вычисления значения http://www.cyberforum.ru/cgi-bin/latex.cgi?\pi с помощью метода Монте-Карло. Для этого рассмотреть квадрат с центром в начале координат и длиной ребра 2, в которой вписана окружность радиуса 1 с центром в начале координат. Вероятность того, что выбранная наугад точка внутри квадрата попадет внутрь окружности равна отношению площадей окружности и квадрата, то есть http://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{\pi }{4}. Площадь квадрата накрывается сеткой из равноотстоящих точек (чем выше плотность точек, тем выше точность вычисления http://www.cyberforum.ru/cgi-bin/latex.cgi?\pi). Отношение точек, попавших внутрь окружности, к общему числу точек стремится (при увеличении общего количества точек к бесконечности) к вероятности попадания случайной точки внутри окружности, то есть http://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{\pi }{4}. Если координаты точки x и y
( -1 < x < 1 и -1 < y < 1), то условие попадания точки внутрь окружности имеет вид
http://www.cyberforum.ru/cgi-bin/latex.cgi?{x}^{2} + {y}^{2} < 1.

Суть расчета заключается в том, что мы берем квадрат со стороной a = 2 R, вписываем в него круг радиусом R. И начинаем наугад ставить точки внутри квадрата. Геометрически, вероятность P1 того, что точка попадет в круг, равна отношению площадей круга и квадрата:
P1=Sкруг / Sквадрата = Pi*R2 / a 2 = Pi*R2 / (2 R ) 2= Pi*R2 / (2 R) 2 = Pi / 4 (1)
Вероятность попадания точки в круг можно также посчитать после численного эксперимента: посчитать количество точек, попавших в круг, и поделить их на общее количество поставленных точек:
P2=Nпопавших в круг / Nточек; (2)
Так, при большом количестве точек в численном эксперименте вероятности должны вести себя cледующим образом:
lim(Nточек→∞)/(P2-P1)=0; (3)
Следовательно:
Pi/ 4 = Nпопавших в круг / Nточек; (4)
Pi=4 * Nпопавших в круг / Nточек; (5)
При моделировании мы применяем псевдослучайные числа, которые не являются случайным процессом.
Вот сам код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<cstdio> 
#include<cmath>
#include <ctime>
#include<cstdlib> 
#include <cstdio>
#define limit_Nmax 1e7 //Максимальное количество точек
#define limit_a 1e6 //Максмиальный радиус круга
#define min_a 100 //Начальный радиус
 
double circle(double, double); //Выдает квадрат Y в зависимости от координаты Х и радиуса круга.
 
int main() 
{ 
 
double x,y,Pi; 
long long int a=min_a;//сторона квадрата
int i=0;//Счетчик 
double Ncirc=0;//Количество точек, попавших в круг 
double Nmax=a; //Общее количество точек
while (a<limit_a)  //Перебор  значений радиуса
{ 
Nmax=a; 
 while (Nmax<=limit_Nmax) // Перебор значения количества точек
 { 
 Ncirc=0; i=0; //обнуляторы
    while (i<Nmax) 
    { 
    x = (rand() % (a * 1000))/1000;  //Рандомный Х с 3 знаками после запятой
    y = (rand() % (a * 1000))/1000;  //Рандомный Y с 3 знаками после запятой
        if (y*y<=circle(x,(a/2)))  //Условие принадлежности точки к кругу
        { 
        Ncirc++; 
        } 
    i++; 
    } 
 
 Pi=(Ncirc/Nmax)*4; 
 Nmax *= 2; 
 printf("\n%lld, %.0f, %f",a,Nmax,Pi); 
 } 
a*=2; 
} 
 
} 
 
double circle(double x, double radius) 
{ 
double y=radius*radius-x*x; 
return y; 
}
Но она не правильно считает число Pi. Подскажите пожалуйста в чем ошибка???? Заранее огромное спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
06.11.2012, 01:24     Вычисление числа Пи методом Монте-Карло #2
isaak, алгоритм досконально не смотрел, но в глаза бросается тот факт что ты используешь rand предварительно не установив начальное значение генератора случайных чисел посредством srand, в результате твои rand-ы возвращают одни и тже последовательности. Поэтому, для генерации стохастических последовательностей, введи в свой код строку помеченную красным
Цитата Сообщение от isaak Посмотреть сообщение
double circle(double, double); //Выдает квадрат Y в зависимости от координаты Х и радиуса круга.
int main()
{
srand(time(0));
double x,y,Pi;
isaak
101 / 38 / 9
Регистрация: 17.10.2010
Сообщений: 634
06.11.2012, 13:28  [ТС]     Вычисление числа Пи методом Монте-Карло #3
-=ЮрА=- спасибо огромное за ответ, сделал как ты советуешь:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<cstdio> 
#include<cmath>
#include <ctime>
#include<cstdlib> 
#include <cstdio>
#define limit_Nmax 1e7 //Максимальное количество точек
#define limit_a 1e6 //Максиальный радиус круга
#define min_a 100 //Начальный радиус
 
double circle(double, double); //Выдает квадрат Y в зависимости от координаты Х и радиуса круга.
 
int main() 
{ 
srand(time(0));
double x,y,Pi; 
long long int a=min_a;//сторона квадарата
int i=0;//Счетчик 
double Ncirc=0;//Количество точек, попавших в круг 
double Nmax=a; //Общее количество точек
while (a<limit_a)  //Перебор  значений радиуса
{ 
Nmax=a; 
 while (Nmax<=limit_Nmax) // Перебор значения количества точек
 { 
 Ncirc=0; i=0; //обнуляторы
    while (i<Nmax) 
    { 
    x = (rand() % (a * 1000))/1000;  //Рандомный Х с 3 знаками после запятой
    y = (rand() % (a * 1000))/1000;  //Рандомный Y с 3 знаками после запятой
        if (y*y<=circle(x,(a/2)))  //Условие принадлежности точки к кругу
        { 
        Ncirc++; 
        } 
    i++; 
    } 
 
 Pi=(Ncirc/Nmax)*4; 
 Nmax *= 2; 
 printf("\n%lld, %.0f, %f",a,Nmax,Pi); 
 } 
a*=2; 
} 
 
} 
 
double circle(double x, double radius) 
{ 
double y=radius*radius-x*x; 
return y; 
}
Но программа все равно не правильно работает???? Она должна выводить число Pi с пятью знаками после запятой, а она выводит левое число совсем не похожее на Pi ????? В чем ошибка?????? Заранее огромное спасибо.
-=ЮрА=-
07.11.2012, 21:58
  #4

Не по теме:

isaak, я помню твоём задании, через пару дней освобождаюсь и напишу код, либо поравлю твой, пока банально нет времени (без обид)

isaak
101 / 38 / 9
Регистрация: 17.10.2010
Сообщений: 634
07.11.2012, 22:25  [ТС]     Вычисление числа Пи методом Монте-Карло #5
Хорошо буду ждать.
-=ЮрА=-
Заблокирован
Автор FAQ
10.11.2012, 23:41     Вычисление числа Пи методом Монте-Карло #6
Цитата Сообщение от isaak Посмотреть сообщение
Хорошо буду ждать.
Лови
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
using namespace std;
 
bool IsPointInCircle(double R, double x, double y);
 
int main()
{
    int Npoints = (int)1E3;
    int Nincircle = 0;
    srand(time(0));
    for(int i = 0; i < Npoints; i++)
    {
        if
        (
            IsPointInCircle
            (
                1.0, 
                (rand()%(4*Npoints) - 2*Npoints)/(2.0*Npoints), 
                (rand()%(4*Npoints) - 2*Npoints)/(2.0*Npoints)
            )
        )
            Nincircle++;
    }
    cout<<"Calc  Value of PI : "<<setprecision(5)<<Nincircle*4.0/Npoints<<endl;
    cout<<"Check Value of PI : "<<setprecision(5)<<asin(1.0)*2.0<<endl;
    cin.get();
    return 0;
}
 
bool IsPointInCircle(double R, double x, double y)
{
    return ((x*x + y*y) < R*R);
}
Проверка здесь http://codepad.org/RStNqGJv
Calc Value of PI : 3.184
Check Value of PI : 3.1416
Миниатюры
Вычисление числа Пи методом Монте-Карло  
isaak
101 / 38 / 9
Регистрация: 17.10.2010
Сообщений: 634
10.11.2012, 23:50  [ТС]     Вычисление числа Пи методом Монте-Карло #7
-=ЮрА=- спасбо огромное как здоровье? Поправляйся.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2012, 00:19     Вычисление числа Пи методом Монте-Карло
Еще ссылки по теме:

Таблица умножения методом Монте-Карло C++
C++ Вычисление интеграла методом Монте-Карло
Определить площадь фигуры (методом Монте-Карло) C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
-=ЮрА=-
11.11.2012, 00:19     Вычисление числа Пи методом Монте-Карло
  #8

Не по теме:

Цитата Сообщение от isaak Посмотреть сообщение
-=ЮрА=- спасбо огромное как здоровье? Поправляйся.
isaak, со мной всё ок

Yandex
Объявления
11.11.2012, 00:19     Вычисление числа Пи методом Монте-Карло
Ответ Создать тему
Опции темы

Текущее время: 22:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru