- •Курсовой проект по учебной дисциплине
- •Задание на проектирование
- •Введение
- •Методы решения оптимизационной задачи
- •Метод Свенна
- •Метод Ньютона
- •Метод дихотомии
- •Метод золотого сечения
- •Алгоритм зс-1
- •Метод квадратичной интерполяции – экстраполяции
- •Метод Фибоначчи
- •Алгоритм Фибоначчи-1
- •Метод Давидона
- •Исследование методов полиномиальной интерполяции для поиска минимума целевых функций
- •Исследование методов линейного поиска
- •Заключение
Исследование методов полиномиальной интерполяции для поиска минимума целевых функций
Метод Золотого сечения-1 - Метод экстраполяции-интерполяции
Спецификация программы.
a,b– текущий интервала локализации
c– третья точка
h– размер шага
min–минимум
x1 – стартовая точка
k,k1,k2 – счетчики числа итераций.
Текст программы:
#include <iostream.h>
#include <math.h>
#include <stdio.h>
#include <iostream.h>
#include <conio.h>
double a,b,c;
double x1,x2,h,h1,min;
int k, k1, k2; // счетчик циклов
double t1=(sqrt(5.0)-1)/2;
double t2=(3-sqrt(5.0))/2;
double fx(double x) // заданная функция
{
return (x*x+2*x);
}
double Sven (double x1, double x2, double h)
{ // Метод Свенн
long double x3,z;
x2=x1+h;
k1=1;
while (1)
{
h=2*h;
x3=x2+h;
if (fx(x3)>fx(x2))
break;
x1=x2;
x2=x3;
k1=k1+1;
}
a=x1;
b=x3;
if (a>b) // перестановка для: а - всегда слева, b - справа
{
z=b;
b=a;
a=z;
}
return h;
}
double zs1(double a, double b) //Метод золотое сечение-1
{
double e,m,y,min;
y=a+t1*fabs(a-b);
m=a+t2*fabs(a-b);
k=1;
e=0.1;
while(fabs(a-b)>e)
{
if (fx(y)<fx(m))
{
b=m;
m=y;
y=a+t2*fabs(a-b);
}
else
{
a=y;
y=m;
m=a+t1*fabs(a-b);
}
k++;
}
min=(a+b)/2;
return min;
}
double inter(double a,double b,double c)
{
double fa,fb,fc;
fa=fx(a);
fb=fx(b);
fc=fx(c);
return (0.5*(fa*(b*b-c*c)+fb*(c*c-a*a)+fc*(a*a-b*b))/(fa*(b-c)+fb*(c-a)+fc*(a-b)));
} ;
void main()
{
clrscr();
h=0.01;
x1=4;
x2=x1+h;
if(fx(x2)>fx(x1))
{h=-h;
x2=x1+h;
}
h=Sven(x1,x2,h);
cout<<"\na = "<<a; //Получили a и b после Свенна
cout<<"\nb = "<<b;
min=zs1(a,b); // Золотое сечение 1
cout<<"\n\nZolotoe sechenie-1. k= "<<k;
cout<<"\nminimum = "<<min;
c=(a+b)/2; // Задаем 3 точку
min=inter(a,b,c);
min=fabs(min);
cout<<"\n\nInter";
cout<<"\nminimum= "<<min;
getch();
}
Результаты тестирования различных методов:
Ниже приведены таблицы с результатами работы программы для двух методов, с различными стартовыми точками и точностями вычисления.
Точность: |
|
0.01 |
X1=4 |
К |
X* |
Метод Свенна |
10 |
[-6,23;1,45] |
Метод интерполяция |
1 |
1 |
Точность: |
|
0.001 |
X1=4 |
К |
X* |
Метод Свенна |
10 |
[-6,227;1,451] |
Метод интерполяция |
1 |
1 |
График функции
Исследование методов линейного поиска
Метод Фибоначчи – метод Дэвидона
Спецификация
a, b – текущий интервала локализации
x10, x20 – начальная точка
p1, p2 – направление поиска
x* - значение минимума
k – счетчики числа итераций.
Текст программы:
#include<conio.h>
#include<iostream.h>
#include<iomanip.h>
#include<math.h>
double a, b, x1, x2, x10, x20, r1, p1, p2, n, F, L, Ln, alpha, e=0.01;
int k;
double fc(double alpha)
{ return(pow((x10+alpha*p1-2),4)+pow((x10+alpha*p1-2*(x20+alpha*p2)),2));
}
double pr(double a)
{
double g1, g2;
g1=4*pow(((x10+a*p1)-2),3)+2*((x10+a*p1)-2*(x20+a*p2));
g2=-4*((x10+a*p1)-2*(x20+a*p2));
return (g1*p1+g2*p2);
}
double Svenn(double p1, double p2)
{
alpha=0.1;
k=0;
if(pr(alpha) < 0)
{ p1=+p1;
p2=+p2;
}
else
{ p1=-p1;
p2=-p2;
}
do
{
k=k+1;
alpha=2*alpha;
}
while(pr(alpha)<0);
return alpha;
}
double fib (double s)
{ double fib1=1; double fib2=1;
double sum;
for(int y=2;y<s;y++)
{ sum=fib1+fib2;
fib1=fib2;
fib2=sum;
}
return sum;
}
double Fibbonachi(double a1, double b1, double n, double L)
{
x1=a1+(fib(n-2)/fib(n))*L;
x2=a1+(fib(n-1)/fib(n))*L;
k=0;
for(int i=0; i<n; i++)
{
if(fc(x1)>=fc(x2))
{ a1=x1;
b1=b1;
x1=x2;
L=fabs(b1-a1);
x2= a1+b1-x1; //a1+(fib(n-i-2)/fib(n))*L;
}
else
{ a1=a1;
b1=x2;
x2=x1;
L=fabs(b1-a1);
x1=a1+b1-x2; //a1+(fib(n-i-3)/fib(n))*L;
}
k=k+1;
}
if(fc(x1)>=fc(x2))
alpha=(x1+b1)/2;
else
alpha=(x2+a1)/2;
return alpha;
}
double Davidon(double a, double b)
{
double alpha_min, w, z, e, q1,q2,q3;
e=0.001;
int y=0;
do
{
z=pr(a)+pr(b)+(3*(fc(a)-fc(b)))/(b-a);
q1=(pr(a));
q2=(pr(b));
q3=(z*z);
w=sqrt(q3-q2*q1);
r1=a+(b-a)*((w-pr(a)+z)/(2*w-pr(a)+pr(b)));
if(pr(r1) > 0)
{
b=r1;
}
else
{
a=r1;
}
++y;
}
while(fabs(pr(r1))>=e);
return r1;
}
void main()
{
clrscr();
k=0;
x10=0;
x20=3;
p1=1;
p2=0;
Svenn (p1, p2);
cout<<"Posle Svenn"<<endl;
// x1=x10+alpha/4*p1;
// x2=x20+alpha/4*p2;
// cout<<"\na= "<<x1<<", b= "<<x2<<"]";
x1=x10+alpha*p1;
x2=x20+alpha*p2;
double a1=alpha/4;
double b1=alpha;
cout<<"a1="<<a1<<" b1="<<b1<<endl<<endl;
Ln=0.2;
L = fabs(b1-a1);
F = L/Ln;
n = log(F*sqrt(5))/log(1.618);
Fibbonachi(a1,b1,b,L);
cout<<"Posle Fibonachi"<<endl;
a=x10+alpha*p1;
b=x20+alpha*p2;
cout<<"a= "<<a<<" b= "<<b<<endl<<endl;
Davidon(a,b);
x1=x10+r1*p1;
x2=x20+alpha*p2;
cout<<"Posle Davidona"<<endl;
cout<<"x1= "<<x1<<" x2= "<<x2<<endl;
getch();
}
Результаты работы программы:
Интервал по Свенну: a= -0,8b=3
Число повторений цикла после установления интервала k=5
Метод Фибоначчи: а = 3,2 b=3
Метод Дэвидона: х1= 3,12818 x2= 3