三分搜索法

一 问题

在一个平面上有N个点,每个点的坐标已经给出,现在要求在X轴上找一个点,使得这个点到所有点中最大的距离最小。

二 分析

不知道是否有基于策略选择的算法,也许是DP也许是Greedy。本文通过数值计算来解决此问题。

问题抽象:

设f(x) = max(node1_distance, node2_distance, ……nodeN_distance), a<=x<=b;

求x*使min(f(x)) = f(x*),a<=x*<=b;

如果存在x*使目标函数极小,那么对任意的a<=x1<x2<=b,当x2<=x*时,f(x1)>f(x2);当x1>=x*时,f(x1)<f(x2). 也就是f(x)是一个单峰函数。

问题就转化为求单峰函数的极值。

三 算法

网上主要有两种搜索算法,虽然都称之为三分搜索(或称查找)。核心思想都是通过“去坏留好”的原则不断压缩解空间来求极值。

流传算法1:

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) Left = mid;
        else Right = midmid;
    }
}

流传算法2:

double ternary_search(double l,double r){ //三分查找求最小值
	while(l + EPS < r){
		double left = (2*l + r)/3;
		double right = (2*r + l)/3;
		double tmp1 = cal(left);
		double tmp2 = cal(right);
		if(tmp1 > tmp2) l = left;
		else     	r = right;
	}
	return l;
}

上面两种广为流传的三分搜索求单峰函数极值的实现,除了在每次迭代中选取两点的策略不同之外,其他都一样。

正当我疑惑为什么有两种不同的选取策略,突然又想起了在工程优化中学到的0.618法求单峰函数极值的算法。查阅书本之后,算法如下


黄金分割法(0.618法):

三分搜索法_第1张图片


看完黄金分割法发现,核心思想和前面两种算法一样,仅仅是有一种新的计算迭代过程中两点的方法。

细想一下,其实不管哪种策略,都是去除了不可能的那部分,留下解所在的区域。那么就能保证这三种算法都能求得极值点。只是逼近的极值点的速度不一样而已。我们自己也可以想出一种新的逼近方案。


四 总结:

之前在学工程优化的时候,一直没有好好听课,总觉得作用不大,今天居然还用上了,真是应了老话,学到的知识总会用上的。

三分搜索或者0.618法都是在单峰函数(非单调)查找。而二分查找其实就是在一个单调函数中查找某一值。两者还是有联系的。


你可能感兴趣的:(三分搜索法)