用共轭梯度法求函数极小值和最优解,其中用进退法求步长区间,用黄金分割法求最佳步长
来源:互联网 发布:php开源三级分销商城 编辑:程序博客网 时间:2024/06/06 06:36
//共轭梯度法求二次函数的最优解和极小值/*----------------------------------------------*///本函数为 x1*x1+4*x2*x2-2*x1*x2-4*x1/*----------------------------------------------*///若需要改为其他函数,请修改//change#include<stdio.h>#include<math.h>#include<stdlib.h>#pragma warning(disable:4996)//取消scanf不安全提示//原函数#define f(x1,x2) x1*x1+4*x2*x2-2*x1*x2-4*x1//change//梯度模#define tdm(x1,x2) sqrt((2*x1-2*x2-4)*(2*x1-2*x2-4)+(8*x2-2*x1)*(8*x2-2*x1))//change//x1的偏导数#define G1(x1,x2) 2*x1-2*x2-4//change//x2的偏导数#define G2(x1,x2) 8*x2-2*x1//change//一维搜索//进退法求搜索区间const float eps = 0.00001;//eps为计算精度double HJFC(double x1[], double s1[]){int k = 1, i, j;double a0 = 1, b0 = 0.5, a1, b1, a[3], f[3], y[3][2], m, n, ak2, c;//a0为初始步长,b0为初始步长增量,a1,b1为进退法确定的最终区间;a[0] = a0;a[1] = a0 + b0;for (i = 0; i < 2; i++)for (j = 0; j < 2; j++)y[i][j] = x1[j] + a[i] * s1[j];for (i = 0; i < 2; i++)f[i] = f(y[i][0], y[i][1]);if (f[0]>f[1])while (k){b0 = 2 * b0;a[2] = a[1] + b0;for (j = 0; j < 2; j++)y[2][j] = x1[j] + a[2] * s1[j];f[2] = f(y[2][0], y[2][1]);if (f[2]>f[1]){m = a[0];n = a[2];k = 0;}else{k = 1;a[1] = a[2];f[1] = f[2];}}elsewhile (k){b0 = 2 * b0;a[2] = a[0] - b0;for (j = 0; j < 2; j++)y[2][j] = x1[j] + a[2] * s1[j];f[2] = f(y[2][0], y[2][1]);if (f[2]>f[0]){m = a[2];n = a[1];k = 0;}else{k = 1;a[0] = a[2];f[0] = f[2];}}//黄金分割法求最佳步长a1 = m;b1 = n;a[0] = n - 0.618*(n - m);a[1] = m + 0.618*(n - m);for (i = 0; i < 2; i++)for (j = 0; j < 2; j++)y[i][j] = x1[j] + a[i] * s1[j];for (i = 0; i < 2; i++)f[i] = f(y[i][0], y[i][1]);do{if (f[0] < f[1]){n = a[1];a[1] = a[0];f[1] = f[0];a[0] = n - 0.618*(n - m);for (j = 0; j < 2; j++)y[0][j] = x1[j] + a[0] * s1[j];f[0] = f(y[0][0], y[0][1]);}else{m = a[0];a[0] = a[1];f[0] = f[1];a[1] = m + 0.618*(n - m);for (j = 0; j < 2; j++)y[1][j] = x1[j] + a[1] * s1[j];f[1] = f(y[1][0], y[1][1]);}c = (n - m) / (b1 - a1);} while (fabs(c)>eps);ak2 = (m + n) / 2;return ak2;}//共轭梯度void main(){double x[2], s[2], g[4], bita, arph;//x数组为函数解得转置矩阵;s数组为搜索方向的转置矩阵,g数组为梯度转置矩阵,arph为最优步长;int k = 1;//k为迭代次数;//赋初值printf("请输入初始x1,x2(本函数是:1 1):\n\n");scanf("%d %d", &x[0], &x[1]);printf("过程如下:\n\n");g[0] = G1(x[0], x[1]);g[1] = G2(x[0], x[1]);while (tdm(x[0], x[1]) > eps)//迭代终止准则{if (k == 1){s[0] = -g[0];s[1] = -g[1];bita = 0;}else{bita = (g[0] * g[0] + g[1] * g[1]) / (g[2] * g[2] + g[3] * g[3]);s[0] = -g[0] + bita*s[0];s[1] = -g[1] + bita*s[1];}arph = HJFC(x, s);x[0] = x[0] + arph*s[0];x[1] = x[1] + arph*s[1];g[2] = g[0];g[3] = g[1];g[0] = G1(x[0], x[1]);g[1] = G2(x[0], x[1]);printf("第%d次迭代:\n\n", k);printf("步长steplength=%f\t", arph);printf("bb=%f\t\n", bita);printf("x[0]=%f\tx[1]=%f\n\n\n", x[0], x[1]);k++;}k--;printf("最后结果:\n");printf("最优解为:\nx[0]=%f\nx[1]=%f\n 最小值:min=%f\n 迭代次数:n=%d\n", x[0], x[1], f(x[0], x[1]), k);}
0 0
- 用共轭梯度法求函数极小值和最优解,其中用进退法求步长区间,用黄金分割法求最佳步长
- 梯度下降法求极小值
- 基于MATLAB和C#编程实现二元函数梯度下降法求极小值
- 用 梯形法,矩形法,辛普生法,变步长梯形法,求积分
- 黄金分割法求函数最小值
- [黄金分割比] 黄金分割法求单峰函数最值
- 黄金分割法与单峰函数求极值
- 随机梯度下降法步长的选择
- 基于复化梯度求积的求积步长自适应matlab实现
- 计算方法之用变步长梯形求积公式求定积分
- 牛顿法求极大极小值
- 变步长梯形求数值积分
- 二分法与黄金分割法求函数方程最小值
- 变步长梯形法
- 步长加速法
- 求极大和极小值
- 用梯度下降法求极大值-Matlab
- 视觉与目标跟踪第一课——梯度下降法求已知函数的局部最优解
- Android 新闻App的开发思路
- 杭电-2028 Lowest Common Multiple Plus (LCM)
- Swift学习第十二枪----移动数据库王者Realm入门教程
- {小结}2016.6.11【初中部 NOIP提高组 】模拟赛C
- jquery animate自定义动画的使用感受
- 用共轭梯度法求函数极小值和最优解,其中用进退法求步长区间,用黄金分割法求最佳步长
- Mybatis动态SQL--采用开发案例讲解
- 剑指offer(五十九)之二叉搜索树的后序遍历序列
- 神奇的栈帧
- 面向对象——this和super
- [Java] 对象的声明与实例化
- C++ 理解二维数组的指针
- Shell脚本编程之函数
- android通讯录之短信