参考书目:机械最优设计技术,孟兆明 常德功编著
坐标轮替上升法与梯度下降非常相似,在梯度下降基础上以下是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,最优步长);
}
}
}
}
参考如下: