收藏 分销(赏)

牛顿法上机实验.doc

上传人:s4****5z 文档编号:8941378 上传时间:2025-03-08 格式:DOC 页数:9 大小:5.53MB 下载积分:10 金币
下载 相关 举报
牛顿法上机实验.doc_第1页
第1页 / 共9页
牛顿法上机实验.doc_第2页
第2页 / 共9页


点击查看更多>>
资源描述
设计性实验报告 课程名称: 最优化 实验名称: 牛顿法 实验地点: 指导老师: 实验时间: 提交时间: 班级: 姓 名: 座号: 一、实验目的和要求 [1] 掌握非线性方程的极小点基本求解算法; [2] 通过实例掌握用MATLAB或C语言求非线性方程的极小点方法; [3] 编程实现2种或以上算法并进行比较掌握牛顿法原理,并能够用 程序实现 二、实验环境、内容和方法 1.写出非线性方程的极小点基本求解算法的程序框架 2.用C语言或matlab编写实现所设计算法 3. 构造一个非线性方程,用所设计的程序实现,比较各个算法的迭代速度,求解的精度,运行的时间。另改变初值,分析初值对解的影响。 4. 可采用二分法,Newton迭代,黄金分割法。 编制程序,用牛顿迭代法、二分法、黄金分割法三种不同的方法求解函数 的最优解。 求解区间为 [-8,8] 解法一:二分法 在C++ 软件中输入如下程序: #include<iostream> using namespace std; double f(double x) { return x*x*x*x-4*x*x*x-6*x*x-16*x+4; }; int main() { double left=-8; double right=8; double mid; while((right-left)>0.005) { mid=(left+right)/2; if(f(mid)==0) break; if((f(mid)*f(left))>0) left=mid; else right=mid; }; cout<<mid<<endl; system("pause"); return 0; } 运行程序的结果为: 我们知道,在极小点处,并且当时,函数时递减的,即;而当时,函数递增,即。如果找到一个区间,具有性质,,则在之间必有的极小点,并且。 为了找到,我们取,若,则在区间中有极小点。这时以作为新的区间;若,则在中有极小点,因此以作为新的区间。继续这个过程,逐步将区间换小,当区间充分小时,即可取到极小点的近似。 解法二:牛顿迭代法 在C++ 软件中输入如下程序: #include<iostream.h> #include <math.h> #define eps 0.01 double fun(double x) { return x*x*x*x-4*x*x*x-6*x*x-16*x+4; } double diff_fun(double x) { return 4*x*x*x-12*x*x-12*x-16; } double diff_2_fun(double x) { return 12*x*x-24*x-12; } double diff_3_fun(double x) { return 24*x-24; } double newton(double a,double b) { double result = (a+b)/2; double t = 0.0; while(true) { t = result - (diff_fun(result)/diff_2_fun(result)); if(fabs((t-result)) < eps) { return result; } else { result =t; } } } int main() { double a =0.0; double b =6.0; double x= newton(a,b); cout<<"求解的结果是 x = "<<x<<endl; cout<<"此时f(x) = "<<fun(x)<<endl; return 0; } 输出程序得到方程的最优解为: 当输入初值为,当=-156时,求出此时方程的根为=4.00066。我们知道输入不同的初值,在不同的迭代次数得到方程的解是不一样的。由于牛顿法是一种函数逼近法,它的基本思想是,在迭代点附近用二阶泰勒多项式近似目标函数,进而求出极小点的估计值。在一定条件下,这个点列收敛于最优解且具有二阶收敛速度。 运用牛顿法时,初值点的选择显得十分重要。如果初始点靠近极小点,则收敛可能很快;如果收敛点原理极小点,则迭代产生的点列还有可能不收敛于极小点。 解法三:黄金分割法 在C++软件中输入如下程序: #include <iostream.h> #include <math.h> double f(double x);//函数声明 //主函数 void main() { double a=-8,b=8,e=0.01; double x1=0,x2=0,x3=0,f1=0,f2=0,f3=0; x1=a+0.382*(b-a); x2=a+0.618*(b-a); f1=f(x1); //调用f函数 f2=f(x2); //调用f函数 //在没有达到误差限情况下就循环 while(fabs(a-b)>=e) { if(fabs(f1-0)<fabs(f2-0)) { b=x2; x2=x1; f2=f1; x1=a+0.382*(b-a); f1=x1*x1*x1*x1-4*x1*x1*x1-6*x1*x1-16*x1+4; } else { a=x1; x1=x2; f1=f2; x2=a+0.618*(b-a); f2=x2*x2*x2*x2-4*x2*x2*x2-6*x2*x2-16*x2+4; } x3=(a+b)/2; f3=f(x3); } cout<<"方程为:"<<"f(x)=x*x*x*x-4*x*x*x-6*x*x-16*x+4"<<endl; cout<<endl; cout<<"误差限为:e=0.01"<<endl; cout<<endl; cout<<"方程的根为: x="<<x3<<endl; cout<<endl; cout<<"方程的值为:f="<<f3<<endl; cout<<endl; } //定义函数 double f(double x) { double y; y=x*x*x*x-4*x*x*x-6*x*x-16*x+4; return y; } 结果如下图所示: 0.618法适用于单峰函数,即在所论区间[a,b]上,函数只有一个极小值点 在极小值得左边,函数单调下降;在极小值得右边,函数单调上升。但在实际问题中,目标函数在其定义域内不一定是单峰的,因此需要先确定单峰区间,然后再使用0.618法的计算公式。在现有的0.168法的程序中,一般具有的这种功能。 四、心得体会 通过此次的设计性实验,让我通过运用牛顿迭代法、二分法以及黄金分割法解决非线性方程。 让我明白了三种方法的区别和联系,根据不同题目我们可以采用不同的方法。 同时,我也更深刻地了解 三种方法。在以后的解题中,更灵活地 五、教师评语 9
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服