【算法分析】之重新认识三分-----求极值(极大值和极小值)

被虐了。不过也是经常的事。

好了,开始讲。我们都知道二分可以求具有单调性的函数中的某个值。比如f(x)是具有单调性的,我们可以通过二分求f(x)==y的时候x的值是多少(已知y求x)。

但是为什么可以这么做呢?假设f(x)的单调性递增。

首先看二分的伪 代码:

bool binary_search(int l,int r,int y,int &ans)
{
    while(l<=r){
        int mid=(l+r)>>1;
        if(f(x)-y>0)r=mid-1;
        else if(f(x)-y<0)l=mid+1;
        else {
            ans=mid;
            return true;
        }
    }
    return false;
}

观察之后发现每次对于L和R的赋值操作都保证值在[L,R]这个区间内,这样就可以逼近要求的那个值。

好了,二分简单说到这。

现在提出一个问题。


现在我想求这个抛物线的极大值。

如果继续使用二分的话无法得出有效的答案,因为单纯的二分每次对于L或R的操作无法确定答案位于[L,R]区间内

因为这个图某个部分是单调上升而某个部分是单调递减的。

但是我们可以抓住二分的本质。

现在我想问。二分的本质是什么?

每次对于L或R的操作可以保证要求的值位于[L,R]区间中,这样迭代到最后是一定可以求到值的,以[L,R]为目标,mid为参考不断缩小[L,R]的范围。

知道了这一点我们可以考虑怎么求这个函数的极值了。

一个mid不行,那么我用mid的mid呢?

假设

mid=(L+R)/2;

midmid=(L+mid)/2;

那么可能出现的情况在图中所示,mid为红色(两种情况),midmid为褐色

当发生这种情况的时候,我们一定可以保证,答案位于[midmid,R]这个区间

这时我们就可以这么做:

当f(midmid)


当然了,还有f(midmid)>f(mid)的情况。见图。


考虑到这种情况

当f(midmid)>f(mid)时,我们令R=mid

考虑到这里,其实还有f(midmid)=f(mi)的情况。这种也很好解决

当f(midmid)=f(mid)时,我们令L=midmid或者R=mid;

到这里我们就有了一个很清晰的直观解决方法

假设我们一开始就可以确认极值位于[0,n]这个范围内


伪代码

1.令L=0,R=n;

2.令mid=(L+R)/2,midmid=(L+mid)/2;(除法为向下取整

3.计算若f(midmid)

   否则令R=mid;

4.若L=R则算法结束,结果为L

   否则转2


到这里我们还可以继续。新问题:

求下面这个函数的任意极大值


只需要求任意一个极大值,

其实是和求抛物线一样的算法。

为什么可以?

你可以按照我分析求抛物线所得出的算法方法来分析这题。

图:

假设:红色为mid,褐色为midmid


图:


其实算法都是一样的。好了说完了。

你可能感兴趣的:(算法分析&学习)