• 三分/优选法(黄金分割法)求单峰函数极值


     给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减。试求出x的值。

    (此题其实当然可以取导用二分做,但是如果有些函数求导很麻烦的话那就用三分)

    三分:
    此题根据对称性,在(l,r)中间找两个点l',r',若f(l')<f(r')那就取(l',r)否则取(l,r')  -----其实可以看成粗糙的取导

    double f(double x){//秦九昭
    double ans=0,k=1;
    FFor(i,n,0)ans+=k*a[i],k*=x;
    return ans;
    }

    普通三分

    double work(double l,r){
    while(fabs(r-l)>eps){
    lm=l+(r-l)/3;
    rm=r-(r-l)/3;
    if(f(rm)>=f(lm))l=lm;
    else r=rm;
    }
    printf("%.5f",l);

    优选法三分:
    我看了网上大量博客文章,大多数真心没说到点子上(而且代码也没体现出优化性)
    实际上就一句话,普通的三分(或者你随意按其他比例缩小范围)都是每次必须取两个点进行计算f(l+len*w),f(r-len*w),
    但黄金分割法除了第一次取两个点外,以后每次就只需要取一个点就OK了,你说快不快。
    如图,红点是必须计算的点,灰点因为上一轮已经计算过,所以此轮就不用计算了,这样就实现了每轮只计算一个点的效果


    黄金分割数为 (sqrt(5)-1)/2 就不证明了

    上代码:

    #define gor (sqrt(5)-1)/2
    bool fgl=true,fgr=true;
    
    double gold(double l,r){
    while(fabs(r-l)>eps){
    double midr=(r-l)*gor+l;
    double midl=r-(r-l)*gor;
    if(!fgr)fr=f(midr);
    if(!fgl)fl=f(midl);
    if(fl>fr)
    r=midr,fgr=true,fgl=false;
    else if(fl<fr)
    l=midl,fgl=true,fgr=false;
    else 
    l=midl,r=midr,fgr=true,fgl=true;
    }
    return r;
    }
    printf("%.5f",gold(l,r));
    
  • 相关阅读:
    利用python求非线性方程
    迪士尼穷游攻略
    爬虫八之爬取京东商品信息
    爬虫七之分析Ajax请求并爬取今日头条
    爬虫五之Selenium
    爬虫4之pyquery
    前端传入 SQL 语句 到后端执行
    手写分页处理
    集合(Map,List)分组:多属性进行分组
    java 枚举类非常好的运用实例
  • 原文地址:https://www.cnblogs.com/planche/p/9395378.html
Copyright © 2020-2023  润新知