zoukankan      html  css  js  c++  java
  • 三分法

    1.三分法模板

    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_value = Calc(mid);
            midmid_value = Calc(midmid);
            // 假设求解最大极值.
            if (mid_value >= midmid_value) Right = midmid;
            else Left = mid;
        }
    }

    2.两重三分法

    XMU.1125.越野车大赛

    #include <math.h>
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    
    #define INF 0x7fffffff
    #define eps 1e-5
    
    int n, m, s1, s2, s3;
    
    double Calc(double x, double y)                 /* x, y, n-x-y分别表示三段横向距离 */
    { return sqrt(pow(m,2)+pow(x,2))/s1 + sqrt(pow(m,2)+pow(y,2))/s2 + sqrt(pow(m,2)+pow(n-x-y,2))/s3; }
    
    int main()
    {
        double ans = INF;
        scanf("%d %d %d %d %d", &n, &m, &s1, &s2, &s3);
        double XL, XR, XM, XMM, Xt1, Xt2;
        double YL, YR, YM, YMM, Yt1, Yt2;
    
        XL = 0; XR = n;                       /* 外层对y取值透明,x为唯一变量时推极小值 */
        while(XR - XL > eps)
        {
            XM = (XL + XR) / 2;
            XMM = (XM + XR) / 2;
    
            YL = 0; YR = n;                      /* 当x固定为XM,y为唯一变量时推极小值 */
            while(YR - YL > eps)
            {
                YM = (YL + YR) / 2;
                YMM = (YM + YR) / 2;
    
                Yt1 = Calc(XM, YM);
                Yt2 = Calc(XM, YMM);
                if(Yt1 > Yt2)
                    YL = YM;
                else YR = YMM;
            }
            Xt1 = Calc(XM, YL);                  // 或Xt1 = Calc(XM, YR);
    
    
            YL = 0; YR = n;                      /* 当x固定为XMM,y为唯一变量时推极小值 */
            while(YR - YL > eps)
            {
                YM = (YL + YR) / 2;
                YMM = (YM + YR) / 2;
    
                Yt1 = Calc(XMM, YM);
                Yt2 = Calc(XMM, YMM);
                if(Yt1 > Yt2)
                    YL = YM;
                else YR = YMM;
            }
            Xt2 = Calc(XMM, YL);                 // 或Xt2 = Calc(XMM, YR);
    
            if(Xt1 > Xt2)
            { XL = XM; ans = Xt2; }
            else
            { XR = XMM; ans = Xt1; }
        }
        printf("%.10f
    ", ans);
        return 0;
    }

    思路分析:

    从Calc公式不难看出函数图像在x-y-z三维坐标中是一个下凸曲面,现在题目要求转换为:找到曲面最低处(x', y'),使得z = Calc(x', y')达到最小,解决这类三维图像(二元)求极值问题就是转化成二维图像(一元)求极值问题,就可以用普通三分法求解,这里采用两重三分法,外层用来逐步逼近目标x',内层用来逐步逼近目标y':

    当x固定在某值时,用普通三分法再确定y求得当前最小值是很容易做到的……在这一系列最小值的集合再选最小值事实上又是一个二维图像(一元)求极值问题,这可以从曲面的纵向剖物面看出,那么程序内外层就是依据这个思路编写的。

  • 相关阅读:
    UIKit, AppKit, 以及其他API在多线程当中的使用注意事项
    BOZJ-2590 优惠券
    P3620 [APIO/CTSC 2007] 数据备份
    矩阵乘法与快速幂
    CodeForces
    AtCoder
    CodeForces
    考试成绩和学号的(结构体)排序
    CodeForces
    Atcoder Beginner Contest 092 —— C题
  • 原文地址:https://www.cnblogs.com/1203ljh/p/4650858.html
Copyright © 2011-2022 走看看