Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.01.2009, 02:15   #1
ChertYaGa
 
Регистрация: 13.01.2009
Сообщений: 3
Восклицание Поиск площади фигуры методом Монте - Карло

Помогите пожалуйста!!! очень срочно нужно!!!

Заданы две прямые вида y=± d/2 и окружность радиусом R>d и с центром в точке с началом координат.
Найти площадь фигуры, ограниченной этими прямыми и окружностью.
Сделать методом Монте – Карло

Всех заранее благодарю!!!!
ChertYaGa вне форума Ответить с цитированием
Старый 13.01.2009, 15:33   #2
_Dmitry
Участник клуба
 
Аватар для _Dmitry
 
Регистрация: 02.09.2007
Сообщений: 1,193
По умолчанию

Представь, что круг - это мишень. Берёшь пулемёт (генератор случайных чисел) и стреляешь по этой мишени. Далее считаешь попадания: пусть n - общее количество попаданий в круг (в мишень), из них m - количество попаданий в твою фигуру ограниченную линиями и окружностью. Тогда полщадь этой фигуры = (площадь круга)*m/n. Естественно, чем больше выстрелов, тем точнее результат. В силу симметрии, можно стрелять по четверти мишени.
_Dmitry вне форума Ответить с цитированием
Старый 13.01.2009, 17:12   #3
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Привожу два листинга. Первый - для окружности и двух прямых (ваш случай). Но он не до конца рабочий. А именно, он всегда выдает площадь прямоугольника, которым мы ограничиваем функцию (надеюсь, вы уже ознакомились с самим методом Монте-Карло). Это происходит, видимо, из-за кривой функции для геренации координат точки (x := x*2*R-R). Все точки попадают внутрь фигуры. Просто в данной задаче остается довольно небольшая площадь вне фигуры.
В общем, нужно подкорректировать формулы генерации координат, чтобы была большая вероятность попадания во внешнюю область.

Второй листинг - для окружности БЕЗ прямых. Сделал специально для того, чтобы показать, что код рабочий. Например, для R=5 площадь ограничивающего прямоугольника ~78.5398, а площадь круга =78.4672 (результат работы программы)

Листинг 1:
Код:
uses crt;

const MAXI=1000000;
var
d,R : double;
XLEFT,XRIGHT : extended;  { координаты x пересечения окружности с прямыми }
i,K : longint;  { счетчики: K - кол-во точек внутри графика }
x,y : extended;
S : extended;

begin
clrscr;
write('Enter d: ');
readln(d);
write('Enter R: ');
readln(R);
if R<=d then begin
             writeln('R must be >d!');
             readkey;
             exit;
             end;
{--- }
{-- Ищем точки пересечения окружности и прямых --}
XRIGHT := sqrt(sqr(R)-sqr(d));
XLEFT := -XRIGHT;
randomize;
K := 0;
d := d/2;
for i:=1 to MAXI do
  begin
  {x := random()*2*R-R;
  y := random()*2*d-d; }
   x := random();
   y := random();
 {  writeln('  ',x:10:7,'    ',y:10:7);      }
   x := x*2*R-R;
   y := y*2*d-d;

 { writeln('x=',x:10:7,'  y=',y:10:7);   }
  if keypressed then
    if readkey = #27 then
      begin
      writeln('i= ',i);
       writeln('x=',x:10:7,'  y=',y:10:7);
      if readkey = #27 then break;
      end;

  if (x>=XLEFT) or (x<=XRIGHT) then
     begin
     if (y<=d) or (y>=-d) then inc(K);
     end
  else begin
       if sqr(x)+sqr(y)<sqr(R) then inc(K);
       end;


  end;  { конец цикла }

S := 4*d*R*K/MAXI;

{-------------}
writeln('d= ',d:20:17);
writeln('R= ',R:20:17);
writeln('K= ',K);
writeln('S= ',S:20:17);

readln;
end.
Листинг 2:
Код:
uses crt;

const MAXI=1000000;
var
R : double;
{XLEFT,XRIGHT : extended;  координаты x пересечения окружности с прямыми }
i,K : longint;  { счетчики: K - кол-во точек внутри графика }
x,y : extended;
S : extended;

begin
clrscr;
write('Enter R: ');
readln(R);
randomize;
K := 0;
for i:=1 to MAXI do
  begin
  x := random();
  y := random();
  x := x*2*R-R;
  y := y*2*R-R;
  if keypressed then
    if readkey = #27 then
      begin
      writeln('i= ',i);
       writeln('x=',x:10:7,'  y=',y:10:7);
      if readkey = #27 then break;
      end;
    if sqr(x)+sqr(y)<sqr(R) then inc(K);
  end;  { конец цикла }

 s := 4*R*R*K/MAXI;
{-------------}
writeln('R= ',R:20:17);
writeln('K= ',K);
writeln('S= ',S:20:17);

readln;
end.
Вообще, имхо тема довольно интересная. Советовал бы вам разобраться.
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 13.01.2009, 18:16   #4
_Dmitry
Участник клуба
 
Аватар для _Dmitry
 
Регистрация: 02.09.2007
Сообщений: 1,193
По умолчанию

Рабочий код
Код:
var
  R,d,a,x,y,S,S0: real;
  n,m,i,nMax: integer;
begin
  write('R = '); readln(R);
  write('d = '); readln(d);
  write('nMax = '); readln(nMax); {количество выстрелов}
  randomize;
  n:=0; m:=0;
  for i:=1 to nMax do
    begin
      x:=random*R; y:=random*R;
      if (x*x+y*y) <= (R*R) then
        begin
          n:=n+1;
          if y <= d then m:=m+1;
        end;
    end;
  {площадь по методу Монте-Карло}
  S:=pi*R*R*m/n;
  {точная площадь}
  a:=sqrt(R*R-d*d);
  S0:=4*(a*d+pi*R*R/4-a/2*sqrt(R*R-a*a)-R*R/2*arctan(a/R/sqrt(1-a*a/R/R)));
  writeln('S = ',S:1:6);
  writeln('S0 = ',S0:1:6);
  writeln('delta = ',abs(S0-S)/S0*100:1:6,' %'); {погрешность расчёта}
  readln;
end.
--------------
p.s. Ошибочка. По условию задачи уравнение прямой y=± d/2, в данном алгоритме y=± d, что, вообще говоря, не принципиально. Исправьте сами...

Последний раз редактировалось _Dmitry; 13.01.2009 в 18:28.
_Dmitry вне форума Ответить с цитированием
Старый 13.01.2009, 21:17   #5
MIKI
Пользователь
 
Регистрация: 31.03.2008
Сообщений: 14
По умолчанию

а то самое только в С++!!!
пожалуйста!!!
MIKI вне форума Ответить с цитированием
Старый 13.01.2009, 21:56   #6
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

На C++. Переведенный вариант _Dmitry. Вроде, ничего не забыл.
Код:
#include <iostream>
#include <conio.h>
#include <time.h>
#include <math.h>
using namespace std;

int main(){
double PI=asin(1)*2;
double R,d,a,x,y,S,S0;
int n,m,i,nMax;
cout<<"R = "; cin>>R;
cout<<"d = "; cin>>d;
cout<<"nMax = "; cin>>nMax; //количество выстрелов
srand(time(NULL));
n=0; m=0;
d/=2;
for(i=1;i<=nMax;i++)
  {
      x=(double)rand()*R/RAND_MAX; y=(double)rand()*R/RAND_MAX;
      if(x*x+y*y <= R*R)
        {
          n++;
          if(y <= d) m++;
        }
   }
//площадь по методу Монте-Карло
  S = PI*R*R*m/n;
//точная площадь
cout.setf(ios::fixed,ios::floatfield);
a=sqrt(R*R-d*d);
S0=4*(a*d+PI*R*R/4-a/2*sqrt(R*R-a*a)-R*R/2*atan(a/R/sqrt(1-a*a/R/R)));
cout<<"S = "<<S<<endl;
cout<<"S0 = "<<S0<<endl;
cout<<"delta = "<<fabs(S0-S)/S0*100<<" %"<<endl; //погрешность расчёта

getch();
return 0;
}
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 14.01.2009, 19:49   #7
MIKI
Пользователь
 
Регистрация: 31.03.2008
Сообщений: 14
По умолчанию

благодарю!!!!
MIKI вне форума Ответить с цитированием
Старый 14.01.2009, 19:49   #8
_Dmitry
Участник клуба
 
Аватар для _Dmitry
 
Регистрация: 02.09.2007
Сообщений: 1,193
По умолчанию

Цитата:
double PI=asin(1)*2;
В модуле math.h есть константа PI, она называется M_PI.
Вот выдержка из модуля:
Код:
#define M_E         2.71828182845904523536
#define M_LOG2E     1.44269504088896340736
#define M_LOG10E    0.434294481903251827651
#define M_LN2       0.693147180559945309417
#define M_LN10      2.30258509299404568402
#define M_PI        3.14159265358979323846
#define M_PI_2      1.57079632679489661923
#define M_PI_4      0.785398163397448309616
#define M_1_PI      0.318309886183790671538
#define M_2_PI      0.636619772367581343076
#define M_1_SQRTPI  0.564189583547756286948
#define M_2_SQRTPI  1.12837916709551257390
#define M_SQRT2     1.41421356237309504880
#define M_SQRT_2    0.707106781186547524401
_Dmitry вне форума Ответить с цитированием
Старый 14.01.2009, 20:02   #9
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

_Dmitry
Цитата:
В модуле math.h есть константа PI, она называется M_PI.
Знаю, спасибо.. Просто у меня она почему-то не определялась.
Хотя проверил сейчас - работает.. Мистика ))
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 15.01.2009, 17:12   #10
ChertYaGa
 
Регистрация: 13.01.2009
Сообщений: 3
По умолчанию

Спасибо большое!
ChertYaGa вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Монте карло KJIOyH Помощь студентам 21 07.09.2010 13:20
поиск простых чисел методом решета.программа на С или С++ из_семи Помощь студентам 2 25.02.2009 20:56
Поиск обратной матрицы методом Гаусcа BOB.GLAMUR Общие вопросы Delphi 1 26.12.2008 11:30
Метод Монте-Карло литература или примеры программ на С++ или С MIKI Помощь студентам 2 09.12.2008 13:33
1) Поиск кратчайшего пути в графе методом полного перебора в ширину(очередь) Serega123 Помощь студентам 3 30.10.2008 22:26