C++黄金分割法
简单来说,黄金分割法是一种无约束单目标一维优化方法。
下面是简单的一个黄金分割法程序。
#include <iostream>
#include<cmath>
using namespace std;
double func(double x);
//一维搜索
class Golden
{
public:
Golden(double x0, double h0,double eps1,double eps2, double K)
{
//成员属性初始化
this->m_x0 = x0;
this->m_h = h0;
this->m_epsx = eps1;
this->m_epsf = eps2;
this->m_K = K;
}
//黄金分割法
double* golden_search(double X_F[], double x_0[])
{
// double X_F[]
//黄金比例
double r = (sqrt(5)-1)/2;
//循环标识
int kk = 1;
//进退法计算搜索区间
double *X0 = this->jintui_search(x_0);
double X[2] = {0,0};
double f[4] = {0}; //前两个存两边的函数值,后两个存中间的函数值
//两个初值
f[0] = func(X0[0]); //fa
f[1] = func(X0[1]); //fb
while(kk > 0)
{
X[0] = X0[1]-r*(X0[1]-X0[0]); //a1
X[1] = X0[0]+r*(X0[1]-X0[0]); //a2
//变换后的值
f[2] = func(X[0]); //记为f1
f[3] = func(X[1]); //记为f2
--this->m_K;
if(f[2] >= f[3])
{
X0[0] = X[0]; //一项就够了
f[0] = f[2];
}
else
{
X0[1] = X[1];
f[1] = f[3];
}
if((fabs(f[1]-f[0])< this->m_epsf) & (fabs(X0[0]-X0[1])< this->m_epsx))
{
kk = 0;
X_F[0] = 0.5*(X0[0]+X0[1]);
X_F[1] = func(X_F[0]);
}
if(this->m_K < 0)
{
cout << "达到计算上限" << endl;
kk = 0;
}
}
return X_F;
}
//进退法找搜索区间
double* jintui_search(double x_0[])
{
double jin_f[2] = {0};
double jin_x[4] = {0};
jin_x[2] = this->m_x0; //x3
int k = 0;
// while(true)
// {
// jin_x[1] = jin_x[0]+this->m_h;
// jin_f[0] = func(jin_x[0]); //f1
// jin_f[1] = func(jin_x[1]); //f2
// if(jin_f[1] < jin_f[0])
// {
// x_0[0] = jin_x[0];
// jin_x[2] = jin_x[0]+2*this->h;
// jin_f[2] = func(jin_x[2]);
// if(jin_f[2] < jin_f[1])
// {
//
// }
// }
// }
while(true)
{
k = k+1;
jin_x[3] = jin_x[2]+this->m_h; //xp
jin_f[1] = func(jin_x[3]); //fp
jin_f[0] = func(jin_x[2]); //f3
if(jin_f[1] < jin_f[0])
{
// mygive(x2,x3);
jin_x[1] = jin_x[2];
// mygive(x3,xp);
jin_x[2] = jin_x[3];
this->m_h = 2*this->m_h;
}
else
{
if(k == 1)
{
// mygive(x2,xp);
jin_x[1] = jin_x[3];
this->m_h = -this->m_h;
}
else
{
// mygive(x1,x2);
jin_x[0] = jin_x[1];
// mygive(x2,x3);
jin_x[1] = jin_x[2];
// f2 = f3;
// mygive(x3,xp);
jin_x[2] = jin_x[3];
// f3 = fp;
break;
}
}
}
if(jin_x[2] > jin_x[0])
{
x_0[0] = jin_x[0];
x_0[1] = jin_x[2];
}
else
{
x_0[0] = jin_x[2];
x_0[1] = jin_x[0];
}
return x_0;
}
void myprint(double *x, int len)
{
for(int i = 0; i < len; i++)
{
cout << x[i] <<' ';
}
cout << endl;
}
//初值
double m_x0;
//搜索步长
double m_h;
//精度
double m_epsx;
double m_epsf;
//循环次数
int m_K;
};
double func(double x)
{
return x*x-5*x+100;
}
void test01()
{
Golden g(0,0.1,1e-5,1e-5,50);
double x_0[2] = {0};
double X_F[2] = {0};
double *x = g.golden_search(X_F,x_0);
g.myprint(x,2);
// double *y = g.jintui_search(x_0);
// g.myprint(y,2);
}
int main()
{
test01();
// double f1 = func(95.3),f2 = func(249.8);
// cout << f1 << ' ' << f2 << endl;
return 0;
}
结果如下: