二分法基本思想
利用连续函数零点定理,将含根区间逐次减半缩小的方式构造点列来逼近根。
二分法步骤
Step1: 计算 f(x) 在有根区间 [a, b] 端点处的值 f(a) 和 f(b)
如何判断有根?可以根据零点定理,若 f(x)∈C[a, b] ,且 f(a) f(b) < 0
Step2: 计算 f(x) 在区间中点 (a+b)/2 处的数值 f((a+b)/2)
开始二分
Step3:判断 f((a+b)/2) 是否等于0,如果是,则根就是 (a+b)/2 ,计算过程结束,否则继续
提前满足条件就完事了!这一步用我们老师的话来说就是瞎猫碰着死耗子,如果 f((a+b)/2) = 0,可以就此打住,因此这一步不能省!
Step4:判断 f((a+b)/2) f(a) 是否小于0,如果是,则用 (a+b)/2 代替 b ,否则就用 (a+b)/2 代替 a
进一步缩小区间
Step5:判断区间[a, b]的长度是否小于允许误差,如果满足条件,则上一步得到的 (a+b)/2 即为所求的近似根,否则继续循环 Step2~Step5
由于二分法只能求解根的近似值,如果不设定循环求近似解的终止条件的话会一直求解下去
程序框图
题目要求和初步分析
题目1
用二分法求方程 x 2 − x − 1 = 0 x^2-x-1=0x2−x−1=0 的正根,要求误差小于0.05。
分析1
首先令 f ( x ) = x 2 − x − 1 = 0 f(x) = x^2-x-1=0f(x)=x2−x−1=0,将方程求根问题转为函数求零点的问题。
接着根据正根的性质,初步选定一个区间 [1, 2],然后验证是否存在零点:
f(1) = -1 < 0,f(2) = 1 > 0,f(1) f(2) < 0,则 [1, 2] 存在零点,可继续进行二分法求解。
Matlab 代码1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 简介:用二分法求方程x^2-x-1=0的正根,要求误差小于0.05 % 作者:不雨_亦潇潇 % 文件:dichotomy.m % 日期:20221009 % 博客:https://blog.csdn.net/weixin_43470383/article/details/127222948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clc; clear all; syms x % 定义变量 f = @(x) x^2 - x -1; % 求解方程 a = 1; b = 2; % 初始的区间上下限 n = 0; % 迭代次数 w = 0.05; % 误差要求 while f(a) * f(b) < 0 % 存在根 x_0 = (a+b)/2 % 计算中点,开始二分 if f(x_0) == 0 % 零点即中点 break; end if f(a) * f(x_0) < 0 % 零点在左边的区间 b = x_0; else % 零点在右边的区间 a = x_0; end n = n+1 if abs(a - b) < w % 判断是否满足精度条件 x_0 % 最终得到的近似解 n = n+1 % 迭代总次数 break; end end
运行结果1
x_0 = 1.5000
n = 1
x_0 = 1.7500
n = 2
x_0 = 1.6250
n = 3
x_0 = 1.5625
n = 4
x_0 = 1.5938
n = 5
x_0 = 1.5938
n = 6
第6次迭代时abs(a - b)=1.625-1.5938<0.05,满足条件
最终求得的根为 1.5938
题目2
用二分法求方程 e x p ( x ) + 10 ∗ x − 2 = 0 exp(x) + 10*x -2=0exp(x)+10∗x−2=0 的根,要求根有3位小数。
Matlab代码2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 简介:用二分法求方程exp(x) + 10*x -2=0的根,要求根有3位小数 % 作者:不雨_亦潇潇 % 文件:dichotomy1.m % 日期:20221010 % 博客:https://blog.csdn.net/weixin_43470383/article/details/127222948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clc; clear all; syms x % 定义变量 f = @(x) exp(x) + 10*x -2; % 求解方程 a = 0; b = 1; % 初始的区间上下限 n = 0; % 迭代次数 w = 0.5*power(10, -3); % 误差要求 while f(a) * f(b) < 0 % 存在根 x_0 = (a+b)/2 % 计算中点,开始二分 if f(x_0) == 0 % 零点即中点 break; end if f(a) * f(x_0) < 0 % 零点在左边的区间 b = x_0; else % 零点在右边的区间 a = x_0; end n = n+1 if abs(a - b) < w % 判断是否满足精度条件 x_0 % 最终得到的近似解 n = n+1 % 迭代总次数 break; end end
运行结果2
x_0 =
0.5000
n =
1
x_0 =
0.2500
n =
2
x_0 =
0.1250
n =
3
x_0 =
0.0625
n =
4
x_0 =
0.0938
n =
5
x_0 =
0.0781
n =
6
x_0 =
0.0859
n =
7
x_0 =
0.0898
n =
8
x_0 =
0.0918
n =
9
x_0 =
0.0908
n =
10
x_0 =
0.0903
n =
11
x_0 =
0.0903
n =
12