坐标轮替上升法(吴恩达机器学习c#实践)

参考书目:机械最优设计技术,孟兆明 常德功编著

坐标轮替上升法与梯度下降非常相似,在梯度下降基础上以下是c#代码:

namespace 坐标上升法//求函数minF(X)=x1^2+x2^2-x1*x2-15*x1+75
{
    public partial class Form1 : Form//求函数minF(X)=x1^2+x2^2-x1*x2-15*x1+75
    {
        public Form1()
        {
            InitializeComponent();
        }
        int 维数N = 2;
        double 收敛精度E = 0.01;
        double[] X;
        private void Form1_Load(object sender, EventArgs e)
        {
            X = new double[维数N];
            for (int n = 0; n < 维数N; n++)
            {
                X[n] = 0;// X[0] = 0;
                // X[1] = 0;
            }

//借用梯度下降第一次求步长
            //1,计算一次黑塞矩阵,求出第一个轮换坐标轴的步长=minf(x^k-ttttttttt*deltaf(x^k))
            double[] X的偏导数P = new double[维数N];
            X的偏导数P[0] = 2 * X[0] - X[1] - 15;//x0^2+x1^2-x0*x1-15*x0+75=f
            X的偏导数P[1] = 2 * X[1] - X[0];
           //求黑塞矩阵,此处已经求出
            int H00 = 2;
            int H01 = -1;
            int H10 = -1;
            int H11 = 2;
            //计算步长
            //第一步,计算分子,内积
            double 分子 = X的偏导数P[0] * X的偏导数P[0] + X的偏导数P[1] * X的偏导数P[1];
            //第二步,计算分母,内*H*积
            double 分母1 = X的偏导数P[0] * H00 + X的偏导数P[1] * H10;//x
            double 分母2 = X的偏导数P[0] * H01 + X的偏导数P[1] * H11;//y
            double 分母 = 分母1 * X的偏导数P[0] + 分母2 * X的偏导数P[1];
            //第三部,步长=分子/分母
            double 步长 = 分子 / 分母;//ttttttttttttttttttttttttttttttttt
            //计算第二次迭代的X1=X-步长*第一次的梯度
            X[0] = X[0] - 步长 * X的偏导数P[0];// X[0]这就是第一个轮换坐标轴的步长,=7.5,最优步长?
            X[1] = X[1] - 步长 * X的偏导数P[1];// X[1] 这个步长等于0,不合适,无改变

            ///2,开始坐标轮换上升算法
            double 初始最优步长 = X[0]*2;

            PointF 初始X0 = new Point(0, 0);

            坐标轮换上升迭代(初始X0, 初始最优步长);         
        }
        private void 坐标轮换上升迭代(PointF X0,double 最优步长)
        {
            //第一次坐标轮换,先x轴
            PointF 假定先x轴先轮换1 = new PointF();
            Point P1 = new Point(1, 0);
            最优步长 = 0.5 * 最优步长;
            假定先x轴先轮换1.X = (float)(X0.X + 最优步长 * P1.X);
            假定先x轴先轮换1.Y = (float)(X0.Y + 最优步长 * P1.Y);
            //第二次坐标轮换,再y轴
            PointF y轴后轮换2 = new PointF();
            Point P2 = new Point(0, 1);
            最优步长 = 0.5 * 最优步长;
            y轴后轮换2.X = (float)(假定先x轴先轮换1.X + 最优步长 * P2.X);
            y轴后轮换2.Y = (float)(假定先x轴先轮换1.Y + 最优步长 * P2.Y);
            //一波xy轮换后,对比要求精度,是否达标
            double G = (y轴后轮换2.X - X0.X) * (y轴后轮换2.X - X0.X);

            G = G + (y轴后轮换2.Y - X0.Y) * (y轴后轮换2.Y - X0.Y);

            G = Math.Sqrt(G);
            if (G > 收敛精度E)//继续坐标轮换上升迭代
            {
                X0 = y轴后轮换2;
                坐标轮换上升迭代( X0,最优步长);
            }
        }
    }
}

参考如下:

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页