Скачиваний:
6
Добавлен:
01.05.2014
Размер:
105.47 Кб
Скачать

Текст программы с комментариями

#include "stdafx.h"

#include <windows.h>

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <cmath>

#include<iostream>

#include "math.h"

#define min(a,b) (((a)>(b))?(b):(a))

#define max(a,b) (((a)<(b))?(b):(a))

double error=-9999;

unsigned int vusov=0;

#define adr unsigned long

#define right(p) (((adr )p!=NULL))

// структура для вектора

class vect {

public:

unsigned short n; //длина вектора

double * x;

vect() {n=0; x=0;} //конструктор по умолчанию

vect(unsigned short dlin) {n=dlin;if(n!=0) x=new double [n];else x=0;} //создание вектора длины n без инициализации

vect (vect &a) //конструктор копирования

{

n=a.n;

if(n)

{

x=new double [n];

memcpy(x,a.x,n*sizeof(double));

}

else x=0;

}

vect operator = (vect &a)

{

n=a.n;

if(n) x=new double [n]; else x=0;

if(n) memcpy(x,a.x,n*sizeof(double));

return *this;

}

vect mult(double c) //метод класса, для умножения вектора на число

{

vect itog(n) ;

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

{

itog.x[i]=x[i]*c;

}

return itog;

}

vect sum(vect a) //метод класса, для подсчета суммы векторов

{

if(a.n!=n)

{

printf("Error in sum");

return vect(0);

}

vect itog(n) ;

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

{

itog.x[i]=x[i]+a.x[i];

}

return itog;

}

vect razn(vect a) //метод класса, для подсчета разности векторов

{

if(a.n!=n)

{

printf("Dif vectors with diff. dimensions");

return vect(0);

}

vect itog(n) ;

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

{

itog.x[i]=x[i]-a.x[i];

}

return itog;

}

double pr_ch(vect b)// метод для перемножения векторов

{

if(n!=b.n)

{

printf("Dif vectors with diff. dimensions");

return 0;

}

double itog=0;

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

{

itog=itog+x[i]*b.x[i];

}

return itog;

}

double norm()//подсчет нормы вектора

{

double res=0;

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

res+=x[i]*x[i];

res=sqrt(res);

return res;

}

};

class matr

{

public:

unsigned short n;

double * x;

matr(unsigned short dlin=0) {n=dlin; if(n) x=new double[n*n];else x=0;}

matr (matr &a) // метод для копирования матриц

{

n=a.n;

if(n) x=new double [n*n]; else x=0;

if(n) memcpy(x,a.x,n*n*sizeof(double));

}

matr operator = (matr &a)// метод для копирования матриц

{

n=a.n;

if(n) x=new double [n*n]; else x=0;

if(n) memcpy(x,a.x,n*n*sizeof(double));

return *this;

}

double & e(unsigned short i,unsigned short j )// метод для определения элемента матрицы

{

if(i>n || j>n )

{printf("Error in e"); return error; }

return x[i*n+j];

}

~matr() {if(right(x)) delete [] x;n=0;x=0;}

matr multm(matr &a, matr &res)// метод для перемножения матриц

{

if(a.n!=n){printf("Error - Mult matrix - different dimensions"); return matr(0);}

memset(res.x,0,n*n*sizeof(double));

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

{

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

{

for(int k=0; k<n; k++)

res.e(i,j)+=e(i,k)*a.e(k,j);

}

}

return res;

}

matr sum(matr a, matr b)// метод для сложения матриц

{

if(a.n!=b.n)

{

printf("Error - Sum matrix - different dimensions");

return matr(0);

}

matr itog(n);

for(int i=0;i<n*n;i++)

{

itog.x[i]=a.x[i]+b.x[i];

printf("i=%d x[i]=%f",i,x[i]);

}

return itog;

}

matr mult(double c)// метод для перемножения матрицы на число

{

int ind=0;

matr itog(n);

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

{

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

{

itog.x[ind]=x[ind]*c;

ind++;

}

}

return itog;

}

vect mult(vect &a)// метод для перемножения матрицы на столбец

{

if(a.n!=n){printf("Error in mult matrix"); return vect(0);}

vect res(n);

memset(res.x,0,sizeof(double)*n);

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

{

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

{

res.x[i]+=e(i,j)*a.x[j];

}

}

return res;

}

matr pr_m(vect a,vect b)// метод для перемножения векторов

{

if(a.n!=b.n)

{

printf("Dif vectors with diff. dimensions");

return matr(0);

}

matr itog(a.n);

int ind=0;

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

{

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

{

itog.x[ind]=a.x[i]*b.x[j];

ind++;

}

}

return itog;

}

};

int z=0;//выбор функции

int dlin;//число переменных

double y(vect &v)//заданные функции

{

vusov++;

if(z==1)return v.x[0]*v.x[0]*v.x[0]+v.x[1]*v.x[1]-3*v.x[0]-2*v.x[1]+2;

if(z==2)return (v.x[1]-v.x[0]*v.x[0])*(v.x[1]-v.x[0]*v.x[0])+(1-v.x[0])*(1-v.x[0]);

}

//функция для прехода в новую точку вдоль линии

double next(double a, vect &x0, vect &p)

{

return y(x0.sum(p.mult(a)));//y(x+p*a)

}

//функция для расчёта производной

double dy(double a, vect &x0, vect & p)

{

double e=0.000000000001;

return (next(a+e/2,x0,p)-next(a-e/2,x0,p))/e;

}

//функция для расчёта градиента

inline vect grad(vect & point)

{

double e=0.000000000001;

vect res(point.n);

vect temp(point.n);

for(int i=0; i<point.n;i++)

{

memcpy(temp.x,point.x,point.n*sizeof(double));

temp.x[i]+=e;

res.x[i]=(y(temp)-y(point))/e;

}

return res;

}

// метод Свенна 4

void Swann4(double a0,vect &x0, vect & p, double &x1, double &x2)

{

double x=0,y1,y2;

if(dy(a0,x0,p)>0) a0=-a0;

y1=dy(a0,x0,p);

do

{

a0*=2;

y2=dy(a0,x0,p);

}while(y1*y2>0);

x1=min(a0,a0/2);

x2=max(a0,a0/2);

/*printf("\n x1= %f",x1);

printf("\n x2= %f",x2);*/

}

// метод Дэвидона

vect Davidon(vect &x0, vect & p, double *al)

{

vect res(x0.n);

double e=0.0000001;

double a,b;

Swann4(0.00000001, x0, p,a,b);

double x1=0,x12=0, z=0, w=0,delta=0;

do{

z =dy(a,x0,p)+dy(b,x0,p)+3*(next(a,x0,p)-next(b,x0,p))/(b-a);

w =sqrt(z*z-dy(a,x0,p)*dy(b,x0,p));

delta =(z-dy(a,x0,p)+w)/(dy(b,x0,p)-dy(a,x0,p)+2*w);

x12=x1;

x1=a+delta*(b-a);

if(dy(x1,x0,p)>0)

b=x1;

else

a=x1;

}while(fabs(dy(x1,x0,p))>e);

*al=x1;

res=x0.sum(p.mult(x1));

return res;

}

//шаг метода Коши

vect step(vect &x0)

{

double al;

vect p=grad(x0);

p=p.mult(-1);

vect x=Davidon(x0,p, &al);

return x;

}

void Paul1(vect &x0)

{

int i,j, iter=0,blin=1;

double e=0.0001,al,kop,znam,b,m[10][10],kop1;

vect x2(x0.n),x1(x0.n),d(x0.n),p(x0.n),xn(x0.n);

x1=x0;

do

{

x2=x1;

if(iter==0)

{

for (i=0;i<x0.n;i++)

{

for(j=0;j<x0.n;j++)

{

if(i==j)

m[i][j]=1;

else

m[i][j]=0;

}

}

}

else

{

for (i=0;i<x0.n;i++)

{

if(i==((x0.n)-1))

{

for(j=0;j<x0.n;j++)

m[i][j]=d.x[j];

}

else

{

for(j=0;j<x0.n;j++)

m[i][j]=m[i+1][j];

}

}

}

for(i=0;i<x0.n;i++)

{

for(j=0;j<x0.n;j++)

p.x[j]=m[i][j];

x2=Davidon(x2,p, &al);

kop1=grad(x2).norm();

if(kop1<=e)

{

i=x0.n+5;

blin=0;

}

}

printf("\nx2=[%f,%f] ",x2.x[0],x2.x[1]);

getch();

if(i<(x0.n+3))

{

d=x2.razn(x1);

xn=Davidon(x2,d, &al);

kop=grad(xn).norm();

x1=xn;

}

iter++;

}while((kop>e)&&blin);

printf("\n\n\nITER=%d, ",iter);

if(blin)

x0=xn;

else

x0=x2;

}

void main(void)

{

vect x1;

do

{

system("cls");

printf("\nFunction minimum search \n\n\n\n");

printf("\nMenu:\n\n\n");

printf(" 1. x1^3 + x2^2 - 3x1 - 2x2 + 2 Min: (1,1)\n\n");

printf(" 2.(x2 - x1^2)^2 + (1 - x1)^2 Min : (1,1)\n\n");

printf(" 3.Exit\n\n");

printf("Please select punkt menu(from 1 to 3): ");

scanf( "%d",&z );

if(z<0||z>3)

{

printf("\n Please from 1 to 3 ");

getch();

}

switch(z)

{

case 1:{

dlin=2;

vusov=0;

vect x0(dlin);

x0.x[0]=1.5;

x0.x[1]=2;

Paul1(x0);

printf("Min:");

for(int i=0;i<x0.n;i++)

printf("%f, ",x0.x[i]);

getch();

getch();

break;

}

case 2:{dlin=2;

vusov=0;

vect x0(dlin);

x0.x[0]=-1;

x0.x[1]=-1;

Paul1(x0);

printf("Min:");

for(int i=0;i<x0.n;i++)

printf("%f, ",x0.x[i]);

getch();

getch();

break;

}

}

}while(z!=3);

}

18

Соседние файлы в папке Лабораторная работа №9