C++黄金分割法

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;
}

结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值