Лабораторная работа №11 / Отчет
.docМинистерство Образования Российской Федерации
Уфимский Государственный Авиационный Технический Университет
Кафедра ТК
Отчет по лабораторной работе №1
по предмету «Методы оптимизации»
на тему: Безусловная одномерная оптимизация
Выполнил: студент гр.Т28-320
Проверил: Хасанов А.Ю.
-Уфа, 2004 -
Лабораторная работа №1
Тема: Безусловная одномерная оптимизация
Методы: алгоритм блочного равномерного поиска;
алгоритм пассивного поиска минимума;
метод чисел Фибоначчи;
Задание: найти точку минимума функции f(x) = на отрезке [-1,0] при заданном числе экспериментов N=18.
Описание алгоритма в псевдокоде:
алгоритм F(x)
начало
скаляр ans=0; - вещественное
ans=x*x+exp(x);
возврат ans;
конец
алгоритм T(a, b, c, ya, yb, yc)
начало
скаляр x - вещественное
x=(b-c)*(b-c)*(ya-yc)-(c-a)*(c-a)*(yb-yc);
x=x/((b-c)*(ya-yc)+(c-a)*(yb-yc));
x=x/2;x+=c;
возврат (x);
конец
алгоритм **XY(a,b,ya,yb,n)
начало
массив XY[2][n+2] - вещественный
XY[0][0]=a;XY[1][0]=ya;
XY[0][n+1]=b;XY[1][n+1]=yb;
для i=1,i<=n, i++ повторить
начало
XY[0][i]=a+i*(b-a)/(n+1);
XY[1][i]=F(XY[0][i]);
конец
возврат XY;
конец
алгоритм **CXY(a, b, s, ya, yb, ys, n)
начало
вещественное **Tmp;
массив x[2][n+1] вещественный
xy[0][0]=a;xy[1][0]=ya;
xy[0][n+1]=b;xy[1][n+1]=yb;
если fmod(n,2)!=0 то
начало
Tmp=XY(a,s,ya,ys,(n-1)/2);
Для int i=1;i<=(n+1)/2;i++ повторить
начало
xy[0][i]=Tmp[0][i];
xy[1][i]=Tmp[1][i];
конец
Tmp=XY(s,b,ys,yb,(n-1)/2);
для int i=(n+1)/2;i<=n;i++)
начало
xy[0][i]=Tmp[0][i-(n+1)/2];
xy[1][i]=Tmp[1][i-(n+1)/2];
конец
конец
иначе
xy=XY(a,b,ya,yb,n);
все-если
возврат xy;
конец
алгоритм блочный поиск
начало
скаляры a=-1;ya=F(a);b=0;yb=F(b);s,ys;**xy; - вещественные
N=StrToInt(edtN->Text)-2;int n=StrToInt(edtD->Text);int ts=N/n; - Целые
xy=XY(a,b,ya,yb,n);
для i=2;i<=ts;i++ повторить
начало
c=xy[1][1];
t=1;
для k=2;k<=n;k++ повторить
если(xy[1][k]<c)началоc=xy[1][k];t=k;конец
a=xy[0][t-1];ya=xy[1][t-1];
b=xy[0][t+1];yb=xy[1][t+1];
s=xy[0][t];ys=xy[1][t];
xy=CXY(a,b,s,ya,yb,ys,n);
конец
вывод (b-a)/2,(a+b)/2
конец
алгоритм золотого сечения
начало
скаляры Lmb=1.618033989; a=-1; b=0; - Вещественные
N=StrToInt(edtN->Text); - Целое
x1=b-(b-a)/Lmb;x2=a+(b-a)/Lmb; y1=F(x1); y2=F(x2);- вещественное
для int i=1;i<=N;i++ повторить
начало
если (y1>y2) то
начало
a=x1;
x1=x2;y1=y2;
x2=a+(b-a)/Lmb;y2=F(x2);
конец
иначе
начало
b=x2;
x2=x1;y2=y1;
x1=b-(b-a)/Lmb;y1=F(x1);
конец
все-если
конец
вывод (fabs(b-a)/2),(b+a)/2;
конец
алгоритм метод парабол
начало
скаляры a=-1; b=0;
c=a+(b-a)/2; ya=F(a); yb=F(b);
yc=F(c); x=T(a,b,c,ya,yb,yc);
yx=F(x); - Вещественное
N=StrToInt(edtN->Text); - Целое
для int i=1;i<=N-4;i++ повторить
начало
fl=0;
если (x>c)то fl=1; все-если
если (x<c)то fl=2; все-если
если (x==c)то fl=3; все-если
выбрать (fl)
начало
case 1:
начало
если(yx>yc)начало b=x;yb=yx;x=T(a,b,c,ya,yb,yc);yx=F(x);конец
иначе если(yx<yc)начало a=c;ya=yc;c=x;yc=yx;x=T(a,b,c,ya,yb,yc);yx=F(x);конец
иначе если(yx==yc)начало a=c;ya=yc;b=x;yb=yx;c=(a+b)/2;yc=F(c);x=T(a,b,c,ya,yb,yc);
yx=F(x);i++;конец конец break;
case 2:
начало
если(yx>yc)начало a=x;ya=yx;x=T(a,b,c,ya,yb,yc);yx=F(x);конец
иначе если(yx<yc)начало b=c;yb=yc;c=x;yc=yx;x=T(a,b,c,ya,yb,yc);yx=F(x);конец
иначе если(yx==yc)началоa=x;ya=yx;b=c;yb=yc;c=(a+b)/2;yc=F(c);x=T(a,b,c,ya,yb,yc);
yx=F(x);i++;конец конец break;
case 3:началоx=(a+c)/2;yx=F(x);конец break;
конец
конец
вывод (fabs(b-a)/2),((b+a)/2);
конец
конец
Листинг программы:
Main.cpp
#include <vcl.h>
#pragma hdrstop
#include <math.h>
#include "Main.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
long double F(long double x)
{
long double ans=0;
ans=x*x+exp(x);
return ans;
}
long double T(long double a,
long double b,
long double c,
long double ya,
long double yb,
long double yc)
{
long double x;
x=(b-c)*(b-c)*(ya-yc)-(c-a)*(c-a)*(yb-yc);
x=x/((b-c)*(ya-yc)+(c-a)*(yb-yc));
x=x/2;x+=c;
return (x);
}
long double **XY(long double a,long double b,long double ya,long double yb,int n)
{
long double **XY;
XY = new long double *[2];
XY[0] = new long double [n+2];
XY[1] = new long double [n+2];
XY[0][0]=a;XY[1][0]=ya;
XY[0][n+1]=b;XY[1][n+1]=yb;
for (int i=1;i<=n;i++)
{
XY[0][i]=a+i*(b-a)/(n+1);
XY[1][i]=F(XY[0][i]);
}
return XY;
}
long double **CXY(long double a, long double b, long double s,
long double ya,long double yb,long double ys,
int n)
{
long double **xy;
long double **Tmp;
xy = new long double *[2];
xy[0] = new long double [n+2];
xy[1] = new long double [n+2];
xy[0][0]=a;xy[1][0]=ya;
xy[0][n+1]=b;xy[1][n+1]=yb;
if(fmod(n,2)!=0)
{
Tmp=XY(a,s,ya,ys,(n-1)/2);
для int i=1;i<=(n+1)/2;i++)
{
xy[0][i]=Tmp[0][i];
xy[1][i]=Tmp[1][i];
}
Tmp=XY(s,b,ys,yb,(n-1)/2);
для int i=(n+1)/2;i<=n;i++)
{
xy[0][i]=Tmp[0][i-(n+1)/2];
xy[1][i]=Tmp[1][i-(n+1)/2];
}
}
else
xy=XY(a,b,ya,yb,n);
return xy;
}
TfrmMain *frmMain;
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
для long double i=-1;i<=0.00;i+=0.05)
Series1->AddXY(i,F(i),"",clRed);
}
void __fastcall TfrmMain::btnCloseClick(TObject *Sender)
{
Close();
}
void __fastcall TfrmMain::btnSearchClick(TObject *Sender)
{
if (rbtn1->Checked)
{
long double a=-1;long double ya=F(a);
long double b=0;long double yb=F(b);
long double s,ys;
int N=StrToInt(edtN->Text)-2;
int n=StrToInt(edtD->Text);
int ts=N/n;
long double **xy;
xy=XY(a,b,ya,yb,n);
для int i=2;i<=ts;i++)
{
long double c=xy[1][1];
int t=1;
для int k=2;k<=n;k++)
if(xy[1][k]<c){c=xy[1][k];t=k;}
a=xy[0][t-1];ya=xy[1][t-1];
b=xy[0][t+1];yb=xy[1][t+1];
s=xy[0][t];ys=xy[1][t];
xy=CXY(a,b,s,ya,yb,ys,n);
}
edtE->Text=FloatToStr((b-a)/2);
edtX->Text=FloatToStr((a+b)/2);
}
if (rbtn2->Checked)
{
long double Lmb=1.618033989;
long double a=-1;
long double b=0;
int N=StrToInt(edtN->Text);
long double x1=b-(b-a)/Lmb;
long double x2=a+(b-a)/Lmb;
long double y1=F(x1);
long double y2=F(x2);
для int i=1;i<=N;i++)
{
if(y1>y2)
{
a=x1;
x1=x2;y1=y2;
x2=a+(b-a)/Lmb;y2=F(x2);
}
else
{
b=x2;
x2=x1;y2=y1;
x1=b-(b-a)/Lmb;y1=F(x1);
}
}
edtE->Text=FloatToStr(fabs(b-a)/2);
edtX->Text=FloatToStr((b+a)/2);
}
if(rbtn3->Checked)
{
float a=-1;
long double b=0;
int N=StrToInt(edtN->Text);
long double c=a+(b-a)/2;
long double ya=F(a);
long double yb=F(b);
long double yc=F(c);
long double x; x=T(a,b,c,ya,yb,yc);
long double yx=F(x);
для int i=1;i<=N-4;i++)
{
int fl=0;
if (x>c)fl=1;
if (x<c)fl=2;
if (x==c)fl=3;
switch (fl)
{
case 1:
{
if(yx>yc){b=x;yb=yx;x=T(a,b,c,ya,yb,yc);yx=F(x);}
else if(yx<yc){a=c;ya=yc;c=x;yc=yx;x=T(a,b,c,ya,yb,yc);yx=F(x);}
else if(yx==yc){a=c;ya=yc;b=x;yb=yx;c=(a+b)/2;yc=F(c);x=T(a,b,c,ya,yb,yc);yx=F(x);i++;}
}break;
case 2:
{
if(yx>yc){a=x;ya=yx;x=T(a,b,c,ya,yb,yc);yx=F(x);}
else if(yx<yc){b=c;yb=yc;c=x;yc=yx;x=T(a,b,c,ya,yb,yc);yx=F(x);}
else if(yx==yc){a=x;ya=yx;b=c;yb=yc;c=(a+b)/2;yc=F(c);x=T(a,b,c,ya,yb,yc);yx=F(x);i++;}
}break;
case 3:{x=(a+c)/2;yx=F(x);}break;
}
}
edtE->Text=FloatToStr(fabs(b-a)/2);
edtX->Text=FloatToStr((b+a)/2);
}
}
void __fastcall TfrmMain::rbtn1Click(TObject *Sender)
{
edtD->Enabled=1;
btnBlockSize->Enabled=1;
}
void __fastcall TfrmMain::rbtn2Click(TObject *Sender)
{
edtD->Enabled=0;
btnBlockSize->Enabled=0;
}
void __fastcall TfrmMain::rbtn3Click(TObject *Sender)
{
edtD->Enabled=0;
btnBlockSize->Enabled=0;
}
void __fastcall TfrmMain::btnBlockSizeClick(TObject *Sender)
{
long double N=StrToInt(edtN->Text)-2;
long double i=2;
while((i<=N)&&(fmod(N,i)!=0)) i++;
edtD->Text=FloatToStr(i);
}
Тестирование: