- •Уфимский государственный авиационный технический университет
- •Разработка прикладного алгоритма
- •Пояснительная записка
- •Уфимский государственный авиационный технический университет
- •1.Технические условия
- •2. Содержание проекта
- •4. Список используемой литературы:
- •1 Постановка задачи и описание исходных данных
- •2 Математическое обеспечение
- •4 Разработка алгоритма программы в виде блок-схемы
- •Создание проекта
- •5 Описание работы программы
- •Список используемой литературы
- •Приложения
- •Листинг функции кнопки «Построить!»
- •Описание переменных
5 Описание работы программы
Рисунок 3 – Интерфейс программы
В группу "Начальные данные" пользователем вводятся значения для переменных a,b,k,m соответственно. Кнопка "Установить случайный набор значений" задает параметрам a,b,k,m произвольные значения. Кнопка "Построить!" выполняет необходимые построения, а также вычисляет площадь искомой фигуры методом Монте-Карло. Кнопка "Очистить экран" удаляет все содержимое графического поля.
Группа "Настройки изображения" содержит 3 настройки (флажка), позволяющих регулировать некоторые особенности отображения графика (строить ли оси координат, контейнер, сетку).
Группа "Результаты вычислений" содержит в себе всю информацию, полученную при анализе входных данных: координаты пересечения графика параболы с прямыми k и m, пересечение параболы с осью OX. Кроме того, в этой группе отображены и результаты работы самого метода Монте-Карло, в частности, площадь искомой фигуры.
В нижней части программы расположено поле, отображающее время выполнения программы (отображается в секундах).
Вывод
В результате выполнения данной курсовой работы был детально изучен метод Монте-Карло (имитационное моделирование). Кроме того, были изучены фундаментальные основы программирования в среде Microsoft Visual Studio 6.0, с использованием MFC (Microsoft Foundation Classes). Не смотря на то, что Visual Studio C++ автоматически генерирует фрагменты кода, а MFC подключает все необходимые библиотеки для использования GUI (Grahical User Interface), разработка алгоритма программы в любом случае остается непосредственной обязанностью программиста. Таким образом, для выполнения поставленной в курсовом проектировании задачи, были изучены не только основы программирования на языке С++, но и рассмотрена общая теория Объектно-Ориентированного Программирования.
Список используемой литературы
1. Страуструп Б. Язык программирования С++. Специальное издание. Пер. с англ. – М.: Издательство Бином, 2011. – 1136 с. : ил.
2. Селиванова М.В. Методические указания к курсовой работе по дисциплине «Методы программирования и прикладные алгоритмы»/ Уфимск. гос. авиац. тех. ун-т. Сост. Селиванова М.В. – Уфа, 2008. – 31 с.
3. Седжвик, Р. Алгоритмы на C++.: Пер. с англ. – М.: ООО "И.Д. Вильямс", 2011 - 1056 с.
4. Страуструп Б. Программирование: принципы и практика использования C++, испр. изд.: Пер. с англ. –М.:ООО "И.Д. Вильямс", 2011. – 1248с.
5. Кнут Д. Искусство программирования. Т.3 Сортировка и поиск. М.: Вильямс, 2000. – 832 с.
Приложения
Приложение А
Листинг функции кнопки «Построить!»
void CKlab1Dlg::OnBuildGraph()
{
float runtime0=0;
clock_t start, finish;
start=clock();
//Считывание информации
UpdateData(1);
float precision,a,b,k,m;
float p1,p2; //точки пересечения прямых x=k и x=m
float x1,x2; // точки пересечения параболы и oX
precision=textbox_precision; //это точность измерений
a=textbox_avalue; //параметр а - коэффициент параболы при квадратичном иксе
b=textbox_bvalue; // b - коэффициент при икс
k=textbox_kvalue; // x=k прямая вертикальная
m=textbox_mvalue; // прямая x=m вертикальная
UpdateData(1);
//Расчет
if (k>m) // Для определенности положим, что K всегда меньше m
{
float b2;
b2=k;
k=m;
Продолжение приложения А
m=b2;
}
p1=a*k*k+b;
p2=a*m*m+b; //нашли точки Y пересечения с параболой прямых
// определение интервала генерации чисел для оси oY
interval_y_max=0;
interval_y_min=0;
if (b*a<0) {interval_y_min=b; interval_y_max=0;} // вариант 1.1 и 1.2
if (b==0) // вариант 2.1 и 2.2
{
if (abs(p1)>abs(p2)) {interval_y_max=p1;} else {interval_y_max=p2;}
interval_y_min=0;
}
if (b*a>0) // вариант 3.1 и 3.2
{
if (abs(p1)>abs(p2)) {interval_y_max=p1;} else {interval_y_max=p2;}
interval_y_min=0;
}
// Решение квадратного уравнения и определение действительных корней
if (-4*a*b>=0)
{
x1=sqrt(-b/a);
Продолжение приложения А
x2=-1*x1; // симметрична относ oY
} else
{
x1=0;
x2=0;
}
//генерация по X
interval_x_max=0;
interval_x_min=0;
if (b*a<0) // вариант 1.1 и 1.2
{
interval_x_max=0;
interval_x_min=0;
if (x1<m && p2*b<0) {interval_x_max=x1;} else {interval_x_max=m;};
if (x2>k && b*p1<0) {interval_x_min=x2;} else {interval_x_min=k;};
}
if (b==0) // вариант 2.1 и 2.2
{
if (k>m) {interval_x_max=k; interval_x_min=m;} else {interval_x_max=m; interval_x_min=k;}
}
Продолжение приложения А
if (b*a>0) // вариант 3.1 и 3.2
{
if (k>m) {interval_x_max=k; interval_x_min=m;} else {interval_x_max=m; interval_x_min=k;}
}
float buf;
if (interval_x_max<interval_x_min)
{
buf=interval_x_max;
interval_x_max=interval_x_min;
interval_x_min=buf;
}
if (interval_y_max<interval_y_min)
{
buf=interval_y_max;
interval_y_max=interval_y_min;
interval_y_min=buf;
}
//Имитационное моделирование. Подсчет площади через точки
float s_cont=0, s_figure=0;
int cnt_points=0,debug_neg_cnt_points=0;
float diax=0,diay=0;
float xr=0,yr=0;
Продолжение приложения А
float xran[10000];
float yran[10000];
diax=fabs(interval_x_max)+fabs(interval_x_min);
diay=fabs(interval_y_max)+fabs(interval_y_min);
s_cont=diax*diay;
FILE* logfile2;
logfile2=fopen("c:\\logfile2.txt","w");
fprintf(logfile2,"\n");
fprintf(logfile2,"y(x)=%f*x^2+%f\n",a,b);
fprintf(logfile2,"| xr | YR | f(y) | COUNT |\n");
srand(time(NULL));
for (int c2=0;c2<precision;c2++)
{
xr=(512*rand()%int(diax*10000)*0.0001)+interval_x_min;
yr=(512*rand()%int(diay*10000)*0.0001)+interval_y_min;
if (fabs(yr)<fabs(a*xr*xr+b)) cnt_points++; else debug_neg_cnt_points++;
fprintf(logfile2,"| %.12f | %.12f | %.12f | %.12i |\n",xr,yr,fabs(a*xr*xr+b),cnt_points );
xran[c2]=xr;
yran[c2]=yr;
}
textbox_answer=s_cont*(float(cnt_points)/precision);
textbox_contsq=s_cont;
// Проверка правильности обычным интегральным методом.
Продолжение приложения А
float sp=0;
sp=((a*interval_x_max*interval_x_max*interval_x_max)/3+b*interval_x_max)-((a*interval_x_min*interval_x_min*interval_x_min)/3+b*interval_x_min);
sp=fabs(sp);
textbox_sintegral=sp;
textbox_pogr=(fabs(sp-s_cont*(float(cnt_points)/precision))/sp)*100;
//Вывод в лог-файл на диске C:\
UpdateData(0);
fprintf(logfile2,"\n");
fprintf(logfile2,"Values:\n a=%f;\n b=%f;\n k=%f;\n m=%f\n",a,b,k,m);
fprintf(logfile2,"P1: %f;\nP2: %f;\n",p1,p2);
fprintf(logfile2,"x1=%f,\nx2=%f\n",x1,x2);
fprintf(logfile2,"interval_y_max=%f;\ninterval_y_min=%f\n",interval_y_max, interval_y_min);
fprintf(logfile2,"interval_x_max=%f;\ninterval_x_min=%f\n",interval_x_max,interval_x_min);
//Вывод в графический интерфейс
UpdateData(0);
textbox_debug_p1=p1;
textbox_debug_p2=p2;
textbox_out_xgen=x1;
textbox_out_ygen=x2;
textbox_cnt_p=cnt_points;
textbox_cnt_pall=cnt_points+debug_neg_cnt_points;
Продолжение приложения А
UpdateData(0);
// построение
CPen MainGraphicPen(PS_SOLID,1,RGB(0,2,255));
CClientDC MyDC(GetDlgItem(IDC_STATICpicture));
CRect rect1(1,1,500,500);
CWnd *pWnd=MyDC.GetWindow();
pWnd->GetClientRect(&rect1);
MyDC.FillSolidRect(rect1,RGB(255,255,255));
CBrush MyBrush(RGB(0,0,1));
if (container)
{
float rect_x1=0,rect_x2=0, rect_y1=0, rect_y2=0;
CBrush MyBrush2(HS_BDIAGONAL, RGB(255,0,0));
MyDC.SelectObject(&MyBrush2);
rect_x1=interval_x_max*20+250;
if (interval_y_max<9) {rect_y1=interval_y_max*(-20)+200;} else {rect_y1=0;}
rect_x2=interval_x_min*20+250;
if (interval_y_min>-9) {rect_y2=interval_y_min*(-20)+200;} else {rect_y2=400;}
MyDC.Rectangle(rect_x1,rect_y1,rect_x2,rect_y2);
}
if (grid)
{
Продолжение приложения А
CPen Grid(PS_SOLID,1,RGB(133,133,133));
MyDC.SelectObject(&Grid);
for (int x=10;x<500;x=x+20)
{
MyDC.MoveTo(x,0);
MyDC.LineTo(x,400);
}
for (int y=20;y<400;y=y+20)
{
MyDC.MoveTo(500,y);
MyDC.LineTo(0,y);
}
}
if (Axes)
{
CPen Coords(PS_SOLID,1,RGB(0,2,255));
MyDC.SelectObject(&Coords);
//Рисование координат
MyDC.MoveTo(250,0);
MyDC.LineTo(250,400);
MyDC.MoveTo(0,200);
MyDC.LineTo(500,200);
//Рисование меток на оси X
Продолжение приложения А
for (int x=10;x<500;x=x+20)
{
MyDC.MoveTo(x,195);
MyDC.LineTo(x,205);
}
//Рисование меток на оси Y
for (int y=20;y<400;y=y+20)
{
MyDC.MoveTo(245,y);
MyDC.LineTo(255,y);
}
}
MyDC.MoveTo(k*20+250,0); //Рисуем линию x=k
MyDC.LineTo(k*20+250,400);
MyDC.MoveTo(m*20+250,0); //Рисуем линию x=m
MyDC.LineTo(m*20+250,400);
CPoint p;
// Рисование самого графика
MyDC.SelectObject(&MainGraphicPen);
int xgraph=0;
int ygraph=0;
int y=0;
Продолжение приложения А
bool flag=true;
for (int x=-250;x<250;x++)
{
xgraph=x+250;
y=-1*a*0.05*x*x-b*20; //коэффициенты увеличения уже учтены
ygraph=y+200;
if (ygraph>400 || ygraph<0) continue;
if (flag) {MyDC.MoveTo(xgraph,ygraph);}
MyDC.LineTo(xgraph,ygraph);
flag=false;
}
MyDC.SelectObject(&MainGraphicPen);
for (int c3=0;c3<precision;c3++)
{
MyDC.MoveTo(xran[c3]*20+250,yran[c3]*(-20)+200);
MyDC.LineTo(xran[c3]*20+250-1,yran[c3]*(-20)+200);
}
finish=clock();
runtime0=(double) (finish-start)/CLOCKS_PER_SEC;
textbox_time=runtime0;
UpdateData(0);
}
Приложение В