(二分法进阶)三分法超详解

在使用二分法时必须保证数列是有序的,因此对应到数学问题上实际上解决的是单调函数的求解问题。通过二分法查找其中一个元素key,则转换为数学问题求f(x)=key的解。

但是一旦数列不是单调的,那么二分法就无法使用了,因为循环判断中不能确定左右区间的划分,于是对于函数有凹凸性的情况,便引入了三分法的使用场景。

欲求某个函数的极值点及极值,将区间[l,r]分为三部分,需要两个分界点m1和m2,如下
在这里插入图片描述
在这里插入图片描述
根据上述函数图像观察到f(m1)>f(m2),即m2离极小值点更近,为了让区间不断趋近极小值点,r不动,将l趋向m1,所以有l=m1。

在这里插入图片描述
在这里插入图片描述
当f(m1)<f(m2),即m1点离极小值点更近,此时缩小区间则应让l不动,r趋近到m2,有r=m2

若f(m1)=f(m2)则同理,为了简化代码,我们在这里将相等的情况与小于的情况合并

这里我们求函数的极小值即极小值点来试试,代码如下:

 /**
     * 函数方程(可自己定义)
     * @param x
     * @return
     */
private static double function(double x){
        return x*x+3*x+6;
    }

    /**
     * 三分法
     * @param l:区间左边界
     * @param r:区间右边界
     * @return   极值点的位置
     */
    private static double tripleSearch(double l,double r){
        while(l+EIS<r){           //EIS=10e-6,即10的-6次方;  因为所有参数为双精度型,不能直接用l<r
            double mid1=(l+r)/2;
            double mid2=(mid1+r)/2;
            if(function(mid1)<=function(mid2)){
                 r=mid2;
            }else {
                l=mid1;
            }
        }
        return l;
    }

main函数:

 public static void main(String[] args) {
        System.out.println(String.format("%.2f",tripleSearch(-2,1)));
        System.out.println(String.format("%.2f",function(tripleSearch(-2,1))));
    }

运行结果如下,经过验算,正确,over!
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值