分治 Divide and Conquer 局部最小值 local optimal 棋盘问题

问题描述:

Suppose now that you’re given an  n × n grid graph $G$. (An n × n graph is just the adjacency graph of an $n \times n$ chessboard. To be completely precise, it is a graph whose node set is the set of all ordered pairs of natural numbers $(i,j)$, where 1 <= i <=n and 1 <= j <= n; the nodes $(i,j)$ and $(k,l)$ are joined by an edge if and only if $|i-k|+|j-l|=1$.)
Each node v is labeled by a real number xv you may assume that all these labels are distinct. 

Show how to find a local minimum of G using only O(n) probes to the nodes of $G$. (Note that G has n^2 nodes.)

解题思路:

首先拿到这样的题,由于是要在O(n)的时间内得到解,暴力枚举的方法显然是行不通的。那么怎样才能找到分治的出路,使得问题的规模减小,并且得到的子问题的数目是可数个,最重要的是子问题的性质应当与原问题一样。

在一个 n × n 的图中寻找局部最小值点,初始的考察范围应当是整个 n × n 总共n^2个格子,那么我们只需要逐步地缩小考察的范围,并且保证我们每一步考察的子范围是一定包含局部最小值的。

鉴于此,可从如下几个方面来解决这个问题:  

为方便描述,假设该图G是在二维平面上的x = 1, x=2 ,…, x=n 和 y = 1, y =2, y = n 这2n  条直线的交点形成的

《分治 Divide and Conquer 局部最小值 local optimal 棋盘问题》

1  首先比较图中红色的直线相交形成的4*n个点,得到一个对应值x最小的点x_min, 这样的x_min共有三种情况,如图中的

A1  4个 n/2 * n/2 共享这个节点

A2  2个 n/2 * n/2 共享这个节点
A3  1个  n/2 * n/2 共享这个节点

针对上述3种情况,显然 如果是 A3,我们只需考虑左上角的 n/2 * n/2 子方块

如果是 A2 或者是 A1  我们应该做何选择,已保证该子模块一定能够得到一个局部极小值点呢。接下来我们以 A1 为例(A2只是A1的一个特例)

2   对于A1,我们首先需要确定A1是否是我们的局部极小值点,比较A1和它的4个邻居,如果A1是最小的,那么A1即为所求。

  如果不是A1,则选择A1的一个“小于A1“ 的邻居节点,(不是一般性,直接选最小的)。假设这个最小点是B,那么我们将问题缩小到了右上角区域或者是右下角区域;

3   再考察B的上下2个邻居(因为在第一步B的右邻居就已经大于A1,被排除了(因为A1是最小的)),如果B最小,输出B;

  否则,选择B的最小的那个邻居,然后决定一个区域,不是一般性,我们假设是右上区域,这样我们就将问题缩小到了 n/2 * n/2 这样的一个区域。问题规模直接减半。

4  只需要递归的进行1,2,3步,即可得到一个局部极小值点。

复杂度分析:

第1步的时间复杂度是O(n), 我们只需要找到最小值即可。

第2步的时间复杂度是常数,因为A1与它的至多4个邻居做比较。(至多的意思是,每个点至多比较4次)

第3步的时间复杂度是常熟,因为A1与它的至多2个邻居比较。 (因为每次考察到B点时,它的邻居已经至少被排除两个)

则将问题降到 n/2 * n/2 的规模时,耗费的时间是O(n),因此有

T(n) = T (n/2) + O(n)

根据主定理,可以有T(n) = O(n)

正确性的证明:

显然在整个过程中,我们每一次考察的点都是一个递减的序列,因此我们最后考察的数一定是局部极小的。

PS:在算法的第一步其实可以只选取 x=n/2 和 y=n/2两条直线的的2n个点,同样可以得到正确答案。


问题反思:此题是一个很好的将问题在O(n)的时间内将问题的规模缩小一半,因此只需要O(n)就可以将问题缩小到常数规模;

在多数要求将问题在O(n)的时间内解决的分治的问题,我们能做的就是将问题在O(n)的时间内将问题的考察规模缩小,进而实现分治,其实一般只考虑某一个一定包含解的子问题即可。


修正:其实每次我只需要比较4条红色的线形成的9个顶点(感谢Tony549285469帮我指出错误),那么情况就会分为类似上面的3种。

    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/xuqingict/article/details/14189045
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞