共轭梯度法c++程序

最优化课程设计

姓 名:指导老师:学 号:班 级:

题目:共轭梯度法

田鑫 智红英 [1**********]6

信息与计算科学111802班

共轭梯度法(Conjugate Gradient)

是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。 在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。

设我们要求解下列线性系统

其中n-×-n矩阵A是对称的(也即,AT = A),正定的(也即,xTAx > 0对于所有非0向量x属于Rn),并且是实系数的。 将系统的唯一解记作x*。 最后算法

经过一些简化,可以得到下列求解Ax = b的算法,其中A是实对称正定矩阵。

x0 := 0 k := 0 r0 := b

repeat until rk is "sufficiently small":

k := k + 1 if k = 1

p1 := r0 else

end if

xk := xk-1 + αk pk rk := rk-1 - αk A pk end repeat 结果为xk

共轭梯度法程序源代码

#include #include #define N 10

#define eps pow(10,-6)

double f(double x[],double p[],double t) {

double s;

s=pow(x[0]+t*p[0],2)+25*pow(x[1]+t*p[1],2); return s; }

/*以下是进退法搜索区间源程序*/

void sb(double *a,double *b,double x[],double p[]) {

double t0,t1,t,h,alpha,f0,f1; int k=0;

t0=2.5; /*初始值*/ h=1; /*初始步长*/ alpha=2; /*加步系数*/

f0=f(x,p,t0);

f1=f(x,p,t1); while(1) {

if(f1

h=alpha*h; t=t0; t0=t1; f0=f1; k++; } else {

if(k==0) {h=-h;t=t1;} else {

*a=tt1?t:t1; break; } }

t1=t0+h; f1=f(x,p,t1); }

}/*以下是黄金分割法程序源代码*/ double hjfg(double x[],double p[]) {

double beta,t1,t2,t; double f1,f2; double a=0,b=0; double *c,*d; c=&a,d=&b;

sb(c,d,x,p);/*调用进退法搜索区间*/

printf("\nx1=%f,x2=%f,p1=%f,p2=%f",x[0],x[1],p[0],p[1]); printf("\n[a,b]=[%f,%f]",a,b); beta=(sqrt(5)-1.0)/2;

t2=a+beta*(b-a); f2=f(x,p,t2); t1=a+b-t2; f1=f(x,p,t1); while(1) {

if(fabs(t1-t2)

{

t=(t1+t2)/2; b=t2; t2=t1;

f2=f1; t1=a+b-t2; f1=f(x,p,t1); } else {

a=t1; t1=t2; f1=f2;

t2=a+beta*(b-a); f2=f(x,p,t2); } } }

t=(t1+t2)/2; return t; }

/*以下是共轭梯度法程序源代码*/

void gtd() {

double x[N],g[N],p[N],t=0,f0,mod1=0,mod2=0,nanda=0; int i,k,n;

printf("请输入函数的元数值n=2"); scanf("%d",&n);

printf("\n请输入初始值:2,2");

for(i=0;i

g[0]=2*x[0]; g[1]=50*x[1];

mod1=sqrt(pow(g[0],2)+pow(g[1],2));/*求梯度的长度*/ if(mod1>0) {

p[0]=-g[0]; p[1]=-g[1]; k=0; while(1) {

t=hjfg(x,p);/*调用黄金分割法求t的值*/

printf("\np1=%f,p2=%f,t=%f",p[0],p[1],t);

x[0]=x[0]+t*p[0]; x[1]=x[1]+t*p[1]; g[0]=2*x[0]; g[1]=50*x[1];

/*printf("\nx1=%f,x2=%f,g1=%f,g2=%f",x[0],x[1],g[0],g[1]);*/ mod2=sqrt(pow(g[0],2)+pow(g[1],2)); /*求梯度的长度*/

if(mod2

if(k+1==n) {

g[0]=2*x[0]; g[1]=50*x[1]; p[0]=-g[0]; p[1]=-g[1]; k=0; } else {

nanda=pow(mod2,2)/pow(mod1,2);

printf("\nnanda=%f,mod=%f",nanda,mod2); p[0]=-g[0]+nanda*p[0]; p[1]=-g[1]+nanda*p[1]; mod1=mod2; k++; } }

printf("\n--------------------------"); } }

printf("\n最优解为x1=%f,x2=%f",x[0],x[1]); printf("\n最终的函数值为%f",f(x,g,t)); }

main() { gtd(); }

运行结果如下:

请输入函数的元数值n=2 请输入初始值:2 2

x1=2.000000,x2=2.000000,p1=-4.000000,p2=-100.000000 [a,b]=[-4.500000,1.500000]

p1=-4.000000,p2=-100.000000,t=0.020030 nanda=0.001474,mod=3.842730 --------------------------

x1=1.919879,x2=-0.003022,p1=-3.845655,p2=0.003665 [a,b]=[-4.500000,1.500000]

p1=-3.845655,p2=0.003665,t=0.499240 --------------------------

x1=-0.000026,x2=-0.001192,p1=0.000052,p2=0.059610 [a,b]=[-4.500000,1.500000]

p1=0.000052,p2=0.059610,t=0.020000 nanda=0.000000,mod=0.000050 --------------------------

x1=-0.000025,x2=-0.000000,p1=0.000050,p2=0.000001 [a,b]=[-4.500000,1.500000]

p1=0.000050,p2=0.000001,t=0.495505 --------------------------

x1=-0.000000,x2=0.000000,p1=0.000000,p2=-0.000023 [a,b]=[-4.500000,1.500000]

p1=0.000000,p2=-0.000023,t=0.020007 最优解为x1=-0.000000,x2=-0.000000 最终的函数值为0.000000

最优化课程设计

姓 名:指导老师:学 号:班 级:

题目:共轭梯度法

田鑫 智红英 [1**********]6

信息与计算科学111802班

共轭梯度法(Conjugate Gradient)

是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。 在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。

设我们要求解下列线性系统

其中n-×-n矩阵A是对称的(也即,AT = A),正定的(也即,xTAx > 0对于所有非0向量x属于Rn),并且是实系数的。 将系统的唯一解记作x*。 最后算法

经过一些简化,可以得到下列求解Ax = b的算法,其中A是实对称正定矩阵。

x0 := 0 k := 0 r0 := b

repeat until rk is "sufficiently small":

k := k + 1 if k = 1

p1 := r0 else

end if

xk := xk-1 + αk pk rk := rk-1 - αk A pk end repeat 结果为xk

共轭梯度法程序源代码

#include #include #define N 10

#define eps pow(10,-6)

double f(double x[],double p[],double t) {

double s;

s=pow(x[0]+t*p[0],2)+25*pow(x[1]+t*p[1],2); return s; }

/*以下是进退法搜索区间源程序*/

void sb(double *a,double *b,double x[],double p[]) {

double t0,t1,t,h,alpha,f0,f1; int k=0;

t0=2.5; /*初始值*/ h=1; /*初始步长*/ alpha=2; /*加步系数*/

f0=f(x,p,t0);

f1=f(x,p,t1); while(1) {

if(f1

h=alpha*h; t=t0; t0=t1; f0=f1; k++; } else {

if(k==0) {h=-h;t=t1;} else {

*a=tt1?t:t1; break; } }

t1=t0+h; f1=f(x,p,t1); }

}/*以下是黄金分割法程序源代码*/ double hjfg(double x[],double p[]) {

double beta,t1,t2,t; double f1,f2; double a=0,b=0; double *c,*d; c=&a,d=&b;

sb(c,d,x,p);/*调用进退法搜索区间*/

printf("\nx1=%f,x2=%f,p1=%f,p2=%f",x[0],x[1],p[0],p[1]); printf("\n[a,b]=[%f,%f]",a,b); beta=(sqrt(5)-1.0)/2;

t2=a+beta*(b-a); f2=f(x,p,t2); t1=a+b-t2; f1=f(x,p,t1); while(1) {

if(fabs(t1-t2)

{

t=(t1+t2)/2; b=t2; t2=t1;

f2=f1; t1=a+b-t2; f1=f(x,p,t1); } else {

a=t1; t1=t2; f1=f2;

t2=a+beta*(b-a); f2=f(x,p,t2); } } }

t=(t1+t2)/2; return t; }

/*以下是共轭梯度法程序源代码*/

void gtd() {

double x[N],g[N],p[N],t=0,f0,mod1=0,mod2=0,nanda=0; int i,k,n;

printf("请输入函数的元数值n=2"); scanf("%d",&n);

printf("\n请输入初始值:2,2");

for(i=0;i

g[0]=2*x[0]; g[1]=50*x[1];

mod1=sqrt(pow(g[0],2)+pow(g[1],2));/*求梯度的长度*/ if(mod1>0) {

p[0]=-g[0]; p[1]=-g[1]; k=0; while(1) {

t=hjfg(x,p);/*调用黄金分割法求t的值*/

printf("\np1=%f,p2=%f,t=%f",p[0],p[1],t);

x[0]=x[0]+t*p[0]; x[1]=x[1]+t*p[1]; g[0]=2*x[0]; g[1]=50*x[1];

/*printf("\nx1=%f,x2=%f,g1=%f,g2=%f",x[0],x[1],g[0],g[1]);*/ mod2=sqrt(pow(g[0],2)+pow(g[1],2)); /*求梯度的长度*/

if(mod2

if(k+1==n) {

g[0]=2*x[0]; g[1]=50*x[1]; p[0]=-g[0]; p[1]=-g[1]; k=0; } else {

nanda=pow(mod2,2)/pow(mod1,2);

printf("\nnanda=%f,mod=%f",nanda,mod2); p[0]=-g[0]+nanda*p[0]; p[1]=-g[1]+nanda*p[1]; mod1=mod2; k++; } }

printf("\n--------------------------"); } }

printf("\n最优解为x1=%f,x2=%f",x[0],x[1]); printf("\n最终的函数值为%f",f(x,g,t)); }

main() { gtd(); }

运行结果如下:

请输入函数的元数值n=2 请输入初始值:2 2

x1=2.000000,x2=2.000000,p1=-4.000000,p2=-100.000000 [a,b]=[-4.500000,1.500000]

p1=-4.000000,p2=-100.000000,t=0.020030 nanda=0.001474,mod=3.842730 --------------------------

x1=1.919879,x2=-0.003022,p1=-3.845655,p2=0.003665 [a,b]=[-4.500000,1.500000]

p1=-3.845655,p2=0.003665,t=0.499240 --------------------------

x1=-0.000026,x2=-0.001192,p1=0.000052,p2=0.059610 [a,b]=[-4.500000,1.500000]

p1=0.000052,p2=0.059610,t=0.020000 nanda=0.000000,mod=0.000050 --------------------------

x1=-0.000025,x2=-0.000000,p1=0.000050,p2=0.000001 [a,b]=[-4.500000,1.500000]

p1=0.000050,p2=0.000001,t=0.495505 --------------------------

x1=-0.000000,x2=0.000000,p1=0.000000,p2=-0.000023 [a,b]=[-4.500000,1.500000]

p1=0.000000,p2=-0.000023,t=0.020007 最优解为x1=-0.000000,x2=-0.000000 最终的函数值为0.000000


相关文章

  • 用最速下降法求解无约束非线性规划问题
  • 用最速下降法求解无约束非线性规划问题 摘要:无约束非线性规划问题是一类重要的数学规划问题.文主要研究了用最速下降法也就是梯度法对无约束非线性规划问题进行求解.对于一个无约束非线性规划利用最速下降法求解,首先需要确定其优化方向,此优化方向应该 ...查看


  • 请不要做个浮躁的人
  • 1. 把C++当成一门新的语言学习(和C 没啥关系!真的.): 2. 看++><Thinking In C,不要看<C++变成死相>: 3. 看<The C++ Programming Language> ...查看


  • 为何要学编程
  • 一.为何要学编程? 每个人的动机不一样.大致有: 1.为了找个好工作:或为了有更好的机会和更好的发展. 2.看到别人超厉害,所以也想学. 3.实际工作中很多场合需要. 4.从小就立志做个程序员,做软件工程师. 5.振兴中国的软件事业. .. ...查看


  • 高校学生综合测评管理系统的设计与实现说明书
  • 'i******************* 实践教学 ******************* 题 目:高校学生综合测评管理系统的设计与实现专业班级:姓 名:学 号:指导教师:成 绩:兰州理工大学 计算机与通信学院 2011年秋季学期 课程设 ...查看


  • C++课程设计任务书
  • <C++面向对象课程设计>任务书 一.课程设计目的与要求 1.课程设计目的 面向对象程序设计作为一门软件设计的课程,具有极强的实践性,必须使学生具备灵活应用理论知识的能力及面向对象程序设计技能.所以在<C++面向对象程序设 ...查看


  • 逆向 C -- 识别类及其构造函数 - FISH 的专栏 - CSDNBlog
  • 逆向 C++ 这些年来,逆向工程分析人员一直是凭借着汇编和 C 的知识对大多数软件进行逆向工程的,但是,现在随着越来越多的应用程序和恶意软件转而使用 C++语言进行开发,深入理解 C++ 面向对象方式开发的软件的反汇编技术就显得越发的必要. ...查看


  • 中南大学c++实践报告
  • 中南大学 本科生课程设计(实践)任务书.设计报告 (<计算机程序设计基础>C++) 题 目 图书馆藏书基本信息管理软件设计 学生姓名 李泽洲 指导教师 朱从旭 老师 学 院 地球科学与物理信息学院 专业班级 地质工程1403 学 ...查看


  • 2011上海专升本C++考试大纲
  • <C++程序设计>考试大纲 一.基本要求 1. 掌握C++语言的基本语法规则. 2.掌握程序设计的三种基本结构. 3.掌握函数.指针和结构体的基本知识及相关应用. 4.熟练掌握有关类与对象的相关知识. 5.能够采用面向过程和面向 ...查看


  • 软件公司入职面试笔试题(C++)
  • C++/C试题 本试题仅用于考查C++/C程序员的基本编程技能.内容限于C++/C常用语法,不涉及数据结构.算法以及深奥的语法.考试成绩能反映出考生的编程质量以及对C++/C的理解程度,但不能反映考生的智力和软件开发能力. 笔试时间90分钟 ...查看


热门内容