Скачиваний:
4
Добавлен:
01.05.2014
Размер:
8.24 Кб
Скачать
#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);

 
}
Соседние файлы в папке Лабораторная работа №9
  • #
    01.05.20143.38 Кб4itog.dsp
  • #
    01.05.2014533 б4itog.dsw
  • #
    01.05.201441.98 Кб4itog.ncb
  • #
    01.05.201448.64 Кб4itog.opt
  • #
    01.05.20141.34 Кб4itog.plg
  • #
    01.05.20148.24 Кб4itog1.cpp
  • #
    01.05.20143.39 Кб4itog1.dsp
  • #
    01.05.2014535 б4itog1.dsw
  • #
    01.05.201433.79 Кб4itog1.ncb
  • #
    01.05.201448.64 Кб4itog1.opt
  • #
    01.05.20141.35 Кб4itog1.plg