二分法、试位法、不动点迭代法、牛顿法、割线法

2023-10-09 10:32

本文主要是介绍二分法、试位法、不动点迭代法、牛顿法、割线法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

二分法、试位法、不动点迭代法、牛顿法、割线法

    • 问题回顾
    • 问题分析
    • 1.二分法
    • 2.试位法
    • 3.不动点迭代
    • 4.Newton-Raphson法
    • 5.割线法
    • 小结

问题回顾

一段质量均匀分布的电缆线悬挂在两点之间,构成一段悬链,其满足如下微分方程:

在这里插入图片描述

问题分析

在这里插入图片描述

1.二分法

首先确定有根区间,将区间二等分,通过判断f(x)的符号,逐步将有根区间缩小,直至有根区间足够地小,便可求出满足精度要求的近似根。通过悬链最低点张力的唯一性,可以确定该区间只有一个根。

用 (xl,xr)来表示我们所感兴趣的根,初始为(1000,1500),MATLAB脚本程序如下,保留10位有效数字。

clear;
x_l = 1000; % the initial value of the left bound of x is 1000
x_r = 1500; % the initial value of the right bound of x is 15000
x_m = mean([x_l,x_r]); % x_m is the mean value of the two bounds
x_g = 0; % x_g is the target value of the Bolzano method
e_a = 5e-11;  
i = 0;
if f(x_l)*f(x_r)>0error('invalid input');
else
while (abs(x_g-x_m)/x_m>e_a) % tolerance of accuracy
if f(x_m)==0                 % find the accurate rootbreak;
elseif f(x_l)*f(x_m)<0x_r = x_m;               % update the new estimation to the intervalelsex_l = x_m;end
end
x_g = x_m; 
x_m = mean([x_r,x_l]);
i = i + 1;
end
end
fprintf('x = %.17f  i = %d\n', x_m, i);

程序输出为

x = 1266.32436044747009873 i = 32

本例中用了 32 次迭代达到了保留10位有效数字的计算准则。下面用图表示出迭代过程。

在这里插入图片描述

2.试位法

与二分法不同,每次区间的划分点不在中点,而是两区间函数值点连线与 x 轴的交点, 递归地做这样的划分求解最终的结果,图示结果附后。

clear;
x_l = 1000; % the initial value of the left bound of x is 1000
x_r = 1500; % the initial value of the right bound of x is1500
x_c = x_r; % x_c is the cross point of the two bound and the x-axis
x_t = 0; % x_t is the target ROOT of the eqation
e_a = 5e-11; 
i = 0; % iteration tag
while (abs(x_t-x_c)/x_c>e_a)x_t=x_c; % update the target value with the cross pointif f(x_t)==0break;elsex_c = x_r - f(x_r)*(x_l-x_r)/(f(x_l)-f(x_r)); if f(x_c)*f(x_r)<0x_l = x_c;elsex_r = x_c;endendi = i+1;
end
fprintf('x = %.17f  i = %d\n', x_c, i);

程序输出为

x = 1266.32436040640868669 i = 16

本例中用了 16 次迭代达到了保留10位有效数字的计算准则。下面用图表示出迭代过程。

在这里插入图片描述

根据计算结果可以看到,此例中试位法较二分法更为快速地收敛到了想要的解,且并也已经出现“一个划界点保持不动”的现象。

3.不动点迭代

在这里插入图片描述

clear;
x_t = 1000;	% the initial is 1000
x_c = 0;
e_a = 5e-11;
for i=1:1000  		 % iteration tagx_c = f(x_t) + x_t;if(abs(x_c-x_t)/x_c<e_a) % tolerance of accuracybreak;endx_t = x_c;
end
fprintf('x = %.17f  i = %d\n', x_c, i);

程序输出为

x = 1266.32436009672028376 i = 115

本例中用了 115 次迭代达到了小数点后 10 位有效数字的计算准则。下面用图表示出迭代过程。

在这里插入图片描述

4.Newton-Raphson法

在这里插入图片描述

clear;
x_t = 1000; % the initial is 1000
x_c = 0;
e_a = 5e-11;
for i=1:1000	% iteration tagx_c = x_t-f(x_t)/df(x_t);if(abs(x_c-x_t)/x_c<e_a) % tolerance of accuracybreak;endx_t = x_c;
end
fprintf('x = %.17f  i = %d\n', x_c, i);

程序输出为

x = 1266.32436039988829179 i = 5
在这里插入图片描述

5.割线法

在这里插入图片描述

clear;
x_t = 1000; % the initial value of the second bound of x is 1000
x_r = 1500; % the initial value of the first bound of x is 1500
x_c = 0;
e_a = 5e-11; 
i = 0; % iteration tag
while (abs(x_r-x_t)/x_t>e_a)x_c=x_t-f(x_t)*(x_t-x_r)/(f(x_t)-f(x_r)); % update the target if f(x_c)==0break;elsex_r = x_t; x_t = x_c;endi = i+1;
end
fprintf('x = %.17f  i = %d\n', x_c, i);

程序输出为

x = 1266.32436039988601806 i = 7

在这里插入图片描述

小结

本文由实际问题出发,按照题目要求的五种方法分别解了一个非线性的方程,作图比较了五种方法的收敛速度,并用每种方法都得到了最终的结果(有十位有效数字),x = 1266.324360,即悬链最低点的张力为1266.324360。

下面列表总结一下每种方法得到结果的情况:

方法名称初始估计 1初始估计 2迭代次数
二分法1000150032
试位法1000150016
不动点迭代1000\115
Newton-Raphson法1000\5
割线法100015007

二分法是最简单的方法,且易于在计算机上实现,对函数的条件要求也很低,只要求在有根区间上连续。缺点就是收敛速度较慢,本次实验进行了32次迭代得到结果,与公比为1/2的等比数列收敛速度相同。因此一般不单独使用,常用来为其他方法提供初值区间。

试位法作为二分法的改进,并不是单一的二分区间,而是利用区间两个端点的线性插值来求一个近似根,因此在大多数情况下优于二分法,收敛速度相对于二分法更快。但在实际计算中,如果区间内一阶导数值突然增长,函数图像有极大拐弯,且方程的根更靠近导数大的一侧,情况将会变得非常糟糕,出现“一个划界点保持不动”的现象,此时收敛速度会慢于二分法。本题中没有出现上述情况,进行了16次迭代后得到了结果。

为了减轻上述情况带来的影响,可以对试位法做出如下改进。如果一个端点重复两次或更多次作为新的含根区间的端点,我们将这个点的函数值乘以一个大于0小于1的常数因子w,比如可以取0.5,将停滞的边界点处的函数值变为原来的一半,能够使线性插值的根更接近于精确根。更加符合“试位”的思想。

不动点迭代法与前两种方法不同,只需要一个初始估计值。这种方法收敛较慢,本次实验迭代了115次才得出了最终结果。对初值的要求较高,需要提供较为近似的初始值x0.大多数情况下需要考虑迭代法的局部收敛性,在方成根的附近取初值。不动点迭代法是迭代法的基础,是一种一般性的方法,对研究方程解的存在性、唯一性和具体计算有重要的理论与实用价值。

Newton-Raphson法是经不动点迭代法变形而来的,是迭代法“收敛性”意义上的最优进化。牛顿法的速度很快,本次实验只用了5次迭代就得到了满足要求的解。它的最大优点是方程在单根附近有较高的收敛速度,且算法逻辑简单。但是由于牛顿法是局部收敛的,对初始估计的要求很高,如果没有估计合适,将会产生很差的结果,甚至无法得出答案。此外,牛顿法的每次迭代除了要计算函数值以外,还需要计算导数值,在导数较为复杂时,该方法会比较麻烦。

割线法是牛顿法和试位法的改进。类似于牛顿法,都是用差商估计斜率,但使用了两点的割线,避开了复杂的导数运算。采用两点投射到x轴上得到新的估计值的方法与试位法较为相似,但是初始估计不用界定根。收敛速度在中等到快,本次实验经过7次迭代后得到了结果。

对初始估计的要求很高,如果没有估计合适,将会产生很差的结果,甚至无法得出答案。此外,牛顿法的每次迭代除了要计算函数值以外,还需要计算导数值,在导数较为复杂时,该方法会比较麻烦。

割线法是牛顿法和试位法的改进。类似于牛顿法,都是用差商估计斜率,但使用了两点的割线,避开了复杂的导数运算。采用两点投射到x轴上得到新的估计值的方法与试位法较为相似,但是初始估计不用界定根。收敛速度在中等到快,本次实验经过7次迭代后得到了结果。

总而言之,不同的求解方法各有千秋,我们需要结合实际问题来选择恰当的方法。

这篇关于二分法、试位法、不动点迭代法、牛顿法、割线法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/172228

相关文章

图的割点、割线问题

图的割点问题 邻接矩阵表示图 package com.hyl.algorithm.other;import java.util.Arrays;import com.hyl.algorithm.search.base.SearchIntf;import com.hyl.algorithm.search.base.SearchIntfFactory;/*** 寻找图的割点* <p>** @aut

数据结构基础之《(3)—二分法》

一、认识二分法 1、经常见到的类型是在一个有序数组上,开展二分搜索 2、但有序真的是所有问题求解时使用二分的必要条件吗?不 3、只要能正确构建左右两侧的淘汰逻辑,你就可以二分 二、二分法怎么用 1、在一个有序数组中,找某个数是否存在 public static boolean exist(int[] sortedArr, int num) {if (sortedArr == null |

Kotlin 二分法算法游戏--猜价格

本人最新想学习算法,算法是提高程序性能的关键! 程序就是数据结构和算法! 写了一个二分法的游戏,供大家参考: 当然,语言基于kotlin import java.util.*/*** Created by Administrator on 2017/10/18.*/fun main(args: Array<String>) {// println("请输入商品真实价格")//

点云配准之ICP和NDT算法的高斯牛顿法求解

ICP算法 NDT算法 代码:https://github.com/taifyang/pointcloud-registration 参考:高翔《自动驾驶与机器人中的SLAM技术》

GNN-2008:Original GNN【消息传递(前向传播):聚合函数+更新函数+输出函数】【核心:不动点理论】【梯度优化:用Almeida-Pineda算法,而不是用BPTT(反向传播)算法】

GNN-2008:Original GNN【消息传递(前向传播):聚合函数+更新函数+输出函数】【核心:不动点理论】【梯度优化:用Almeida-Pineda算法,而不是用BPTT(反向传播)算法】 《原始论文:A new model for learning in graph domains-2005》 《原始论文:The Graph Neural Network Model-2008》 一

【机器人学导论】6自由度机械臂逆运动学求解—牛顿法(数值法,仅旋转关节)

我以前是机器人专业,不过学的不多,教程应该是灰色封面的《机器人学导论》。3年前学的了,软件仿真学的是ABB,上手操作是KUKA的机器人。本文是给别人解决问题的记录,写个笔记。代码是matlab的,不免费分享,但是看我的解析应该也能自己写出来。我不从事这个行业,很多东西已经模糊了。 文章目录 一、DH参数二、正向运动学三、逆向运动学3.1 逆向运动学的求解方法:3.11 解析法(Ana

二分法变种

package compublic class Test {public static void main(String[] args) {int[] nums = {4,7,7,9,12,13};int index = searchLastSmaller(nums,1);System.out.println(index);}/** 第一个与key相等的元素*/public static int

python基础-递归、二分法查找(for\递归)、三级菜单、压栈思想

递归方法二分法查找 通过for循环实现通过递归实现 递归应用–三级菜单压栈 递归方法 # age(1) n = 1 age(2)+2# age(2) n = 2 age(3)+2# age(3) n = 3 age(4)+2# age(4) n = 4 40def age(n):if n == 4:return 40return age(n+1)+2print

559. N 叉树的最大深度(迭代法)

目录 一:题目: 二:代码: 三:结果: 一:题目: 给定一个 N 叉树,找到其最大深度。 最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。 N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。 二:代码: /*// Definition for a Node.class Node {public:int val;vector<N

5、梯度下降法,牛顿法,高斯-牛顿迭代法

1、梯度下降     2、牛顿法         3、高斯-牛顿迭代法     4、代码部分 1.梯度下降法代码 批量梯度下降法c++代码: /*需要参数为theta:theta0,theta1目标函数:y=theta0*x0+theta1*x1;*/#include <iostream>using namespace std;int main()