优化方法(C++)——0.618法、平均值法、单纯形法
来源:互联网 发布:碳足迹 水足迹 数据 编辑:程序博客网 时间:2024/06/05 18:09
1、0.618法
// 0.618.cpp : 优化方法:0.618法确定一维搜索问题的搜索区间。//#include "stdio.h"#include "iostream"#include "math.h"using namespace std;//#define Lambda 0.618double f(double x) //输入 min f(x) f(x)的函数体{ return (x*x-1)*(x*x-1); //return exp(-x)+x*x;}void main(){ double a, b, Epsilon; double Lambda, Mu; a=2, b=5; Epsilon=0.5; //cout<<"输入搜索区间左值:\n"; //cin>>a; //cout<<"输入搜索区间右值:\n"; //cin>>b; Lambda=a+(1-0.618)*(b-a); Mu=a+0.618*(b-a); while((b-a)>=Epsilon) { if(f(Lambda)>f(Mu))//步骤3 { a=Lambda; b=b; Lambda=Mu; Mu=a+0.618*(b-a); } else //步骤4 { a=a; b=Mu; Mu=Lambda; Lambda=a+(1-0.618)*(b-a); } } cout<<"搜索区间为:["<<a<<","<<b<<"]"<<"\n"<<"最优解为:"<<(a+b)/2<<"\n"; system("pause"); return ;}
2、平均值法
// mean.cpp : 优化方法:平均法确定一维搜索问题的搜索区间。//#include "stdio.h"#include "iostream"#include "math.h"using namespace std;double f(double x) ;double d_f(double x);void main(){ double a, b, Epsilon; double x0; Epsilon=0.001; cout<<"输入搜索区间左值:\n"; cin>>a; cout<<"输入搜索区间右值:\n"; cin>>b; if(d_f(a)<0 && d_f(b)>0) { x0=(a+b)/2; while(fabs(d_f(x0))>Epsilon) { x0=(a+b)/2; if(d_f(x0)>0) { b=x0; } else { a=x0; } } cout<<"最优解为:"<<x0<<"\n"; } else { cout<<"该区间内不存在最优解 \n"; } return ;}double f(double x) //输入 min f(x) f(x)的函数体{ //return x*x+2.0*x; //return exp(-x)+x*x; //return x*x*x*x/4-4*x*x*x/3+5*x*x/2-2*x; return 3*x*x*x*x-16*x*x*x+30*x*x-24*x+8;}double d_f(double x){ double Delte=0.00001; return (f(x+Delte)-f(x))/Delte;}
3、单纯形法
//simplex.cpp : 单纯形法。//ex1、ex2#include "stdio.h"#include "iostream"#include <vector>using namespace std;#define m 3 //初始表大小:m行n列 (m<n)#define n 5//*************************************************************************************double A[m][n], b[m], C[n], c[n], A2[m][n];//c[n] 标准型的目标函数系数int BaseVariable[m]; //基变量int NotBaseVariable[n-m]; //非基变量int ArtificalVariable[m]; //人工变量double f=0;int C_min_mark;int b_min_mark;double r[n];//二阶段法的向量rvoid input2();void input2(double **a,int len1,int len2);void input();void input(double **a,int len1,int len2);void output();void output(double **a,int len1,int len2);double determine();double determine(int len1,int len2);double determine2();double determine2(int len1,int len2);void exchange();void newexchange(double **a,int len1,int len2);void one_stage();void two_stage();void two_stage2();void main(){ one_stage();//一阶段 //two_stage();//两阶段 system("pause"); return ;}void two_stage2(){ input2(); //double a[m][n]; //input2((double **)a,m,n); output(); //output((double**)a,m,n); while(determine2()) { exchange(); //newexchange((double**)a,m,n); output(); } if(f==0) { //double a2[m][n-m]; //for(int i=0;i<m;i++) // for(int j=0;j<n-m;j++) // (*((int *)a2+i*m+j))=(*((int *)a+i*m+j)); //int k=0,K[n-m-m]; //for(int i=0;i<n-m;i++) //{ // // for(int j=0;j<m;j++) // { // if(NotBaseVariable[j]!=BaseVariable[i]) // K[k]; // } //} //while(determine(m,n-m)) // { // newexchange((double**)a2,m,n-m); // output((double**)a,m-m,n-m); // } cout<<"最优解f为:\n"<<-f<<endl; } else cout<<"原问题无可行解,故无最优解. \n"<<endl; }void two_stage(){ double a[m][n]; input2((double **)a,m,n); output((double**)a,m,n); while(determine2(m,n)) { newexchange((double**)a,m,n); output((double**)a,m,n); } if(f==0) { double a2[m][n-m]; for(int i=0;i<m;i++) for(int j=0;j<n-m;j++) (*((int *)a2+i*n+j))=(*((int *)a+i*n+j)); while(determine(m,n-m)) { newexchange((double**)a2,m,n-m); output((double**)a,m-m,n-m); } cout<<"最优解f为:\n"<<-f<<endl; } else cout<<"原问题无可行解,故无最优解. \n"<<endl; }void one_stage()//一阶段单纯形法{ double a[m][n]; //input(); input((double**)a,m,n); //output(); output((double**)a,m,n); while(!determine()) { //exchange(); newexchange((double**)a,m,n); output((double**)a,m,n); } cout<<"最优解f为:\n"<<-f<<endl;}void input2(double **a,int len1,int len2) //输入A[m][n], b[m], C[m],并确定基变量BaseVariable[m]{ //double a[len1][len2]; cout<<"输入系数矩阵A:\n"; for(int i=0;i<len1;i++) { for(int j=0;j<len2;j++) { cout<<"A["<<i<<"]"<<"["<<j<<"]="; { cin>>(*((int *)a+i*len2+j)); //A[i][j]=(*((int *)a+i*len1+j)); } } cout<<"\n"; } cout<<"输入右端项b:\n"; for(int i=0;i<len1;i++) { cout<<"b["<<i<<"]="; cin>>b[i]; } int j=0,k=0; for(int i=0;i<len2;i++) { if(i<len2-len1) { C[i]=0; NotBaseVariable[j]=i; j++; } else { C[i]=1; BaseVariable[k]=i; ArtificalVariable[k]=i;//记录人工变量 k++; } } for(int j=0;j<len2;j++) { for(int i=0;i<len1;i++) C[j]=C[j]-(*((int *)a+i*len2+j));//即 C0[n]->r[n] 过程 } for(int i=0;i<len1;i++) { f=f-b[i]; } cout<<"输入标准型的目标函数系数 C:\n"; for(int i=0;i<len2-len1;i++) { cout<<"c["<<i<<"]="; cin>>c[i]; }}void input() //输入A[m][n], b[m], C[m],并确定基变量BaseVariable[m]{ cout<<"输入系数矩阵A:\n"; for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { cout<<"A["<<i<<"]"<<"["<<j<<"]="; cin>>A[i][j]; } cout<<"\n"; } cout<<"输入右端项b:\n"; for(int i=0;i<m;i++) { cout<<"b["<<i<<"]="; cin>>b[i]; } cout<<"输入约束条件系数C:\n"; int j=0,k=0; for(int i=0;i<n;i++) { cout<<"C["<<i<<"]="; cin>>C[i]; if(C[i]==0) { BaseVariable[j]=i; //确定基变量 x2 x3 x4 j++; } else { NotBaseVariable[k]=i; //确定非基变量 x0 x1 k++; } }}void output(){ cout<<"矩阵A为:\n"; for(int i=0;i<m;i++) { for(int j=0;j<n;j++) cout<<A[i][j]<<" "; cout<<"\n"; } cout<<"右端项b:\n"; for(int i=0;i<m;i++) { cout<<b[i]<<" "; } cout<<"\n"; cout<<"约束条件系数C:\n"; for(int i=0;i<n;i++) { cout<<C[i]<<" "; } cout<<"\n"; cout<<"f="<<f<<"\n";}double determine2(){ int BaseVariableIncludeArtificalVariable=0; for(int i=0;i<m;i++) { for(int j=0;j<m;j++) { if(BaseVariable[i]==ArtificalVariable[j]) BaseVariableIncludeArtificalVariable++; } } if(BaseVariableIncludeArtificalVariable)//基变量中若含有人工变量则继续交换 return 1; else return 0;}double determine()//判定C{ int C_BaseVariable_M0=0, C_BaseVariable_L0=0, C_BaseVariable_E0=0; int C_NotBaseVariable_M0=0, C_NotBaseVariable_L0=0, C_NotBaseVariable_E0=0;//大于、小于、等于M L E //double C_min=0; for(int i=0;i<m;i++) { if(C[BaseVariable[i]]==0) C_BaseVariable_E0++; else { if(C[BaseVariable[i]]<0) C_BaseVariable_L0++; else C_BaseVariable_M0++; } } for(int i=0;i<(n-m);i++) { if(C[NotBaseVariable[i]]>0) C_NotBaseVariable_M0++; else { if(C[NotBaseVariable[i]]<0) { C_NotBaseVariable_L0++; } else C_NotBaseVariable_E0++; } } if(C_BaseVariable_E0==m && C_NotBaseVariable_L0==0)//基变量的检验数都等于0,非基变量的检验数都大于0 return 1; if(C_BaseVariable_E0==m && C_NotBaseVariable_L0!=0)//基变量的检验数都等于0,非基变量的检验数都大于0 return 0;}void exchange(){ double C_min=C[0]; int C_min_mark=0; for(int i=0;i<sizeof(C)/sizeof(double);i++) { if(C[i]<C_min) { C_min=C[i]; C_min_mark=i; } } double b_min; for(int i=0;i<m;i++) { if(A[i][C_min_mark]!=0 && b[i]/A[i][C_min_mark]>0) { b_min=b[i]/A[i][C_min_mark]; //记录min(b[m])的下标 b_min_mark=i; for(int j=i;j<m;j++) { if(A[j][C_min_mark]!=0 && b[j]/A[j][C_min_mark]>0 && b[j]/A[j][C_min_mark]<b_min)//0与负数不参加比值 { b_min=b[j]/A[j][C_min_mark];//记录min(b[m])的下标 b_min_mark=j; } } break; } } //确定主元A[b_min_mark][C_min_mark] double A0[m][n], C0[n]; for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { A0[i][j]=A[i][j]; } } for(int j=0;j<n;j++) { C0[j]=C[j]; } for(int i=0;i<m;i++) { if(i!=b_min_mark && A[i][C_min_mark]!=0)//主元所在行不变; { for(int j=0;j<n;j++) { A0[i][j]=A[i][j]-1.0*A[b_min_mark][j]*A[i][C_min_mark]/A[b_min_mark][C_min_mark];//利用主元将对应列消去; } b[i]=b[i]-b[b_min_mark]*A[i][C_min_mark]/A[b_min_mark][C_min_mark]; } } for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { A[i][j]=A0[i][j]; } } f=f-1.0*b[b_min_mark]*C[C_min_mark]/A[b_min_mark][C_min_mark]; for(int j=0;j<n;j++) { C0[j]=C[j]-A[b_min_mark][j]*C[C_min_mark]/A[b_min_mark][C_min_mark]; } for(int j=0;j<n;j++) { C[j]=C0[j]; } NotBaseVariable[C_min_mark]=BaseVariable[b_min_mark]; BaseVariable[b_min_mark]=C_min_mark; // x C_min_mark进基,x b_min_mark出基}void exchange2(){ double C_min=C[0]; int C_min_mark=0; for(int i=0;i<sizeof(C)/sizeof(double);i++) { if(C[i]<C_min) { C_min=C[i]; C_min_mark=i; } } double b_min; for(int i=0;i<m;i++) { if(A2[i][C_min_mark]!=0 && b[i]/A2[i][C_min_mark]>0) { b_min=b[i]/A2[i][C_min_mark]; //记录min(b[m])的下标 b_min_mark=i; for(int j=i;j<m;j++) { if(A2[j][C_min_mark]!=0 && b[j]/A2[j][C_min_mark]>0 && b[j]/A2[j][C_min_mark]<b_min)//0与负数不参加比值 { b_min=b[j]/A2[j][C_min_mark];//记录min(b[m])的下标 b_min_mark=j; } } break; } } //确定主元A[b_min_mark][C_min_mark] double A0[m][n], C0[n]; for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { A0[i][j]=A2[i][j]; } } for(int j=0;j<n;j++) { C0[j]=C[j]; } for(int i=0;i<m;i++) { if(i!=b_min_mark && A2[i][C_min_mark]!=0)//主元所在行不变; { for(int j=0;j<n;j++) { A0[i][j]=A2[i][j]-1.0*A2[b_min_mark][j]*A2[i][C_min_mark]/A2[b_min_mark][C_min_mark];//利用主元将对应列消去; } b[i]=b[i]-b[b_min_mark]*A2[i][C_min_mark]/A2[b_min_mark][C_min_mark]; } } for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { A2[i][j]=A0[i][j]; } } f=f-1.0*b[b_min_mark]*C[C_min_mark]/A2[b_min_mark][C_min_mark]; for(int j=0;j<n;j++) { C0[j]=C[j]-A2[b_min_mark][j]*C[C_min_mark]/A2[b_min_mark][C_min_mark]; } for(int j=0;j<n;j++) { C[j]=C0[j]; } NotBaseVariable[C_min_mark]=BaseVariable[b_min_mark]; BaseVariable[b_min_mark]=C_min_mark; // x C_min_mark进基,x b_min_mark出基}void newexchange(double **a,int len1,int len2)// len1=m, len2=n ((int *)a+i*len1+j))=A2[i][j]{ double C_min=C[0]; int C_min_mark=0; for(int i=0;i<sizeof(C)/sizeof(double);i++) { if(C[i]<C_min) { C_min=C[i]; C_min_mark=i; } } double b_min; for(int i=0;i<len1;i++) { if((*((int *)a+i*len2+C_min_mark))!=0 && b[i]/(*((int *)a+i*len2+C_min_mark))>0) //A2[i][C_min_mark]=(*((int *)a+i*len1+C_min_mark)) { b_min=b[i]/(*((int *)a+i*len2+C_min_mark)); //记录min(b[m])的下标 b_min_mark=i; for(int j=i;j<len1;j++) { if((*((int *)a+j*len2+C_min_mark))!=0 && b[j]/(*((int *)a+j*len2+C_min_mark))>0 && b[j]/(*((int *)a+j*len2+C_min_mark))<b_min)//0与负数不参加比值 { b_min=b[j]/(*((int *)a+j*len2+C_min_mark));//记录min(b[m])的下标 b_min_mark=j; } } break; } } //确定主元A[b_min_mark][C_min_mark] double A0[m][n], C0[n]; for(int i=0;i<len1;i++) { for(int j=0;j<len2;j++) { A0[i][j]=(*((int *)a+i*len2+j)); } } for(int j=0;j<len2;j++) { C0[j]=C[j]; } for(int i=0;i<len1;i++) { if(i!=b_min_mark && (*((int *)a+i*len1+C_min_mark))!=0)//主元所在行不变; { for(int j=0;j<len2;j++) { A0[i][j]=(*((int *)a+i*len2+j))-1.0*(*((int *)a+b_min_mark*len2+j))*(*((int *)a+i*len2+C_min_mark))/(*((int *)a+b_min_mark*len2+C_min_mark));//利用主元将对应列消去; } b[i]=b[i]-b[b_min_mark]*(*((int *)a+i*len2+C_min_mark))/(*((int *)a+b_min_mark*len2+C_min_mark)); } } for(int i=0;i<len1;i++) { for(int j=0;j<len2;j++) { (*((int *)a+i*len2+j))=A0[i][j]; } } f=f-1.0*b[b_min_mark]*C[C_min_mark]/(*((int *)a+b_min_mark*len2+C_min_mark)); for(int j=0;j<len2;j++) { C0[j]=C[j]-(*((int *)a+b_min_mark*len2+j))*C[C_min_mark]/(*((int *)a+b_min_mark*len2+C_min_mark)); } for(int j=0;j<len2;j++) { C[j]=C0[j]; } NotBaseVariable[C_min_mark]=BaseVariable[b_min_mark]; BaseVariable[b_min_mark]=C_min_mark; // x C_min_mark进基,x b_min_mark出基}void input(double **a,int len1,int len2) //输入A[m][n], b[m], C[m],并确定基变量BaseVariable[m]{ cout<<"输入系数矩阵A:\n"; for(int i=0;i<len1;i++) { for(int j=0;j<len2;j++) { cout<<"A["<<i<<"]"<<"["<<j<<"]="; cin>>(*((int *)a+i*len2+j)); } cout<<"\n"; } cout<<"输入右端项b:\n"; for(int i=0;i<len1;i++) { cout<<"b["<<i<<"]="; cin>>b[i]; } cout<<"输入约束条件系数C:\n"; int j=0,k=0; for(int i=0;i<len2;i++) { cout<<"C["<<i<<"]="; cin>>C[i]; if(C[i]==0) { BaseVariable[j]=i; //确定基变量 x2 x3 x4 j++; } else { NotBaseVariable[k]=i; //确定非基变量 x0 x1 k++; } }}void output(double **a,int len1,int len2) { cout<<"矩阵A为:\n"; for(int i=0;i<len1;i++) { for(int j=0;j<len2;j++) cout<<(*((int *)a+i*len2+j))<<" "; cout<<"\n"; } cout<<"右端项b:\n"; for(int i=0;i<len1;i++) { cout<<b[i]<<" "; } cout<<"\n"; cout<<"约束条件系数C:\n"; for(int i=0;i<len2;i++) { cout<<C[i]<<" "; } cout<<"\n"; cout<<"f="<<f<<"\n";}void input2() //输入A[m][n], b[m], C[m],并确定基变量BaseVariable[m]{ cout<<"输入系数矩阵A:\n"; for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { cout<<"A["<<i<<"]"<<"["<<j<<"]="; cin>>A[i][j]; } cout<<"\n"; } cout<<"输入右端项b:\n"; for(int i=0;i<m;i++) { cout<<"b["<<i<<"]="; cin>>b[i]; } int j=0,k=0; for(int i=0;i<n;i++) { if(i<n-m) { C[i]=0; NotBaseVariable[j]=i; j++; } else { C[i]=1; BaseVariable[k]=i; ArtificalVariable[k]=i;//记录人工变量 k++; } } for(int j=0;j<n;j++) { for(int i=0;i<m;i++) C[j]=C[j]-A[i][j];//即 C0[n]->r[n] 过程 } for(int i=0;i<m;i++) { f=f-b[i]; } cout<<"输入标准型的目标函数系数 C:\n"; for(int i=0;i<n-m;i++) { cout<<"c["<<i<<"]="; cin>>c[i]; }}double determine2(int len1,int len2){ int BaseVariableIncludeArtificalVariable=0; for(int i=0;i<len1;i++) { for(int j=0;j<len1;j++) { if(BaseVariable[i]==ArtificalVariable[j]) BaseVariableIncludeArtificalVariable++; } } if(BaseVariableIncludeArtificalVariable)//基变量中若含有人工变量则继续交换 return 1; else return 0;}double determine(int len1,int len2)//判定C{ int C_BaseVariable_M0=0, C_BaseVariable_L0=0, C_BaseVariable_E0=0; int C_NotBaseVariable_M0=0, C_NotBaseVariable_L0=0, C_NotBaseVariable_E0=0;//大于、小于、等于M L E //double C_min=0; for(int i=0;i<len1;i++) { if(C[BaseVariable[i]]==0) C_BaseVariable_E0++; else { if(C[BaseVariable[i]]<0) C_BaseVariable_L0++; else C_BaseVariable_M0++; } } for(int i=0;i<(len2-len1);i++) { if(C[NotBaseVariable[i]]>0) C_NotBaseVariable_M0++; else { if(C[NotBaseVariable[i]]<0) { C_NotBaseVariable_L0++; } else C_NotBaseVariable_E0++; } } if(C_BaseVariable_E0==len1 && C_NotBaseVariable_L0==0)//基变量的检验数都等于0,非基变量的检验数都大于0 return 1; if(C_BaseVariable_E0==len1 && C_NotBaseVariable_L0!=0)//基变量的检验数都等于0,非基变量的检验数都大于0 return 0;}
4、确定搜索区间和初始点
// mean.cpp : 优化方法:平均法确定一维搜索问题的搜索区间。//#include "stdio.h"#include "iostream"#include "math.h"using namespace std;double f(double x) ;void main(){ double t0, t1, t2, h; double a, b; h=0.2; cout<<"输入一个初始点的估计值:\n"; cin>>t0; t2=t0+h; if(f(t2)<=f(t0))//步骤3 { t1=t0+h;//步骤4 //f(t1); } else//步骤3 { h=-h; t1=t0+h;//步骤4 //f(t1); } while(f(t1)<=f(t0))//步骤5 { h=2*h; t2=t0; t0=t1; t1=t0+h;//步骤4 //f(t1); } a=min(t1,t2); b=max(t1,t2); cout<<"搜索区间为:["<<a<<","<<b<<"]"<<"\n"<<"初始点为:"<<(a+b)/2<<"\n"; system("pause"); return ;}double f(double x) //输入 min f(x) f(x)的函数体{ //return x*x+2.0*x; //return exp(-x)+x*x; //return x*x*x*x/4-4*x*x*x/3+5*x*x/2-2*x; //return x*x*x*x*x+2*x*x*x*x-4*x*x*x+x*x+x+2; return (x+1)*(x+1);}
阅读全文
0 0
- 优化方法(C++)——0.618法、平均值法、单纯形法
- 单纯形法(1)
- 单纯形法(2)
- 最优化理论——线性规划及单纯形法求解
- 单纯形法
- 单纯形法
- 单纯形法
- 单纯形法 学习
- 单纯形法
- 单纯形法
- ##单纯形法##
- 单纯形法
- 线性规划--单纯形法
- 单纯形法简介
- 单纯形法
- 单纯形法
- 修正单纯形法·优化算法实现·Java
- 最优化中单纯形法的matlab举例
- LeetCode——575. Distribute Candies(贪心)
- CoreData增删改查简单操作及多线程添加数据
- HDU4768 Flyer 二分|异或的性质|暴力
- POJ 2253(dijkstral变形超级简单)
- Map/Reduce原理
- 优化方法(C++)——0.618法、平均值法、单纯形法
- RFC文档(中文翻译版本)
- linux硬链接与软链接
- shiro学习-基础介绍(一)
- IBM规则引擎的学习三部曲(初步学习)
- Tess4J使用(A)
- 实验吧CTF题目之疑惑的汉字(1876)
- iOS 证书真机测试,推送证书
- jsp中静态包含和动态包含的区别与联系