⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nolinear1.cpp

📁 运筹学中的解非线性规划问题的一种方法,zoutendijk可行方向法
💻 CPP
字号:
// nolinear1.cpp : Defines the entry point for the console application.
//

//#include "stdafx.h"
#include <math.h>
#include "stdio.h"
#include "lineSearch_sm.cpp"

//#include "define.h"

#define LIMIT_GENERATION 100
#define EPSLON 0.00000001



extern void sm();
extern double sm_min;
extern double sm_x[NUM_variable];


void zou_init();
void zou_getRestriction();
//double vector_Multiply(double *a,double *x,int dim);

//static double A[NUM_restriction][NUM_variable]={1.0,1.0,1.0,5.0,-1.0,0.0,0.0,-1.0};
//static double B[NUM_restriction] = {2.0,5.0,0.0,0.0};
//static double current_result[LIMIT_GENERATION] ;//当前解
static bool isStrict[NUM_restriction];//if the restriction is strict
static double A1[NUM_restriction][NUM_variable];//A1: matrix of sm
static double A2[NUM_restriction][NUM_variable];//A2: to decide lamata_max
static double B1[NUM_restriction];//B1: b of sm
static double B2[NUM_restriction];//B2: to decide lamata_max
static int dim_B1;//dimension of B1 :紧约束的个数
static int dim_B2;//dimension of B2 :非紧约束的个数
static double grads[NUM_variable];//梯度
/*=================================================================*/

double f(double g, double h)
{
return (2.0*g*g +2.0*h*h -2.0*g*h -4.0*g -6.0*h);
}


double fx(double g, double h)
{
return (2.0*g - 2.0*h - 4);
}

double fy(double g, double h)
{
	return (-2.0*g + 2.0*h - 6);
}

//double fz(double g, double h,double i)


/*

*/ 
double lineSearch(double XK[2],double dk[2],double max)
{
double x[100];
//double y[100];
//double z[100];

int i=0;

double p;//=0.01;//步长
if(max<0.0)
	p = 0.01;
else if (max >1.0)
    p = 0.01;
else
    p = max * 0.001;


//初始值
x[0] = 0;
//y[0] = 0;
//z[0] = z0;

for(i=0;i<99;i++)//迭代100次
{
	//x[i + 1] = x[i] - p * fx(x[i], y[i]);
	//y[i + 1] = y[i] - p * fy(x[i], y[i]);
	//z[i + 1] = z[i] - p * fz(x[i], y[i],z[i]);
	x[i+1] = x[i] - p * ( fx(XK[0]+x[i]*dk[0],XK[1]+x[i]*dk[1])*dk[0]+ fy(XK[0]+x[i]*dk[0],XK[1]+x[i]*dk[1])*dk[1]);
	
	
	if(max >0.0)
	{
		if(x[i+1] > max)
		{
			if(f(XK[0]+x[i]*dk[0],XK[1]+x[i]*dk[1]) < f(XK[0]+max*dk[0],XK[1]+max*dk[1]))
				x[99] = x[i];
			else
				x[99] = max;
			break;
		}
	}
	
}


//printf("%f,%f,%f",x[99],y[99],f(x[99],y[99]));
printf("lamata:%f,min(f(XK+lamata*dk)):%f",x[99],f(XK[0]+x[99]*dk[0],XK[1]+x[99]*dk[1]));
return f(XK[0]+x[99]*dk[0],XK[1]+x[99]*dk[1]);
}

/*=================================================================*/
int main()
{
	int i,step;
	bool flag = true;
	double b_[NUM_variable] ,d_[NUM_variable],lamata_max;//用于求线搜索的步长限制
	double lamata_k;//步长
	zou_init();
	for(step=0;step<LIMIT_GENERATION;step++)
	{
		/*已知xk A B 求grads A1 A2 B1 B2 isStrict dim_B1 dim_B2*/
		zou_getRestriction();
		/*调用sm求线性规划问题,得到可行改进方向dk*/
		sm(NUM_variable,dim_B1+1,B1,A1,xk);//得到结果sm_min ,sm_x[](相当于dk)
		/*判断是否结束*/
		if(vector_Multiply(grads,sm_x,NUM_variable) < EPSLON)
		{
			//打印结果xk fun(xk),结束
			printf("\n最优解:(");
			for(i = 0 ; i<NUM_variable ; i++)
			{
				printf(" %f ",sm_x[i]);
			}
			printf(")");
			printf("\n最优值:%f \n",sm_min);
			return 1;
		}
		/*求线搜索问题的步长限制lamata_max*/
		for(i=0;i<dim_B2;i++)
		{
			b_[i] = B2[i] - vector_Multiply(A2[i], xk,NUM_variable);
			d_[i] = vector_Multiply(A2[i], sm_x,NUM_variable);
			if (d_[i] >0.0)
				flag = false;
		}
		if(flag)
			lamata_max = -1.0;//此时lamata_max无界,用一个负数表示
		else
		{
			lamata_max = b_[0]/d_[0];
			for(i=1;i<dim_B2;i++)
			{
				if(lamata_max > b_[i]/d_[i])
					lamata_max = b_[i]/d_[i];
			}
		}

		/*线搜索求步长lamata*/
		lamata_k = lineSearch(xk, sm_x, lamata_max);		
		/*根据方向dk和步长lamata_k得到下一个可行解xk*/
		for(i = 0 ; i<NUM_variable ; i++)
		{
			xk[i] = xk[i]+lamata_k * sm_x[i];
		}		
	}

	return 0;
}

void zou_init()//赋值:x0  A ,B, f
{
	int i;

	for( i=0 ; i<NUM_variable ; i++)
	{
      xk[i] = x0[i];	
	}
}

void zou_getRestriction()//已知xk A B 求grads A1 A2 B1 B2 isStrict dim_B1 dim_B2
{
	int i,j;
	
	fun_grads(xk,grads);//求出grads,即 需要输入到sm中的目标函数

	dim_B1 =0;
	dim_B2 =0;
	for(i=0 ; i<NUM_restriction ; i++)
	{	
		if(vector_Multiply(A[i],xk,NUM_variable)==B[i])
		{
			isStrict[i] = true;
			for(j=0;j<NUM_variable;j++)
			{
				A1[dim_B1][j] = A[i][j];
			}
			B1[dim_B1] = B[i];
			dim_B1 ++;
		}
		else
		{
			isStrict[i] = false;
			for(j=0;j<NUM_variable;j++)
			{
				A2[dim_B2][j] = A[i][j];
			}			
			B2[dim_B2] = B[i];
			dim_B2 ++;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -