一维搜索:二分法

本文详细介绍了二分法求解函数零点的过程及MATLAB实现,包括算法步骤、代码示例及其运行结果对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二分法是用来求函数零点的方法,如果函数可导,那么函数的一阶导的零点就是原函数的极值点。但是如果原函数没有极值点,比如一个单调函数,其最值在某一端点。这样求导后就不满足二分法求零点的条件。

1.二分法算法步骤:

  • (1) 初始化搜索区间[x1,x2][x1,x2]均值 xm=0.5(x1+x2)xm=0.5(x1+x2), 给定精度要求 ϵ>0ϵ>0, 计算导数f=dfdxf′=dfdx;
  • (2) 如果|x1x2|<ϵ|x1−x2|<ϵ算法结束。如果fx1×fxm>0fx1′×fxm′>0, 转到步骤(3),如果fx1×fxm<0fx1′×fxm′<0,转到步骤(4)。如果fx1×fxm=0fx1′×fxm′=0xmxm即为结果,算法结束;
  • (3) 置x1=xmx1=xm,转步骤(5);
  • (4) 置x2=xmx2=xm,转步骤(5);
  • (5) 置xm=0.5(x1+x2)xm=0.5(x1+x2),转步骤(2);

1.二分法代码MALTAB实现:
测试函数:

clc,clear
f = @(x) 2*x.^2 - x - 1; %原函数
df = @(x)4*x - 1;       %一阶导数
a = -3;
b = 0.25;
epsilon = 1e-4;
tic
res = binarySearch(df,a,b,epsilon)
toc
% 符号函数实现
func = sym('2*x^2 - x - 1');
tic
res1 = binarySearch1(func,a,b,epsilon)
toc

传函数句柄方式:

% binarySearch 二分法
%   - 优点:计算量少,而且总能收敛到一个局部极小点,不需要计算导数
%   - 缺点:收敛速度慢,需要函数可导
% Inputs:
%   - df      函数的一阶导数
%   - a       搜索区间下限
%   - b       搜索区间下限
%   - epsilon 精度:用区间长度衡量
% Outputs:
%   -res      搜索结果 
function res = binarySearch(df,a,b,epsilon)
% 检查输入
if df(a)*df(b) > 0 
    display('BinarySearch: 二分法区间端点值同号……'); 
    return; 
end
%初始化
x1 = a;
x2 = b;
mean = 0.5*(x1 + x2);
%计算
while(true)
%     state = [x1 x2]
    if(abs(x1-x2)<epsilon) break; end
    if(df(x1)*df(mean) > 0) 
        x1 = mean;
    elseif(df(x1)*df(mean) < 0)
        x2 = mean;
    elseif(df(x1)*df(mean) == 0)
        res = mean; break;
    end
    mean = 0.5*(x1 + x2);
end
res = 0.5*(x1 + x2);
end

传符号函数方式:

% binarySearch 二分法
%   - 优点:计算量少,而且总能收敛到一个局部极小点,不需要计算导数
%   - 缺点:收敛速度慢
% Inputs:
%   - func    原函数的符号函数
%   - a       搜索区间下限
%   - b       搜索区间下限
%   - epsilon 精度:用区间长度衡量
% Outputs:
%   -res      搜索结果 
function res = binarySearch1(func,a,b,epsilon)
df = diff(func);
% 检查输入
if subs(df,a)*subs(df,b) > 0 
    display('BinarySearch: 二分法区间端点值同号……'); 
    return; 
end
%初始化
x1 = a;
x2 = b;
mean = 0.5*(x1 + x2);
%计算
while(true)
%     state = [x1 x2]
    if(abs(x1-x2)<epsilon) break; end
    if(subs(df,x1)*subs(df,mean) > 0) 
        x1 = mean;
    elseif(subs(df,x1)*subs(df,mean) < 0)
        x2 = mean;
    elseif(subs(df,x1)*subs(df,mean) == 0)
        res = mean; break;
    end
    mean = 0.5*(x1 + x2);
end
res = 0.5*(x1 + x2);
end

结果如下图(函数句柄的方式比符号函数方式计算速度快很多):
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值