Паша ЧМы лаба 5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#define NMAX 1000
#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
inline double f(double x,double y) { return 2*x*x + y*y + x*y + x + y; }
inline double f_dx(double x,double y) { return 4*x + y + 1; }
inline double f_dy(double x,double y) { return 2*y + x + 1; }
inline double g(double x, double y, double alpha) { return f(x - alpha*f_dx(x,y), y - alpha*f_dy(x,y)); }
inline double norma(double x, double y) { return sqrt(x*x+y*y); }
double Dihotomia(double a0, double b0, double epsilon, double x, double y)
{
int k;
double lk, mk;
double delta=0.5*epsilon;
double x_;
double ak=a0, bk=b0;
k=1;
do
{
lk=(ak+bk-delta)/2;
mk=(ak+bk+delta)/2;
k++;
if(g(x,y,lk)<=g(x,y,mk)) bk=mk;
else ak=lk;
} while ((bk-ak)>=epsilon);
x_=(ak+bk)/2; //minimum point
return x_;
}
// метод наискорейшего спуска
double GreatDescent(double bx, double by,double epsilon)
{
double x[NMAX];
double y[NMAX];
double alpha[NMAX];
int k;
//Начальное приближение u[0]
x[0]=bx;
y[0]=by;
std::cout <<"Результаты:"
<<std::endl<< "x("<<0<<"): ("<<x[0]<<", "<<y[0]<<")"<<std::endl;
for (k=0; ; k++)
{
alpha[k]=Dihotomia(-10000,100000,epsilon,x[k],y[k]);
x[k+1]=x[k]-alpha[k]*f_dx(x[k], y[k]);
y[k+1]=y[k]-alpha[k]*f_dy(x[k], y[k]);
std::cout<<"x("<<k+1<<"): "<<"("<<x[k+1]<<", "<<y[k+1]<<")"<<std::endl
<<"f("<<x[k+1]<<", "<<y[k+1]<<") = "<<f(x[k+1], y[k+1]) <<std::endl;
if (k>1 && norma(x[k+1]-x[k],y[k+1]-y[k])<epsilon) break;
}
std::cout <<"Точка минимума (epsilon="<<epsilon<<")"<<std::endl
<<"f("<<x[k+1]<<", "<<y[k+1]<<") = "<<f(x[k+1], y[k+1]) <<std::endl;
return f(x[k+1],y[k+1]);
}
int main()
{
double x,y,epsilon;
std::cout <<"x0 = ";
std::cin>>x;
std::cout <<"y0 = ";
std::cin>>y;
std::cout <<"epsilon = ";
std::cin>>epsilon;
GreatDescent(x,y,epsilon);
return 0;
}