[计算机数值分析]牛顿下山法求方程的根
问题描述
一般来说,牛顿法的收敛性依赖于初值 x₀ 的选取,如果 x₀ 偏离方程的正解根 x* 较远,则牛顿法可能发散。
例:用牛顿法求方程 x³ - x - 1 = 0在 x = 1.5 附近的一个根。
取迭代初值 x₀=1.5,应用牛顿公式 x′ = x₀ - (x₀³ - x₀ - 1) / (3x² - 1), 计算结果如下:x₁ = 1.34783, x₂ = 1.32520, x₃ = 1.32472,其中 x₃ 的每一位数字都是有效数字。
但是,如果改用 x₀ = 0.6 作为初值,则按照牛顿公式迭代一次得 x₁ = 17.9,这个结果反而比 x₀ 更偏离了所求得根。
为了防止迭代发散,通常对迭代过程再附加一项要求,即保证函数值单调下降,满足这项要求的算法称为下山法。
将牛顿法与下山法结合起来使用,即在下山法保证函数值稳定下降的前提下,用牛顿法加快收敛速度。
为此,将牛顿法的上一次迭代初值与本次迭代值进行适当加权平均后作为新的改进值,我们有理由相信,加权后的改进值是比未改进前的近似根更好的的根,它更好地逼近了真实解。即使新的改进值 x₁′ = λx₁ + (1 - λ)x₀。
其中λ称为下山因子,适当选择下山因子可以使函数满足单调下降条件。下山因子的选取是一个逐步探索的过程,从 λ = 1 开始反复将因子 λ 的值减半进行试算,一旦单调性条件成立,则 “下山成功”,否则 “下山失败”。若 “下山失败”,这时则需另选初值 x₀ 重算。
如前有例子描述,当选取初值 x₀ = 0. 6时,如果取下山因子 λ = 1 / 32,则可求出 x₁ = 1.140625,这个结果纠正了原有的严重偏差。
运行示例
源码
#include<iostream>
#include<cmath>
using namespace std;double f(double x); //f(x)为需要求解方程的对应函数
double f1(double x); //f1(x)为f(x)的一阶导数int main(void)
{double accuracy, N; //accuracy为精度;N为最大迭代次数;double x0, x1; //x0为运用牛顿法时选取的初值;x1为迭代初值的下一次迭代值int count; //count为当前迭代次数cout << "请输入迭代初值:";cin >> x0;cout << "请输入精度:";cin >> accuracy;cout << "请输入最大迭代次数:";cin >> N;count = 0;do{count++; //迭代次数自增1if (count > N) //迭代次数达到限制{cout << "达到允许的最大迭代次数!迭代结束!" << endl;break;}if (f1(x0) == 0) //不符合牛顿法求根条件,无法求根{cout << "在x0附近f(x)的一阶导数值为0!不适用牛顿法求方程的根!" << endl;;break;}else{double L = 1;x1 = x0 - L * f(x0) / f1(x0); //迭代一次while (abs(f(x1)) >= abs(f(x0))) //函数值未单调下降,控制下山因子的大小使得单调性条件得到满足,若不满足,则换初值重算{L /= 2;x1 = x0 - L * f(x0) / f1(x0); //应用下山因子对迭代值进行改进}cout << "\n下山因子L = " << L << endl;cout << "第" << count << "次迭代,方程的近似根为:" << x1 << endl;//交换x0与1的值,便于进行下一次迭代double temp;temp = x1;x1 = x0;x0 = temp;}} while ((abs(x1 - x0) > accuracy));return 0;
}double f(double x) //原函数
{double result = pow(x, 3) - x - 1;return result;
}double f1(double x) //导函数
{double result = 3 * pow(x, 2) - 1;return result;
}
[计算机数值分析]牛顿下山法求方程的根相关推荐
- Matlab数值分析编程:牛顿下山法解方程
%通用代码 fun=inline('x^0.5-x^3+2','x');%手动输入函数表达式和自变量 dfun=inline('0.5*x^(-0.5)-3*x^2','x');%手动输入函数一阶导数 ...
- 牛顿法和牛顿下山法求极值的理解
泰勒展开 先创建一个不太方便求解的方程sinx=−0.01ex\sin x=-0.01e^xsinx=−0.01ex,并用matlab画出来y=sinx+0.01exy=\sin x+0.01e^ ...
- 二分法+牛顿迭代法+简化牛顿迭代法+牛顿下山法解方程的近似值
1.二分法 //求方程 2*x*x*x-4*x*x+3*x-6 的根 /* 二分法*/ #include<stdio.h> #include<math.h> #define E ...
- 牛顿法及牛顿下山法求零点
牛顿法 difffun该函数的导函数 a在a附近求零点 ep容忍误差 k迭代次数 function [x_star,k]=MyNewton(fun,difffun,a,ep)k=1 x_k=a f_x ...
- 用弦截法求方程的根matlab,matlab 语言 用弦截法任意实数方程求实根
满意答案 dwgg2n0das8 2013.04.26 采纳率:45% 等级:12 已帮助:8202人 弦截法这个方法一般用作学习,实际用的很少.这里我提供一个较完整的弦截法求根的函数.func ...
- 4.9 数值分析: 牛顿下山法
本文内容为东北大学数值分析国家精品慕课课程的课程讲义, 将其整理为OneNote笔记同时添加了本人上课时的课堂笔记, 且主页中的思维导图就是根据课件内容整理而来, 为了方便大家和自己查看,特将此上传到 ...
- 计算方法/数值分析牛顿下山法C/C++实现方法
一.前言(吐槽) 我真的不知道该说些什么好,其实也怪自己.老师将实验发下来,然后我就跟这着老师的实验任务做,实验word上用的什么流程图我就用那个流程图,然而我根据老师的流程图遍完了程序,怎么验算结果 ...
- 弦截法c语言求方程XeX-1=0的解,编程用弦截法求方程 f(x)=3x^3-5x^2+16x-60=0的根
满意答案 w6297281 2013.08.26 采纳率:52% 等级:12 已帮助:8785人 希望下面的资料对你有帮助: 弦截法求方程的根是一种解方程得基本方法,在计算机编程中常用.他的思路 ...
- matlab求方程实根,matlab怎么求方程的根
MATLAB解方程_IT/计算机_专业资料.一般的代数方程函数solve用于求解一般代数方程的根,假定S为符 号表达式,命令solve (S)求解表达式等于0的根,也 可以再输入一个...... MA ...
最新文章
- 理解jQuery对象$.html
- Java常用消息队列原理介绍及性能对比
- poj3254 Corn Fields
- [转载] 手工制作Win7 OEM版
- 扬长避短使用Windbg和Visual Studio高效调试调试你的代码
- ODBC、OLEDB、ADO的区别和联系
- iis自带的ftp服务器权限设置方法,IIS ftp 权限控制
- C++_指针的定义使用_指针所占内存空间_空指针_野指针---C++语言工作笔记023
- Lua中强大的元方法__index详解
- opcache引起的“php-cgi.exe - FastCGI 进程意外退出”,事件ID487
- PHP自定义状态码数组
- 《银联提交服务单》-业务流程
- vw、vh、vmin、vmax 的含义
- Linux网络流量监控
- Crystal Reports(水晶报表)安装及拉(PULL)模式/推(PUSH)模式的使用
- Redis常见面试题整理
- linux内部网关协议igp,在自治系统内部的各个路由器之间,运行的是内部网关协议IGP。早期的IGP叫做【11】 ,它执行 【12】 。_考题宝...
- SuperMap BIM+GIS-Revit模型处理-背景
- redis的发布订阅缺陷
- qt 引发了异常: 写入访问权限冲突。this 是 0x7FF700000000。