最大子矩阵问题-悬线法

来源:互联网 发布:小型宝塔数控机床编程 编辑:程序博客网 时间:2024/06/06 05:18

最大子矩形问题:
在一个给定的矩形中有一些障碍点,要找出内部不包含任何障碍点的,轮廓与整个矩形平行或重合的最大子矩形。
定义与说明:
有效子矩形:内部不包含任何障碍点的,边界与坐标轴平行的子矩形
极大子矩形:每条边都不能向外扩展的有效子矩形
最大子矩形:所有有效子矩形中最大的一个(或多个)
极大化思想:

  • 在一个有障碍点的矩形中最大子矩形一定是极大子矩形
  • 算法的思路:通过枚举所有的极大子矩形,找出最大子矩形。

两个不同的算法(分别适用于不同的情况):
约定:设整个矩形的大小为N×M,其中障碍点个数为S。

  • 算法①

时间复杂度:O(S^2),空间复杂度:O(S)
思路:从极大子矩形的性质入手。
(极大子矩形的性质: 一个极大子矩形的每条边一定都不能向外扩展。更进一步地说,一个有效子矩形是极大子矩形的条件是这个子矩形的每条边要么覆盖了障碍点,要么与整个矩形的边界重合。)
过程:
枚举极大子矩形的左边界——>根据确定的左边界,找出相关的极大子矩形——>检查和处理遗漏的情况
为了处理方便,在矩形的四个顶点上各增加1个障碍点
(1)按照横坐标从小到大的顺序将所有的点编号为1,2,3……
(2)首先选取1号点作为要枚举的极大子矩形的左边界,设定上下边界为矩形的上下边界
(3)从左到右扫描,第一次到2号点,确定一个极大子矩形,修改上下边界;第二次找到3号点,以此类推。
(4)将左边界移动到2号点,3号点……以同样的方法枚举
遗漏的情况:
1、矩形的左边界与整个矩形的左边界重合
解决方法:用类似的方法从左到右扫一遍
2、矩形的左边界与整个矩形的左边界重合,且矩形的右边界与整个矩形的右边界重合。
解决方法:预处理时增加特殊判断。
优点:利用的极大化思想,复杂度可以接受,编程实现简单。
缺点:使用有一定的局限性,不适合障碍点较密集的情况。

  • 算法②

时间复杂度:O(NM),空间复杂度:O(S)
一种在障碍点很密集的时候仍能奏效的算法
说明:如果整个矩形面积很大,可以通过离散化处理来优化
定义:
有效竖线:除了两个端点外,不覆盖任何障碍点的竖直线段。
悬线:上端点覆盖了一个障碍点或达到整个矩形上端的有效竖线。
每个悬线都与它底部的点一一对应,矩形中的每一个点(矩形顶部的点除外)都对应了一个悬线
悬线的个数=(N-1)*M
③如果把一个极大子矩形按x坐标不同切割成多个与y轴平行的线段,则其中至少存在一个悬线,如下图:

④如果把一个悬线向左右两个方向尽可能移动,就能得到一个矩形,不妨称为这个悬线对应的矩形。悬线对应的矩形不一定是极大子矩形,因为下边界可能还可以向下扩展。

  • 原理:所有悬线对应矩形的集合一定包含了极大子矩形的集合。通过枚举所有的悬线,找出所有的极大子矩形。

  • 算法规模:
    悬线个数=(N-1)×M
    极大子矩形个数≤悬线个数

  • 具体方法:

  设:     H[i,j]为点(i,j)对应的悬线的长度。     L[i,j]为点(i,j)对应的悬线向左最多能够移动到的位置。     R[i,j]为点(i,j)对应的悬线向右最多能够移动到的位置。

如下图:

递推关系-考虑点(i,j)对应的悬线与点(i-1,j)对应的悬线的关系

  • 如果(i-1,j)为障碍点,那么,(i,j)对应的悬线长度1,左右能移动到的位置是整个矩形的左右边界。即 H[i,j]=1, L[i,j]=0, R[i,j]=m

  • 如果(i-1,j)不是障碍点,那么,(i,j)对应的悬线长度为(i-1,j)对应的悬线长度+1。即 H[i,j]=H[i-1,j]+1

  • 如果(i-1,j)不是障碍点,那么,(i,j)对应的悬线左右能移动的位置要在(i-1,j)的基础上变化。即L[i,j]=max{L[i-1,j],(i-1,j)左边第一个障碍点的位置}

  • 同理,也可以得到R[i,j]的递推式,即R[i,j]=min{R[i-1,j], (i-1,j)右边第一个障碍点的位置}

推广一:最大权值子矩形问题
模型:在一个带权(正权)矩形中有一 些障碍点,找出一个不包含障碍点 的最大权值子矩形
分析:在一个正权值的矩形中的最大权值子矩形一定是极大子矩形。所以,问题实际上可以依据极大化的思想,利用前面的方法解决。
推广二:最大子正方形问题
模型:在一个矩形中存在S个障碍点,要 求找出最大的不包含障碍点的正方 形。
分析:在一个有障碍点的矩形中的最大有效子正方形一定是一个极大有效子正方形。
极大子正方形的性质:每一个极大子正方形都至少被一个极大子矩形包含,且这个极大子正方形一定有两条不相邻的边与包含它的极大子矩形的边重合。
解决方法:通过枚举每一个极大子矩形找出所有的极大子正方形。每个极大子矩形对应的极大子正方形可能有多个,但大小都一样。
转自:2003 - 王知昆:《浅谈用极大化思想解决最大子矩形问题》
相关习题:
WC2002 奶牛浴场(算法1)
CodeVS1159 最大全0子矩阵(算法2)

原创粉丝点击