1、0.618法
// 0.618.cpp : 优化方法:0.618法确定一维搜索问题的搜索区间。
//
#include "stdio.h"
#include "iostream"
#include "math.h"
using namespace std;
//#define Lambda 0.618
double 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];//二阶段法的向量r
void 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);
}