Описание файла fequa.H
В файле fequa.h хранятся функции для решения определенного уравнения, выбранного пользователем.
В ходе выполнения функции типа equation[1,2,3]() находятся минимальные максимальные значения по OX и OY, подсчитывается точное значение интеграла, строится график интеграла, разбрасываются точки с параллельным подсчетом попаданий (белые – попали под график, зеленые – не попали). Затем выводится в диалоговом окне приближенное значение интеграла методом Монте-Карло, точное значение интеграла, относительная и абсолютная погрешности вычислений.
Переменные в функциях типа equation[1,2,3]():
float randx, randy – произвольные координаты X и Y;
float K – счетчик попаданий под график;
float i – промежуточный счетчик;
float S – значение интеграла методом Монте-Крало;
float Sf – площадь параллелепипеда.
Описание файла mCmain.Cpp
В файле MCmain.cpp находится «сердце» программы, которая считывает данные и направляет на нужные функции.
Переменные в функциях main():
int ur – принимает номер уравнения и оператором switch переходит на определенную функцию.
Описание методики тестирования
Программа была протестирована на всех трех уравнениях с произвольными числами, введенными с клавиатуры.
Ниже приведены результаты работы программы:
Рисунок 3.1.А. – пример работы программы.
Рисунок 3.1.Б. – пример работы программы.
Рисунок 3.2.А. – пример работы программы.
Рисунок 3.2.Б. – пример работы программы.
Рисунок 3.3.А. – пример работы программы.
Рисунок 3.3.Б. – пример работы программы.
Руководство пользователя по работе с программой
Установка программы
Копировать папку проекта в любую директорию. Программа будет иметь полную работоспособность после перезаписи в другой каталог, т.к. не требует дополнительных файлов и работает непосредственно.
Запуск программы
Зпаустить исполняющий файл MC.exe
Ввод данных с клавиатуры
Следовать указаниям, появляющимся на экране.
Примечание
Программа тестировалась и корректно работает в ОС Windows 7.
Третья функция не интегрируема при b+x=0. Следовательно программа будет выдать только приблеженное значение интеграла.
Блок-схема программы
Заключение
Программа вычисления интеграла методом Монте-Карло может быть использована в учебном процессе для иллюстрации принципа вычисления интеграла или как основа для дальнейшей разработки, улучшения и дополнения программы для выполнения специфических задач.
Список использованных источников
Васильев А.Н., Самоучитель С++ с примерами и задачами. – СПб.: Наука и Техника, 2010. – 480 с.
Мудров А.Е., Численные методы для ПЭВМ на языках Бейсик, Фортран и Паскаль. – Томск: МП «РАСКО», 1991. – 172с.
Приложение А, файл const.h
float donkey1(); //функции для проверки ввода
float donkey2();
float donkey3();
int donkey4();
float equation1(); //решение уравнения
float equation2();
float equation3();
float donk, donk0; //глобальные перменные
float x0,x1,a,b,c,x,y;
int n;
float xmin,ymin,xmax,ymax,tchn,step;
char kf;
Приложение B, файл fdonk.h
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <math.h>
#include <cmath>
#include <locale.h>
using namespace std;
float donkey1() //проверка на корректность ввода номера уравнения
{
bool right=false;
while(!right)
{ cout<<"Уравнение номер: "; cin>>donk; if (cin.good() && (donk==1 || donk==2 || donk==3))
{ right=true; return donk; }
else
{ system("cls"); cout<<"Повторите ввод.. "<<endl; cin.clear(); _flushall(); } }
}
float donkey2() //проверка на корректность ввода пределов интегрирования
{ float donkx0, donkx1; bool right=false;
while(!right)
{ cout<<"От: "; cin>>donkx0;
if (cin.good() && (donkx0<=1000 && donkx0>=-1000))
{ right=true; }
else
{ system("cls"); cout<<"Повторите ввод.. "<<endl; cin.clear(); _flushall(); } }
right=false;
while(!right)
{ cout<<"До: "; cin>>donkx1;
if (cin.good() && (donkx1<=1000 && donkx1>=-1000))
{ right=true; }
else
{ system("cls"); cout<<"Повторите ввод.. "<<endl; cin.clear(); _flushall(); } }
right=false;
donk=donkx1;
donk0=donkx0;
if (donk0>=donk) { system("cls"); cout<<"(!) Значение 'До' должно быть больше значения 'От'\n"; donkey2(); }
}
float donkey3() //прверка на корректность ввода коэффицентов
{
bool right=false;
while(!right)
{ cout<<"Коэффициент '"<<kf<<"' = "; cin>>donk; if (cin.good()) { right=true; return donk; }
else { system("cls"); cout<<"Повторите ввод.. "<<endl; cin.clear(); _flushall(); } }
}
int donkey4()
{
bool right=false;
while(!right)
{ cout<<"Число точек 'n' = "; cin>>donk; if (cin.good() && donk>=1 && donk<=500) { right=true; }
else { system("cls"); cout<<"Повторите ввод.. "<<endl; cin.clear(); _flushall(); } }
}
int randomx(int xmin, int xmax)
{ return rand() % (xmax - xmin + 1) + xmin; }
double randomx(double xmin, double xmax)
{ return randomx(static_cast<int>(xmin * 100), static_cast<int>(xmax * 100)) / 100.0; }
int randomy(int ymin, int ymax)
{ return rand() % (ymax - ymin + 1) + ymin; }
double randomy(double ymin, double ymax)
{ return randomy(static_cast<int>(ymin * 100), static_cast<int>(ymax * 100)) / 100.0; }
Приложение C, файл fequa.h
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <math.h>
#include <cmath>
#include <locale.h>
using namespace std;
float equation1()
{
float xmin, ymin, xmax, ymax;
float tchn; //для погрешность
xmin=x0;
xmax=x1;
step=abs(xmax-xmin)/n;
for(; x0<=xmax+step; x0+=step) //нахождения min, max по игрек
{
x=x0;
y=a*x*x*x+b*x+c;
if (y>ymax) ymax=y;
if (y<ymin) ymin=y;
}
//точное значение интеграла
tchn=(a*(xmax*xmax*xmax*xmax-xmin*xmin*xmin*xmin)/4)+(b*(xmax*xmax-xmin*xmin)/2)+c*(xmax-xmin);
x0=xmin;
initwindow(400,300);
moveto(0,150);
for(; x0<=xmax+step; x0+=step)
{
x=x0;
y=a*x*x*x+b*x+c;
lineto((x-xmin)*400/(xmax-xmin),(ymax-y)*300/(ymax-ymin));
}
line((((0-xmin)/(xmax-xmin))*300),0,(((0-xmin)/(xmax-xmin))*300),300); //os y
line(0,(((ymax-0)/(ymax-ymin))*300),400,(((ymax-0)/(ymax-ymin))*300));
float randx, randy, urrand, S, Sf;
float K=0.0,N=0.0;
Sf=(xmax-xmin)*(ymax-ymin);
srand(time(0));
for(int i=1; i<=n; i++) //проверка точек рандомных
{
randx=randomx(xmin, xmax);
randy=randomy(ymin, ymax);
urrand=a*randx*randx*randx+b*randx+c;
if ((urrand<0 && randy<0 && randy>urrand) || (urrand>0 && randy>0 && randy<urrand))
{
K++;
putpixel((randx-xmin)*400/(xmax-xmin),(ymax-randy)*300/(ymax-ymin), 15);
}
else putpixel((randx-xmin)*400/(xmax-xmin),(ymax-randy)*300/(ymax-ymin), 10);
}
S=Sf*(K/n);
cout<<"\n";
cout<<"Приблеженное значение = "<<S<<"\n";
cout<<"Точное значение = "<<tchn<<"\n";
cout<<"Относительная погрешность = "<<abs(tchn-S)/tchn*100<<"%\n";
cout<<"Абсолютная погрешность = "<<abs(tchn-S)<<"\n";
}
float equation2()
{
float xmin, ymin, xmax, ymax;
float tchn; //для погрешность
xmin=x0;
xmax=x1;
step=abs(xmax-xmin)/n;
for(; x0<=xmax+step; x0+=step) //нахождения min, max по игрек
{
x=x0;
y=a*sin(x + b) + c;
if (y>ymax) ymax=y;
if (y<ymin) ymin=y;
}
//точное значение интеграла
tchn=c*(xmax-xmin)-a*(cos(xmax+b)-cos(xmin+b));
x0=xmin;
initwindow(400,300);
moveto(0,150);
for(; x0<=xmax+step; x0+=step)
{
x=x0;
y=a*sin(x + b) + c;
lineto((x-xmin)*400/(xmax-xmin),(ymax-y)*300/(ymax-ymin));
}
line((((0-xmin)/(xmax-xmin))*300),0,(((0-xmin)/(xmax-xmin))*300),300); //os y
line(0,(((ymax-0)/(ymax-ymin))*300),400,(((ymax-0)/(ymax-ymin))*300));
float randx, randy, urrand, S, Sf;
float K=0.0,N=0.0;
Sf=(xmax-xmin)*(ymax-ymin);
srand(time(0));
for(int i=1; i<=n; i++) //проверка точек рандомных
{
randx=randomx(xmin, xmax);
randy=randomy(ymin, ymax);
urrand=a*sin(randx+b)+c;
if ((urrand<0 && randy<0 && randy>urrand) || (urrand>0 && randy>0 && randy<urrand))
{
K++;
putpixel((randx-xmin)*400/(xmax-xmin),(ymax-randy)*300/(ymax-ymin), 15);
}
else putpixel((randx-xmin)*400/(xmax-xmin),(ymax-randy)*300/(ymax-ymin), 10);
}
S=Sf*(K/n);
cout<<"\n";
cout<<"Приблеженное значение = "<<S<<"\n";
cout<<"Точное значение = "<<tchn<<"\n";
cout<<"Относительная погрешность = "<<abs(tchn-S)/tchn*100<<"%\n";
cout<<"Абсолютная погрешность = "<<abs(tchn-S)<<"\n";
}
float equation3()
{
float xmin, ymin, xmax, ymax;
float tchn; //для погрешность
int k;
xmin=x0;
xmax=x1;
step=abs(xmax-xmin)/n;
ymin=xmin;
ymax=xmax;
//точное значение интеграла
tchn=a*(log(abs(xmax+b))-log(abs(xmin+b)))+c*(xmax-xmin);
x0=xmin;
initwindow(400,300);
moveto(0,150);
for(; x0<=xmax+step; x0+=step)
{
x=x0;
y=(a/(x+b))+c;
if (x0<=-b && x0>-b-step) {x+=step; moveto(x,y);}
lineto((x-xmin)*400/(xmax-xmin),(ymax-y)*300/(ymax-ymin));
}
line((((0-xmin)/(xmax-xmin))*300),0,(((0-xmin)/(xmax-xmin))*300),300); //os y
line(0,(((ymax-0)/(ymax-ymin))*300),400,(((ymax-0)/(ymax-ymin))*300));
float randx, randy, urrand, S, Sf;
float K=0.0,N=0.0;
Sf=(xmax-xmin)*(ymax-ymin);
srand(time(0));
for(int i=1; i<=n; i++) //проверка точек рандомных
{
randx=randomx(xmin, xmax);
randy=randomy(ymin, ymax);
urrand=(a/(randx+b))+c;
if ((urrand<0 && randy<0 && randy>urrand) || (urrand>0 && randy>0 && randy<urrand))
{
K++;
putpixel((randx-xmin)*400/(xmax-xmin),(ymax-randy)*300/(ymax-ymin), 15);
}
else putpixel((randx-xmin)*400/(xmax-xmin),(ymax-randy)*300/(ymax-ymin), 10);
}
S=Sf*(K/n);
cout<<"\n";
cout<<"Приблеженное значение = "<<S<<"\n";
cout<<"Точное значение = "<<tchn<<"\n";
cout<<"Относительная погрешность = "<<abs(tchn-S)/tchn*100<<"%\n";
cout<<"Абсолютная погрешность = "<<abs(tchn-S)<<"\n";
} ymax
Приложение D, файл MCmain.cpp
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <math.h>
#include <cmath>
#include <locale.h>
#include "const.h"
#include "fdonk.h"
#include "fequa.h"
using namespace std;
main()
{
setlocale(LC_ALL,"Russian");
int ur;
cout<<"1) a*x^3 + b*x + c;\n";
cout<<"2) a*sin(x + b) + c;\n";
cout<<"3) a/(x + b) + c;\n";
cout<<"Выбор уравнения [1,2,3]: \n"; donkey1(); ur=(int)donk; system("cls");
cout<<"Пределы интегрирования [-1000;1000]: \n"; donkey2(); x0=donk0; x1=donk; system("cls");
cout<<"Первый коэффициент уравнения: \n"; kf='a'; donkey3(); a=donk; system("cls"); //a
cout<<"Второй коэффициент уравнения: \n"; kf='b'; donkey3(); b=donk; system("cls"); //b
cout<<"Третий коэффициент уравнения: \n"; kf='c'; donkey3(); c=donk; system("cls"); //c
cout<<"Точкие разбиения: \n"; donkey4(); n=(int)donk; system("cls"); //n
system("cls");
if (ur==1) cout<<"Уравнение: "<<ur<<" - 'a*x^3 + b*x + c'\n";
if (ur==2) cout<<"Уравнение: "<<ur<<" - 'a*sin(x + b) + c'\n";
if (ur==3) cout<<"Уравнение: "<<ur<<" - 'a/(x + b) + c'\n";
cout<<"\n";
cout<<"Пределы интегрирования [-1000;1000]: ["<<x0<<";"<<x1<<"]\n";
cout<<"Первый коэффициент уравнения: "<<a<<"\n";
cout<<"Второй коэффициент уравнения: "<<b<<"\n";
cout<<"Третий коэффициент уравнения: "<<c<<"\n";
cout<<"Точкие разбиения: "<<n<<"\n";
switch(ur)
{ case 1:
{
equation1();
}; break;
case 2:
{
equation2();
}; break;
case 3:
{
equation3();
}; break;}
getch();
closegraph();
}