Скачиваний:
11
Добавлен:
03.06.2014
Размер:
100.71 Кб
Скачать

Спецификация программы.

В данной программе используется метод Гаусса-Зейделя.

Прототипы функции:

Vector(int Size);

Vector(const Vector& v);

~Vector();

int size() const;

double& Vector::operator[](int N);

double Vector::operator[](int N) const;

void Sum(const Vector& a, const Vector& b);

void Subtraction(const Vector& a, const Vector& b);

Vector Scal(Vector x, double d);

double Mult(const Vector& a, const Vector& b);

Vector& operator=(const Vector& a);

Vector function(Vector& x, double E, int method, int & it);

void Write() const;

Vector Grad(const Vector& x);

/***************Lab3***************/

void Swenn(const Vector& x, Vector& p, double& ala, double& alb);

//double ZS1(Vector& x, Vector p, double al1, double al2);

double ZS1(Vector& x, Vector p, double al1, double al2, double E, int & it);

double Powell(Vector& x, Vector p, double al1, double al2, double E, int & it);

/***************Lab4***************/

Vector Ort(int n, int Num);

double Norma(Vector x);

Vector GZ_3(Vector& x, double E, int maxiter, int& iter, int& boo, int method, int razmer);

Результаты тестирования программы.

Функция y(x)

Начальная точка (x1) t

Значение минимума Пауэлла (x*)t

Значение минимума Золотое сечение (x*)t

(x1 - 1)2 + (x2 - 3)2 + 4(x3 + 5)2

( 4 ; -1 ; 2 )

( 1 ; 3 ; -5)

( 1 ; 3 ; -5)

Текст программы.

#include "stdafx.h"

#include <iostream>

#include <conio.h>

#include <math.h>

using namespace std;

class Vector

{

public:

Vector(int Size);

Vector(const Vector& v);

~Vector();

int size() const;

double& Vector::operator[](int N);

double Vector::operator[](int N) const;

void Sum(const Vector& a, const Vector& b);

void Subtraction(const Vector& a, const Vector& b);

Vector Scal(Vector x, double d);

double Mult(const Vector& a, const Vector& b);

Vector& operator=(const Vector& a);

Vector function(Vector& x, double E, int method, int & it);

void Write() const;

Vector Grad(const Vector& x);

/***************Lab3***************/

void Swenn(const Vector& x, Vector& p, double& ala, double& alb);

//double ZS1(Vector& x, Vector p, double al1, double al2);

double ZS1(Vector& x, Vector p, double al1, double al2, double E, int & it);

double Powell(Vector& x, Vector p, double al1, double al2, double E, int & it);

/***************Lab4***************/

Vector Ort(int n, int Num);

double Norma(Vector x);

Vector GZ_3(Vector& x, double E, int maxiter, int& iter, int& boo, int method, int razmer);

Vector operator+(const Vector& a)

{

Vector s(nSize);

s.Sum(*this, a);

return s;

}

Vector operator-(const Vector& a)

{

Vector s(nSize);

s.Subtraction(*this, a);

return s;

}

double operator*(const Vector& a)

{

double w;

Vector s(nSize);

w = s.Mult(*this, a);

return w;

}

void operator*=(double d)

{

for (int i = 0; i < nSize; i++)

Coord[i] *= d;

}

private:

double* Coord;

int nSize;

};

Vector::Vector(int Size)

{

nSize = Size;

Coord = new double[Size];

}

Vector::Vector(const Vector& v)

{

nSize = v.size();

Coord = new double[nSize];

for (int i = 0; i < nSize; i++)

Coord[i] = v[i];

}

Vector::~Vector()

{

delete[] Coord;

}

int Vector::size() const

{

return nSize;

}

double& Vector::operator[](int N)

{

return *&Coord[N];

}

double Vector::operator[](int N) const

{

return Coord[N];

}

Vector Vector::Scal(Vector x, double d)

{

int i = x.size();

Vector W(i);

for(int j=0; j<i; j++)

W[j] = x[j]*d;

return W;

}

void Vector::Sum(const Vector& a, const Vector& b)

{

int s = a.size();

int i;

if ((s = b.size()) != 0 )

{

for (i = 0; i < s; i++)

{

Coord[i] = a[i] + b[i];

}

}

else

{

cout<<"ERROR!"<<endl;

}

}

void Vector::Subtraction(const Vector& a, const Vector& b)

{

int s = a.size();

int i;

if ((s = b.size()) != 0 )

{

for (i = 0; i < s; i++)

{

Coord[i] = a[i] - b[i];

}

}

else

{

cout<<"ERROR!"<<endl;

}

}

double Vector::Mult(const Vector& a, const Vector& b)

{

int s = a.size();

//int i;

double Um=0;

if ((s = b.size()) != 0 )

{

for (int i = 0; i < s; i++)

{

Coord[i] = a[i] * b[i];

Um = Um + Coord[i];

}

}

return Um;

}

Vector& Vector::operator =(const Vector& a)

{

for (int i = 0; i < nSize; i++)

{

Coord[i] = a.Coord[i];

}

return *this;

}

void Vector::Write() const

{

cout<<"This is vector:"<<endl;

for (int i = 0; i < nSize; i++)

{

cout<<Coord[i]<<endl;

};

}

double F (Vector t)

{

double result = 0;

if (t.size() == 2)

result = t[0]*t[0]+3*t[1]*t[1]+2*t[0]*t[1];

if (t.size() == 3)

result = (t[0]-1)*(t[0]-1) + (t[1]-3)*(t[1]-3) + 4*(t[2]+5)*(t[2]+5);

if (t.size() == 4)

result = 100*pow(t[1]-t[0]*t[0], 2) + (1-t[0])*(1-t[0]) + 90*pow(t[3]-t[2]*t[2], 2) + pow(1-t[2], 3) + 10.1*(t[1]-1)*(t[1]-1) + (t[3]-1)*(t[3]-1) + (t[1]-1)*(t[3]-1);

return result;

}

double Diff(Vector x, int i)

{

int t = x.size();

double w = 0;

double h = 0.000001;

Vector q(t);

if (t >= i)

w = ( F(x + q.Scal(q.Ort(t, i), h)) - F(x - q.Scal(q.Ort(t, i), h)) )/(2*h);

return w;

}

Vector Vector::Grad(const Vector& x)

{

int i = x.size();

Vector w(i);

for (int j = 1; j<=i; j++)

{

w[j-1] = Diff(x, j);

}

return w;

}

void Vector::Swenn(const Vector& x, Vector& p, double& ala, double& alb)

{

int r = x.size();

Vector G(r);

G = G.Grad(x); // Проверка направления на убывание функции

if ((G * p) > 0)

{

p*=-1;

}

double f1, f2, al = 0.000001;

Vector x1(r);

Vector x2(r);

x1 = x;

f1 = G * p;

do

{

al = al*2;

G = G.Scal(p, al);

x2 = x1 + G;

G = G.Grad(x2);

f2 = G * p;

}

while (f1*f2 > 0);

if((G * p) > 0)

{

alb = al;

ala = al/2;

}

else

{

alb = al/2;

ala = al;

}

}

double Vector::ZS1(Vector& x, Vector p, double al1, double al2, double E, int & it)

{

double l, m, f1, f2, help1, help2;

int j=0;

l = al1 + 0.38196601125*fabs(al1-al2);

m = al1 + 0.61803398875*fabs(al1-al2);

int r = x.size();

Vector G(r);

Vector x1(r);

Vector x2(r);

while ( (fabs(al1-al2) >= E) || (fabs(f1-f2) >= E) )

{

it++;

j = j + 1;

x1 = x + G.Scal(p, l);

f1 = F(x1);

x2 = x + G.Scal(p, m);

f2 = F(x2);

if (f1 < f2)

{

al2 = m;

m = l;

l = al1 + 0.38196601125*fabs(al1-al2);

}

if (f1 >= f2)

{

al1 = l;

l = m;

m = al1 + 0.61803398875*fabs(al1-al2);

}

}

return (al1+al2)/2;

}

Vector Vector::Ort(int n, int Num)

{

Vector W(n);

int i=0;

while (i<n)

{

W[i] = 0;

i++;

}

W[Num-1] = 1;

return W;

}

double Vector::Norma(Vector x)

{

int i = x.size();

double d=0;

for (int j = 0; j < i; j++)

d = d + x[j]*x[j];

return sqrt(d);

}

double Vector::Powell(Vector& x, Vector p, double al1, double al2, double E, int & it)

{

double a, b, c, d, help1, help2;

int r = x.size();

Vector xa(r);

Vector xb(r);

Vector xc(r);

Vector xd(r);

a = al1;

b = (al1+al2)/2;

c = al2;

xa = x + xa.Scal(p, a);

xb = x + xb.Scal(p, b);

xc = x + xc.Scal(p, c);

help1 = ( F(xa)*(b*b-c*c) + F(xb)*(c*c-a*a) + F(xc)*(a*a-b*b) );

help2 = (F(xa)*(b-c) + F(xb)*(c-a) + F(xc)*(a-b));

if (help2 == 0)

help2 = 0.0000001;

d = 0.5*help1/help2;

xd = x + xd.Scal(p, d);

while ((fabs((d-b)/b) >= E) || (fabs(F(xd)-F(xb))/F(xb) >= E ))

{

it++;

if( F(xb) > F(xd) )

{

if(b > d)

{

c = b;

}

else

{

a = b;

}

b = d;

}

else

{

if(b > d)

{

a = d;

}

else

{

b = d;

}

}

xa = x + xa.Scal(p, a);

xb = x + xb.Scal(p, b);

xc = x + xc.Scal(p, c);

help1 = (F(xa)-F(xb))*(b-c)*(c-a);

help2 = (F(xa)*(b-c) + F(xb)*(c-a) + F(xc)*(a-b));

if (help2 == 0)

break; // Delenie na nol'

d = (a+b)/2 + 0.5*(help1/help2);

xd = x + xd.Scal(p, d);

}

return (b + d)/2;

}

Vector Vector::GZ_3(Vector& x, double E, int maxiter, int& iter, int& boo, int method, int razmer)

{

int r = x.size();

Vector p(r);

Vector G(r);

Vector t(r);

double w, al, a, b, k;

int y=0;

t = x;

boo = 0;

int it = 0;

while ( ( Norma(G.Grad(t)) >= E ) && ( y < maxiter ) )

{

k = Norma(G.Grad(t));

for (int i = 1; i<=r; i++)

{

w = Diff(t, i);

p = p.Scal(Ort(r,i), w);

G.Swenn(t, p, a, b);

if (method == 1)

al = G.ZS1(t, p, a, b, E, it); //alpha i-oe

if (method == 2)

al = G.Powell(t, p, a, b, E, it); //alpha i-oe

t = t + G.Scal(p, al);

}

y++;

}

if (Norma(G.Grad(t)) < E)

boo = 1;

iter = y;

return t;

}

Vector Vector::function(Vector& x, double E, int method,int & it)

{

int r = x.size();

Vector p(r); //napravlenie

Vector G(r); //vspomogatel'naya

Vector t(r); //dubliruet 'x'

double al, a, b, k;

int y=0;

t = x;

p[0]=2; p[1]=3;

G.Swenn(t, p, a, b);

if (method == 1)

al = G.ZS1(t, p, a, b, E, it); //alpha i-oe

if (method == 2)

al = G.Powell(t, p, a, b, E, it); //alpha i-oe

t = t + G.Scal(p, al);

return t;

}

void main()

{

double E;

int it=0, maxit, tochnost;

int choice, method, countiter=0;

char answer,razmer, next;

cout<<"Dannaia programma ispolzuet metod Gaussa Zeidelia"<<endl;

cout<<"dlya nahojdenia minimuma funktsii."<<endl;

cout<<"Predusmotren vibor metoda promejutochnih raschetov (ZS-1, Powell)"<<endl;

cout<<endl;

cout<<"Viberite functsiu:"<<endl;

cout<<"1. f(x1,x2) = x1^2+3*x2^2+2*x0*x1;"<<endl;

cout<<"2. f(x1,x2,x3) = (x1-1)(x1-1) + (x2-3)(x2-3) + 4(x3+5)(x3+5)"<<endl;

cout<<"3. f(x1,x2,x3,x4) = 100(x2-x1x1)^2 + (1-x1)^2 + 90(x4-x3x3)^2 + (1-x3)^3 + "<<endl;

cout<<" + 10.1(x2-1)^2 + (x4-1)^2 + 19.8(x2-1)(x4-1)"<<endl;

cin>>choice;

razmer = choice + 1;

Vector x(razmer);

for (int i = 0; i < razmer; i++)

x[i] = 0;

cout<<"Po umolchaniu nachalnaia tochka imeet koordinati x[i]=0. Izmenit'? (y/n)"<<endl;

answer = getch();

if (answer == 'y')

for (int i = 0; i < razmer; i++)

{

cout<<"Zadaite "<<i+1<<" koordinatu: ";

cin>>x[i];

}

Vector Q3(razmer);

int current = 0;

do

{

cout<<endl;

cout<<"Viberite metod rascheta:"<<endl;

cout<<"1. Metod Zolotogo Sechenia-1;"<<endl;

cout<<"2. Metod Powella"<<endl;

cin>>method;

cout<<"Vvedite max kol-vo iteratsii: ";

cin>> maxit;

cout<<"Vvedite pogreshnost' (E = 0.00001 - 0.0000000001) : ";

cin>>E;

cout<<endl;

if (current > 0)

{

x = Q3;

cout<<"Izmenit nachalnuiu tochku? (y/n)"<<endl;

answer = getch();

if (answer == 'y')

for (int i = 0; i < razmer; i++)

{

cout<<"Zadaite "<<i+1<<" koordinatu: ";

cin>>x[i];

}

};

if(razmer==2)

{Q3 = Q3.function(x, E, method, it);}

else

{

Q3 = Q3.GZ_3(x, E, maxit, it, tochnost, method, razmer);

}

cout<<"Kolichestvo iteratsii: "<<it;

if (tochnost == 1)

{

cout<<"tochnost dostignuta... "<<endl;

}

else

{

cout<<"tochnost ne dostignuta "<<endl;

}

Q3.Write();

cout<<"Prodoljit rascheti? (y/n)"<<endl;

next = getch();

current++;

}

while (next != 'n');

}

Соседние файлы в папке р 1-5, 2 вар.; 7 лаб. метод Полака Рибьера + Лекции МО + перевод ГА