`

用共轭梯度法求最优解

阅读更多

 

题目:

      已知 f(x) = (x1-1)2+5(x2-5)2+(x3-1)2+5(x4-5)  用快速下降法、牛顿法或共轭梯度法求 minf(x) 

 

共轭梯度法代码:

 

 

//共轭梯度法
//请根据具体题目,修改本程序“//@”所在行的下一行代码。
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
//@ 题目中方程是几元的,此处将LEN设为几
#define LEN 4
#define TYPE float

TYPE fAnswer(TYPE *x) {    //求f(x)的值,并返回
	TYPE f;
	//@ 题目中的方程写与此
	f = (x[0] - 1) * (x[0] - 1) + 5 * (x[1] - 5) * (x[1] - 5) + (x[2] - 1) * (x[2] - 1) + 5 * (x[3] - 5) * (x[3] - 5);
	return f;
}

void vectorMultiply(TYPE *x, TYPE e) {    //常数e乘x向量,赋值给x向量 【若求负梯度,可用梯度乘-1】
	int i;
	for(i = 0; i < LEN; i++) {
		x[i] = e * x[i];
	}
}

void vectorAdd(TYPE *x, TYPE *y, TYPE *z) {    //向量加法操作
	int i;
	for(i = 0; i < LEN; i++) {
		z[i] = x[i] + y[i];
	}
}

void vectorSub(TYPE *x, TYPE *y, TYPE *z) {    //向量减法操作
	int i;
	for(i = 0; i < LEN; i++) {
		z[i] = x[i] - y[i];
	}
}

void vectoreEqual(TYPE *x, TYPE *y) {    //向量赋值操作
	int i;
	for(i = 0; i < LEN; i++) {
		y[i] = x[i];
	}
}

TYPE norm2_graded(TYPE *x) {    //负梯度模的平方
	int i;
	TYPE norm2 = 0.0;

	for(i = 0; i < LEN; i++) {
		norm2 += x[i] * x[i];
	}

	return norm2;
}

//@ 对题目的xi分别求偏倒,赋值给stepLength[i]
void setStepLength(TYPE *stepLength, TYPE *x0) {
	stepLength[0] = 2 * (1 - x0[0]);
    stepLength[1] = 10 * (5 - x0[1]);
	stepLength[2] = 2 * (1 - x0[2]);
    stepLength[3] = 10 * (5 - x0[3]);
}

void DSC(TYPE *x0, TYPE *stepLength) {    //用D.S.C.法求下一个x落点
	TYPE x1[LEN];
	TYPE x2[LEN];
	TYPE x3[LEN];
	TYPE x4[LEN];
	TYPE x5[LEN];
	TYPE xa[LEN];
	TYPE xb[LEN];
	TYPE xc[LEN];
	vectorAdd(x0, stepLength, x1);
	if(fAnswer(x1) > fAnswer(x0))
		vectorMultiply(stepLength, -1);

	vectorAdd(x0, stepLength, x1);
	while(fAnswer(x1) <= fAnswer(x0)) {
		vectoreEqual(x1, x0);
		vectorAdd(stepLength, stepLength, stepLength);
		vectorAdd(x1, stepLength, x1);
	}

	vectorMultiply(stepLength, 0.5);
	vectorSub(x0, stepLength, x2);
	vectoreEqual(x1, x4);
	vectoreEqual(x0, x3);
	vectorSub(x1, stepLength, x5);

	if(fAnswer(x5) > fAnswer(x3))
		vectoreEqual(x3, xb);
	else
		vectoreEqual(x5, xb);

	vectorSub(xb, stepLength, xa);
	vectorAdd(xb, stepLength, xc);

	vectorMultiply(stepLength, (fAnswer(xa) - fAnswer(xc)) / (2 * (fAnswer(xa) - 2 * fAnswer(xb) + fAnswer(xc))));
	vectorAdd(xb, stepLength, x0);
	setStepLength(stepLength, xb);
}

void main() {    //方法主体
	TYPE x0[LEN];    //初始点
	TYPE stepLength[LEN];    //步长
	TYPE stepLength2[LEN];
	TYPE e = 0.001;    //误差
	TYPE a = 0.00;

	int i;    //用于循环计数
	int n = LEN;
	int count = 0;

    printf("请输入x的初始值:\n");
	for(i = 0; i < LEN; i++) {    //初始化x0数组
		printf("x%d = ", i+1);
		scanf("%f", &x0[i]);
	}

	setStepLength(stepLength, x0);

   	for(i = 1; norm2_graded(stepLength) > e * e; i++) {    //共轭梯度法的实现主体
		DSC(x0, stepLength);
		if(i != n) {
			if(norm2_graded(stepLength) <= e * e) break;
			setStepLength(stepLength2, x0);
			a = norm2_graded(stepLength2) / norm2_graded(stepLength);
			vectorMultiply(stepLength, a);
			vectorAdd(stepLength2, stepLength, stepLength); 
			i = i + 1;
		} else {
			i = 1;
		}
		count = count + 1;
	}

	printf("共轭梯度法循环结束,共循环%d次\n", count);

	printf("使用共轭梯度法获得的最优点为:\n");
	for(i = 0; i < LEN; i++) {
		printf("x%d = %f\n", i+1, x0[i]);
	}
	printf("minf(x) = %f\n", fAnswer(x0));

	printf("共轭梯度法程序结束!!!\n");
}

 

总结

        本解法所使用的一维搜索算法仍是改进的D.S.C.法,将步长 的初始值改为负梯度向量,D.S.C.算法中的其它一维参量也采用向量形式替换,使此D.S.C.法可适用于多维搜索。

        本解法仅通过将我发表的最速下降法中的main()函数中最速下降法的实现主体替换为共轭梯度法的实现主体而得到。

        经测试验证,此方法无误。

分享到:
评论

相关推荐

    近代优化方法利用C++编写的PRP共轭梯度法求最优解的程序

    近代优化方法,利用C++编写的PRP共轭梯度法求最优解的程序

    DSC共轭梯度_共轭梯度法_共轭梯度_

    利用DSC方法进行共轭梯度法计算函数最优解,可运行。

    论文研究 - 共轭梯度法在模型与实际差异的非线性最优控制中的应用

    在这里,共轭梯度法用于解决基于模型的改进的最优控制问题,其中反复使用所用模型的最优解,然后在每个迭代步骤中更新调整后的参数。 当达到收敛时,尽管模型与现实之间存在差异,但迭代解决方案仍将逼近原始最优...

    论文研究 - 基于新BFGS割线方程的修正非单调线搜索的比例共轭梯度法

    在本文中,我们基于Broyden-Fletcher-Goldfarb-Shanno(BFGS)方法的修正割线方程和新的改进的非单调线搜索技术,提供并分析了一种新的按比例缩放的共轭梯度法及其性能。 该方法合并了修改后的BFGS正割方程,以包括...

    一种基于约束共轭梯度的闪光照相图像重建算法

    RPCCG算法在闪光照相重建方程中引入Tikhonov正则化准则,利用预优约束共轭梯度法迭代求图像重建的 最优解。数值试验表明,采用最小二乘+平滑准则的RPCCG算法是一种具有较高的抗噪能力的有效闪光照 相图像重建算法,具有...

    Conjugate-Gradient-Method.rar_BFGS Fortran _共轭梯度_共轭梯度算法_最优化_非线性优

    它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。

    matlab实现共轭梯度和负梯度搜索问题

    matlab实现的共轭梯度和负梯度搜索无约束规划问题的最优解程序,其中线性搜索用Fibonacci搜索。最优化课程的编程作业,写完后感觉程序还可以通用,今后遇到类似问题可以节省点时间。先在博客上留下来。

    最优化方法及其Matlab程序设计

    以及主要算法的Matlab程序设计,主要内容包括(精确或非精确)线搜索技术、最速下降法与(修正)牛顿法、共轭梯度法、拟牛顿法、信赖域方法、非线性最小二乘问题的解法、约束优化问题的最优性条件、罚函数法、可行...

    基于Python实现多项式拟合正弦函数【100011190】

    掌握最小二乘法求解(无惩罚项的损失函数)、掌握加惩罚项(2 范数)的损失函数优化、梯度下降法、共轭梯度法、理解过拟合、克服过拟合的方法(如加惩罚项、增加样本) 实验要求 生成数据,加入噪声; 用高阶多项式...

    con_grad.m

    共轭梯度法最优解MATLAB程序,程序有注释,易于理解,可修改处已经注明,方便针对不同的目标函数进行修改测试运行。

    基于Python实现的多项式拟合曲线实验.zip

    掌握最小二乘法求解(无惩罚项的损失函数)、掌握加惩罚项(2范数)的损失函数优化、梯度下降法、共轭梯度法、理解过拟合、克服过拟合的方法(如加惩罚项、增加样本) 要求: 1. 生成数据,加入噪声; 2. 用高阶...

    最优化方法课件-解可新.ppt

    无约束最优化方法 3.1 无约束最优化问题的最优性条件 3.2 最速下降法 3.3 Newton法 3.4 共轭方向法和共轭梯度法 3.5 拟Newton法 3.6 Powell方向加速法 习题第4章 约束最优化方法 4.1 约束最优化问题的最优性条件 4.2...

    论文研究-一种新型高效的计算机寻优算法.pdf

    提出一种全新的寻找无约束最优解的计算机算法。该算法能使得目标函数梯度的模逐渐收缩到零,以达到目标函数极小化,因此命名“梯度收缩法”。它同时利用了牛顿法和共轭梯度法的优点,应用目标函数的二阶导数,收敛...

    最优化方法及其Matlab程序设计(马昌凤)

    本书较为系统地介绍了非线性最优化问题的...(修正)牛顿法, 共轭梯度法, 拟牛顿法, 信赖域方法, 非线性最小二乘问题的解 法, 约束优化问题的最优性条件, 罚函数法, 可行方向法, 二次规划问题的解法, 序列二次规划法等

    基于梯度理论的非线性优化研究

    基于梯度理论的非线性优化研究,张璐,,在生产实践中,非线性优化方法应用广泛,基于梯度搜索理论的共轭梯度法是一种寻找最优解的有效方法。我们将其应用到目前同样被广

    大连理工大学优化方法上机作业-2022春上机作业

    共轭梯度法 其中二次函数f(x) 的参数G, b在MATLAB上生成。 2 编写程序求解下述问题 选择初始点为x= (3,-1,0,1)T.该问题的最优解为x* =0.精度取1e- 4,步长由非精确线搜索生 成,方向分别由下列方法生成: 。最速下降法...

    基于自适应粒子群算法的变压器局部放电定位研究.pdf

    普遍使用的定位算法有修正牛顿算法,最速下降法,共轭梯度法,遗传算法,粒子群优化算法等,这些算法定位精度不够高,容易陷入局部最优值等缺点。 因此,本文引入一种改进的粒子群算法对变压器局部放电进行定位,...

    matlab罚函数的代码-MLLabs_HIT2018:哈尔滨工业大学2018机器学习实验室

    掌握最小二乘法求解(无惩罚项的损失函数)、掌握加惩罚项(2范数)的损失函数优化、梯度下降法、共轭梯度法、理解过拟合、克服过拟合的方法(如加惩罚项、增加样本) 要求: 生成数据,加入噪声; 用高阶多项式函数...

    1183710113-许健-Lab1-Report1

    1. 成数据,加噪声 2. 阶多项式函数拟合曲线 3. 解析解求解两种loss的最优解(正则项和有正则项) 4. 优化法求解最优解(梯度下降,共轭梯度) 5.

    conjugate-gradient-method.rar_

    用共轭梯度法求解系数矩阵为对称正定矩阵的二次函数的最优解

Global site tag (gtag.js) - Google Analytics