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

📄 test.cpp

📁 3种关于非线性优化的办法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//www.pudn.com > 最优化作业C++源代码.rar > 单纯形法.cpp


/*#include<iostream.h> 
#include<math.h> 
int const n=2; 

  double fun(double x[n]); 
  void compare(double x[n+1][n],double LGH[3][n],double LGH_tap[3]);//在调用之前LGH先给x[n+1]赋值 
  double H(double x[n+1][n],double LGH[3][n],double c);//判别准则 
  void zx(double x[n+1][n],double LGH[3][n],double LGH_tap[3],double xn_1[n],double xn_2[n]); 
  
	void main() 
	{ 
	double x[n+1][n]={0}; 
	double c=0.1; 
	double a=1.1; 
	double b=0.5; 
	double LGH[3][n]={0}; 
	double LGH_tap[3]={0}; 
	double xn_1[n]={0}; 
	double xn_2[n]={0}; 
	double xn_3[n]={0}; 
	double xn_4[n]={0}; 
	int i,j,tap=0; 
	
	  //给出一个初始点X0,X!,X2 
	  x[0][0]=0;x[0][1]=0; 
	  x[1][0]=0.965;x[1][1]=0.259; 
	  x[2][0]=0.259;x[2][1]=0.965; 
	  cout<<"初始点:"<<endl; 
	  for(i=0;i<n+1;i++) 
	  { 
	  cout<<"x["<<i<<"]=("; 
	  for(j=0;j<n;j++) 
	  { 
	  cout<<x[i][j]; 
	  if(j!=n-1) 
	  cout<<","; 
	  } 
	  cout<<")"<<endl; 
	  } 
	  compare(x,LGH,LGH_tap);//返回Xl,Xh,Xg及它们在x[n+1][n]中的下标 
	  zx(x,LGH,LGH_tap,xn_1,xn_2);//返回中心X(n+1)和反射点X(n+2) 
	  while(H(x,LGH,c)==0) 
	  { 
	  if(fun(xn_2)<fun(LGH[0]))//if(fun(xn_2)<fun(LGH[0][n]))//////////////////////////////////////////////////?关于传值疑问 
	  { 
	  for(i=0;i<n;i++) 
	  { 
	  xn_3[i]=xn_1[i]+a*(xn_2[i]-xn_1[i]);//扩张 
	  } 
	  if(fun(xn_3)<fun(LGH[0])) 
	  { 
	  for(i=0;i<n;i++) 
	  { 
	  x[int(LGH_tap[2])][i]=LGH[2][i]=xn_3[i]; 
	  } 
	  //goto step 2; 
	  } 
	  else 
	  { 
	  for(i=0;i<n;i++) 
	  { 
	  x[int(LGH_tap[2])][i]=LGH[2][i]=xn_2[i]; 
	  } 
	  //goto step 2; 
	  } 
	  } 
	  else 
	  { 
	  if(fun(xn_2)<fun(LGH[1])) 
	  { 
	  for(i=0;i<n;i++) 
	  { 
	  xn_4[i]=xn_1[i]+b*(xn_2[i]-xn_1[i]);//压缩 
	  } 
	  //goto step 2; 
	  } 
	  else 
	  { 
	  for(i=0;i<n;i++) 
	  { 
	  xn_4[i]=xn_1[i]-b*(xn_2[i]-xn_1[i]);//压缩 
	  } 
	  } 
	  if(fun(xn_4)<fun(LGH[2])) 
	  { 
	  for(i=0;i<n;i++) 
	  { 
	  x[int(LGH_tap[2])][i]=LGH[2][i]=xn_4[i]; 
	  } 
	  } 
	  else//缩边 
	  { 
	  cout<<"进行缩边。"<<endl; 
	  for(i=0;i<n+1;i++) 
	  { 
	  if(i==LGH_tap[0]) 
						continue; 
						for(j=0;j<n;j++) 
						{ 
						x[i][j]=(LGH[0][j]+x[i][j])/2; 
						} 
						} 
						} 
						} 
						compare(x,LGH,LGH_tap);//返回Xl,Xh,Xg及它们在x[n+1][n]中的下标 
						zx(x,LGH,LGH_tap,xn_1,xn_2);//返回中心X(n+1)和反射点X(n+2) 
						tap++; 
						} 
						cout<<"单纯形法求解minf(x)=X1^2+2X2^2-4X1-8X2+5;"<<endl; 
						cout<<"XL="<<endl; 
						for(i=0;i<n;i++) 
						{ 
						cout<<LGH[0][i]<<endl; 
						} 
						cout<<"fun="<<fun(LGH[0])<<endl; 
						cout<<"迭代次数:"<<tap<<endl; 
						} 
						double fun(double x[n])//求函数值 
						{ 
						double y; 
						y=pow(x[0],2)+2*pow(x[1],2)-4*x[0]-8*x[1]+5; 
						//cout<<"y="<<y<<endl; 
						return y; 
						} 
						void compare(double x[n+1][n],double LGH[3][n],double LGH_tap[3])//在调用之前LGH先给x[n+1]赋值 
						{ 
						int i; 
						double y[n+1]; 
						for(i=0;i<n+1;i++) 
						y[i]=fun(x[i]);//y[i]=fun(x[i][n]);//////////////////////////////////////////////////?关于传值疑问 
						
						  double temp[2]; 
						  temp[0]=y[0]; 
						  for(i=0;i<n+1;i++)//temp[0]存储最小的值XL,temp[1]存储对应x的下标 
						  { 
						  if(y[i]<=temp[0]) 
						  { 
						  temp[0]=y[i]; 
						  temp[1]=i; 
						  } 
						  } 
						  LGH_tap[0]=temp[1];//记录标记 
						  for(i=0;i<n;i++) 
						  LGH[0][i]=x[int(temp[1])][i]; 
						  
							for(i=0;i<n+1;i++)//temp[0]存储最大的值XH,temp[1]存储对应x的下标 
							{ 
							if(y[i]>=temp[0]) 
							{ 
							temp[0]=y[i]; 
							temp[1]=i; 
							} 
							} 
							LGH_tap[2]=temp[1];// 
							for(i=0;i<n;i++) 
							LGH[2][i]=x[int(temp[1])][i]; 
							
							  temp[0]=y[0]; 
							  if(LGH_tap[2]==0) 
							  { 
							  temp[0]=y[1]; 
							  } 
							  for(i=0;i<n+1;i++)//寻找次大值 
							  { 
							  
								if(i==LGH_tap[2])//if(i==temp[1]) 
								continue; 
								if(y[i]>=temp[0]) 
								{ 
								temp[0]=y[i]; 
								temp[1]=i; 
								} 
								} 
								LGH_tap[1]=temp[1]; 
								for(i=0;i<n;i++) 
								LGH[1][i]=x[int(temp[1])][i]; 
								} 
								void zx(double x[n+1][n],double LGH[3][n],double LGH_tap[3],double xn_1[n],double xn_2[n]) 
								{ 
								int i,j; 
								for(i=0;i<n;i++) 
								xn_1[i]=xn_2[i]=0; 
								
								  for(i=0;i<n+1;i++)//返回重心 
								  { 
								  if(i==LGH_tap[2])//轮流加n次(去掉一次) 
								  continue; 
								  for(j=0;j<n;j++) 
								  { 
								  xn_1[j]+=x[i][j]; 
								  } 
								  } 
								  for(i=0;i<n;i++) 
								  xn_1[i]/=n; 
								  for(i=0;i<n;i++)//返回反射点 
								  xn_2[i]=2*xn_1[i]-LGH[2][i]; 
								  } 
								  double H(double x[n+1][n],double LGH[3][n],double c)//判别准则 
								  { 
								  int i; 
								  double s=0; 
								  for(i=0;i<n+1;i++)//小心i从0到n即(i=0;i<n+1;i++) 
								  { 
								  s+=pow(fun(x[i])-fun(LGH[0]),2);//s+=pow(fun(x[i][n])-fun(LGH[0][n]),2);//////////////////////////////////////////////////?关于传值疑问 
								  } 
								  if(s<=c) 
								  return 1; 
								  else 
								  return 0; 
								  }
*/

//Part II
//www.pudn.com > 最优化作业C++源代码.rar > DFP法.CPP

// 
// #include<iostream.h> 
// #include<math.h> 
// #include<iomanip.h> 
// int const n=2;//正定二次函数的自变量个数 
// double fun(double x[n],double f_xs[n+n+1+(n-1)*n/2]);//输入变量为函数自变量初值 
// void Q_fun(double f_xs[n+n+1+(n-1)*n/2],double Q[n][n+1]);//Q[n][n]是二次函数的正定矩阵,但Q的第n+1列存储一次项的系数 
// void D_fun(double x[n],double Q[n][n+1],double g0[n]);//自变量初值,正定二次函数的各项系数,返回梯度的初值 
// int H(double g0[n],double c);//判别准则:返回1结束,返回0继续迭代 
// void abc(double x[n],double p[n],double f_xs[n+n+1+(n-1)*n/2],double t[3]);//t[3]中返回的是a,b,c的系数值.开始计算minf(Xk+tPk)时的步长t的值,由于这是n元二次函数所以minf(t)是关于t>0的二次函数,先求二次方程a,b,c系数,用一阶导为零。 
// double t_c(double t[3]);//二次函数一阶导为零计算t的值,t>0 
// 
// void main() 
// { 
// 	double f_xs[n+n+1+(n-1)*n/2]={4,1,-40,-12,136,0};//正定二次函数的各项系数,第一个为:X1^2系数,第二个为:X2^2系数,第三个为:X1系数,第四个为:X2系数,第五个为:常数项,第六个为:X1X2系数; 
// 	//n元的系数存放类推 
// 	double x[n]={8,9};//函数自变量初值 
// 	double f0;//函数值 
// 	double g0[n];//梯度的值 
// 	double Q[n][n+1];//求梯度处值设置的中间变量,包含两部分:正定二次函数对应的实对称矩阵,还有一次项系数 
// 	double c=0.01;//H准则限值 
// 	double t[3];//返回求minf()时t的二次函数的a,b,c的系数值 
// 	double t_bc;//步长 
// 	double p[n];//保存下降方向 
// 	double H0[n][n];//保存模拟Hesse矩阵的逆 
// 	double y[n];//y(k)=g0(k+1)-g0(k) 
// 	double s[n];//s(k)=X(k+1)-X(k) 
// 	double s_temp[n][n]={0};//计算保存矩阵 
// 	double s_temp2[n][n]={0}; 
// 	double s_temp3[n][n]={0}; 
// 	double s_tl[n]={0}; 
// 	double temp;//临时值 
// 	int i,j,k,flag=0,tap=0;//迭代次数 
// 	
// 	Q_fun(f_xs,Q);//计算正定二次函数对应的实对称矩阵 
// 	f0=fun(x,f_xs);//求函数初值 
// 	D_fun(x,Q,g0);//返回梯度的初值 
// 	
// 	do 
// 	{ 
// 		for(i=0;i<n;i++)//给H0[n][n]的处值赋单位矩阵 
// 		{ 
// 			for(j=0;j<n;j++) 
// 			{ 
// 				if(i==j) 
// 					H0[i][j]=1; 
// 				else 
// 					H0[i][j]=0; 
// 			} 
// 		} 
// 		for(i=0;i<n;i++) 
// 			p[i]=(-1)*g0[i]; 
// 		k=0;//step 2; 
// 		
// 		do 
// 		{ 
// 			abc(x,p,f_xs,t);//开始计算minf(Xk+tPk)时的步长t的值, 
// 			t_bc=t_c(t);//求一阶导来计算t 
// 			
// 			for(i=0;i<n;i++) 
// 			{ 
// 				x[i]=x[i]+t_bc*p[i]; 
// 				s[i]=t_bc*p[i];//保存计算之值X(k+1)-X(k) 
// 			} 
// 			for(i=0;i<n;i++) 
// 				y[i]=g0[i];//保存之类的 
// 			
// 			f0=fun(x,f_xs); 
// 			D_fun(x,Q,g0);//step 3; 
// 			
// 			for(i=0;i<n;i++) 
// 				y[i]=g0[i]-y[i];//保存计算g0(k+1)-g0(k) 
// 			
// 			if(H(g0,c)==0)//即不满足小于c 
// 			{ 
// 				if(k!=n) 
// 				{ 
// 					//y 
// 					//s have done! 
// 					temp=0;//初值 
// 					for(i=0;i<n;i++) 
// 						temp+=s[i]*y[i]; 
// 					for(i=0;i<n;i++) 
// 					{ 
// 						for(j=0;j<n;j++) 
// 						{ 
// 							s_temp[i][j]=s[i]*s[j]/temp; 
// 						} 
// 					}//求出S(k)S(k)t/S(k)tyk 
// 					
// 					for(i=0;i<n;i++)//初值 
// 						s_tl[i]=0; 
// 					
// 					for(i=0;i<n;i++) 
// 					{ 
// 						for(j=0;j<n;j++) 
// 						{ 
// 							s_tl[i]+=y[j]*H0[j][i]; 
// 						} 
// 					} 
// 					temp=0;//初值 
// 					for(i=0;i<n;i++) 
// 					{ 
// 						temp+=s_tl[i]*y[i]; 
// 					}//这时s_tl[n]和s_temp2[n][n]可以利用 
// 					
// 					for(i=0;i<n;i++)//初值 
// 						s_tl[i]=0; 
// 					
// 					for(i=0;i<n;i++) 
// 					{ 
// 						for(j=0;j<n;j++) 
// 						{ 
// 							s_tl[i]+=H0[i][j]*y[j]; 
// 						} 
// 					} 
// 					
// 					for(i=0;i<n;i++)//初值 
// 						for(j=0;j<n;j++) 
// 							s_temp2[i][j]=0; 
// 						
// 						for(i=0;i<n;i++) 
// 						{ 
// 							for(j=0;j<n;j++) 
// 							{ 
// 								s_temp2[i][j]=s_tl[i]*y[j]; 
// 							} 
// 						} 
// 						
// 						for(i=0;i<n;i++)//初值 
// 							for(j=0;j<n;j++) 
// 								s_temp3[i][j]=0; 
// 							
// 							for(i=0;i<n;i++) 
// 							{ 
// 								for(j=0;j<n;j++) 
// 								{ 
// 									for(int ii=0;ii<n;ii++) 
// 									{ 
// 										s_temp3[i][j]+=s_temp2[i][ii]*H0[ii][j]; 
// 									} 
// 								} 
// 							} 
// 							
// 							for(i=0;i<n;i++) 
// 							{ 
// 								for(j=0;j<n;j++) 
// 								{ 
// 									H0[i][j]=H0[i][j]+s_temp[i][j]-s_temp3[i][j]/temp; 
// 								} 
// 							} 
// 							for(i=0;i<n;i++) 
// 							{ 
// 								temp=0; 
// 								for(j=0;j<n;j++) 
// 								{ 
// 									temp+=H0[i][j]*g0[j]; 
// 								} 
// 								p[i]=(-1)*temp; 
// 							} 
// 							k++; 
// 				} 
// 				else 
// 				{ 
// 					f0=fun(x,f_xs); 
// 					//这里x[n],g0[n]的值已经修改 
// 					break; 
// 				} 
// 			} 
// 			else 
// 			{ 
// 				flag=1; 
// 				break; 
// 			} 
// 			tap++; 
// }while(H(g0,c)==0); 
// if(flag==1)//符合梯度准则跳出 
// { 
// 	flag=0; 
// 	break; 
// } 
// }while(k==n); 
// 
// cout<<"DFP法"<<endl; 
// cout<<"函数f(x1,x2)=4(X1-5)^2+(X2-6)^2.的极小点为:"<<"f="<<f0<<endl; 
// cout<<"自变量取值为:"<<endl; 
// for(i=0;i<n;i++) 
// { 
// 	cout<<"x"<<i+1<<"="<<x[i]<<endl; 
// } 
// cout<<"迭代次数为:"<<tap<<endl; 
// } 
// 
// double fun(double x[n],double f_xs[n+n+1+(n-1)*n/2])//输入变量为函数自变量初值 
// { 
// 	int i,j; 
// 	double f=0; 
// 	for(i=0;i<n;i++)//计算X^2部分 
// 	{ 
// 		f+=pow(x[i],2)*f_xs[i]; 
// 	} 
// 	for(;i<2*n;i++)//计算X部分 
// 	{ 
// 		f+=x[i>n]*f_xs[i]; 
// 	} 
// 	f+=f_xs[i];//计算常数项部分 
// 	for(i=0;i<n;i++)//计算XiXj部分 
// 	{ 
// 		for(j=i+1;j<n;j++) 
// 		{ 
// 			f+=f_xs[(n+1)+n*(i+1)-i*(i+1)/2+j-i-1]*x[i]*x[j]; 
// 		} 
// 	} 
// 	return f; 
// } 
// 
// void Q_fun(double f_xs[n+n+1+(n-1)*n/2],double Q[n][n+1])//Q[n][n]是二次函数的正定矩阵,但Q的第n+1列存储一次项的系数 
// { 
// 	int i,j; 
// 	for(i=0;i<n;i++) 
// 	{ 
// 		Q[i][i]=2*f_xs[i]; 
// 	} 
// 	for(i=0;i<n;i++) 
// 	{ 
// 		Q[i][n]=f_xs[n+i]; 
// 	} 
// 	for(i=0;i<n;i++) 
// 	{ 
// 		for(j=i+1;j<n;j++) 
// 		{ 
// 			Q[j][i]=Q[i][j]=f_xs[(n+1)+n*(i+1)-i*(i+1)/2+j-i-1]; 
// 		} 
// 	} 
// } 
// 
// void D_fun(double x[n],double Q[n][n+1],double g0[n])//自变量初值,正定二次函数的各项系数,返回梯度的初值 
// { 
// 	int i,j; 
// 	for(i=0;i<n;i++) 
// 	{ 
// 		g0[i]=0;//清零 
// 		for(j=0;j<n;j++) 
// 		{ 
// 			if(i==j) 
// 				g0[i]+=Q[i][j]*x[j]; 
// 			else 
// 				g0[i]+=Q[i][j]*x[j]; 
// 		} 
// 	} 
// 	for(i=0;i<n;i++) 
// 	{ 
// 		g0[i]+=Q[i][n]; 
// 	} 
// 	cout<<endl<<"梯度g0的值="<<endl; 
// 	for(i=0;i<n;i++) 
// 		cout<<setw(10)<<g0[i]<<endl; 
// 	cout<<endl; 
// } 
// 
// int H(double g0[n],double c)//判别准则:返回1结束,返回0继续迭代 
// { 
// 	double s=0; 
// 	for(int i=0;i<n;i++) 
// 	{ 
// 		s+=pow(g0[i],2); 
// 	} 
// 	if(sqrt(s)<c) 
// 		return 1; 
// 	else 
// 		return 0; 
// } 
// 
// void abc(double x[n],double p[n],double f_xs[n+n+1+(n-1)*n/2],double t[3])//t[3]中返回的是a,b,c的系数值 
// { 
// 	int i,j; 
// 	
// 	t[0]=t[1]=t[2]=0; 
// 	t[0]=fun(p,f_xs)-f_xs[2*n]; 
// 	for(i=n;i<2*n;i++) 
// 	{ 
// 		t[0]-=f_xs[i]*p[i>n]; 
// 	} 
// 	for(i=0;i<n;i++) 
// 	{ 
// 		t[1]+=2*f_xs[i]*x[i]*p[i]; 
// 	} 
// 	for(;i<2*n;i++) 
// 	{ 
// 		t[1]+=f_xs[i]*p[i>n]; 
// 	} 
// 	for(i=0;i<n;i++) 
// 	{ 

⌨️ 快捷键说明

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