zoukankan      html  css  js  c++  java
  • 转:三分搜索法

    三分搜索法

      二分法作为分治中最常见的方法,适用于单调函数,逼近求解某点的值。但当函数是凸性函数时,二分法就无法适用,这时三分法就可以“大显身手”~~

     


           如图,类似二分的定义Left和Right,mid = (Left + Right) / 2,midmid = (mid + Right) / 2; 如果mid靠近极值点,则Right = midmid;否则(即midmid靠近极值点),则Left = mid;

    程序模版如下:

    double Calc(Type a)
    {
        /* 根据题目的意思计算 */
    }

    void Solve(void)
    {
        double Left, Right;
        double mid, midmid;
        double mid_value, midmid_value;
        Left = MIN; Right = MAX;
        while (Left + EPS < Right)
        {
            mid = (Left + Right) / 2;
            midmid = (mid + Right) / 2;
            mid_area = Calc(mid);
            midmid_area = Calc(midmid);
            // 假设求解最大极值.
            if (mid_area >= midmid_area) Right = midmid;
            else Left = mid;
        }
    }

    现根据几道的OJ题目来分析三分法的具体实现。

    buaa 1033 Easy Problem 
    http://acm.buaa.edu.cn/oj/problem_show.php?c=0&p=1033

    题意为在一条线段上找到一点,与给定的P点距离最小。很明显的凸性函数,用三分法来解决。
    Calc函数即为求某点到P点的距离。

    ZOJ 3203 Light Bulb
    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3203

     


    如图,人左右走动,求影子L的最长长度。
    根据图,很容易发现当灯,人的头部和墙角成一条直线时(假设此时人站在A点),此时的长度是影子全在地上的最长长度。当人再向右走时,影子开始投影到墙上,当人贴着墙,影子长度即为人的高度。所以当人从A点走到墙,函数是先递增再递减,为凸性函数,所以我们可以用三分法来求解。

    下面只给出Calc函数,其他直接套模版即可。
    double Calc(double x)
    {
        return (h * D - H * x) / (D - x) + x;
    }

    heru 5081 Turn the corner 08年哈尔滨regional网络赛
    http://acm.hrbeu.edu.cn/index.php?act=problem&id=1280

     


    汽车拐弯问题,给定X, Y, l, d判断是否能够拐弯。首先当X或者Y小于d,那么一定不能。
    其次我们发现随着角度θ的增大,最大高度h先增长后减小,即为凸性函数,可以用三分法来求解。

    这里的Calc函数需要比较繁琐的推倒公式:
    s = l * cos(θ) + w * sin(θ) - x;
    h = s * tan(θ) + w * cos(θ);
    其中s为汽车最右边的点离拐角的水平距离, h为里拐点最高的距离, θ范围从0到90。

    POJ 3301 Texas Trip
    http://acm.pku.edu.cn/JudgeOnline/problem?id=3301

    题意为给定n(n <= 30)个点,求出饱含这些点的面积最小的正方形。

    有两种解法,一种为逼近法,就是每次m分角度,求出最符合的角度,再继续m分,如此进行times次,即可求出较为精确的解。(m 大概取10, times取30即可)

    第二种解法即为三分法,首先旋转的角度只要在0到180度即可,超过180度跟前面的相同的。坐标轴旋转后,坐标变换为:
    X’ = x * cosa - y * sina;
    y’ = y * cosa + x * sina;

    至于这题的函数是否是凸性的,为什么是凸性的,我也无法给出准确的证明,希望哪位路过的大牛指点一下~~

    例题更新(2010.5.5)
    hdu 3400 Line belt

    http://acm.hdu.edu.cn/showproblem.php?pid=3400
    典型的三分法,先三分第一条线段,找到一个点,然后根据这个点再三分第二条线段即可,想出三分的思路基本就可以过了。

    对于求解一些实际问题,当公式难以推导出来时,二分、三分法可以较为精确地求解出一些临界值,且效率也是令人满意的

  • 相关阅读:
    Spring Cloud Hystrix Dashboard的使用 5.1.3
    Spring Cloud Hystrix 服务容错保护 5.1
    Spring Cloud Ribbon 客户端负载均衡 4.3
    Spring Cloud 如何实现服务间的调用 4.2.3
    hadoop3.1集成yarn ha
    hadoop3.1 hdfs的api使用
    hadoop3.1 ha高可用部署
    hadoop3.1 分布式集群部署
    hadoop3.1伪分布式部署
    KVM(八)使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机
  • 原文地址:https://www.cnblogs.com/kkrisen/p/2874616.html
Copyright © 2011-2022 走看看