用极大化思想解决最大子矩形问题

最大子矩形问题:在一个给定的矩形中有一些障碍点,要找出内部不包含任何障碍点的,轮廓与整个矩形平行或重合的最大子矩形。
定义有效子矩形为内部不包含任何障碍点的,边界与坐标轴平行的子矩形。
这里写图片描述 有效子矩形

这里写图片描述 非有效子矩形

定义极大子矩形为每条边都不能向外扩展的有效子矩形。
定义最大子矩形为所有有效子矩形中最大的一个(或多个)。
【极大化思想】
在一个有障碍点的矩形中的最大子矩形一定是一个极大子矩形。
设计算法的思路:通过枚举所有的极大子矩形,找出最大子矩形。
【两个算法】
[针对问题的性质,可以设计出两个不同的算法。他们分别适用于不同的情况。]
[约定:为了叙述方便,设整个矩形的大小为N×M,其中障碍点个数为S。]
[算法一](时间复杂度:O(S2) 空间复杂度:O(S))
极大子矩形的性质: 一个极大子矩形的每条边一定都不能向外扩展。更进一步地说,一个有效子矩形是极大子矩形的条件是这个子矩形的每条边要么覆盖了障碍点,要么与整个矩形的边界重合。
这里写图片描述
1)基本算法:枚举上下左右四个边界,然后判断组成的矩形是否是有效子矩形。 (复杂度:O(S5))[可以改进的地方: 产生了大量的无效子矩形]
2)初步改进算法: 枚举左右边界,然后对处在边界内的点排序。每两个相邻的点和左右边界一起组成一个矩形。
(复杂度:O(S3)) [可以改进的地方: 枚举了部分不是极大子矩形的情况]
设计算法的方向: 1、保证每一个枚举的子矩形都是有效的 ; 2、保证每一个枚举的子矩形都是极大的
算法的过程:枚举极大子矩形的左边界→ 根据确定的左边界,找出相关的极大子矩形→ 检查和处理遗漏的情况
(1)首先,将所有障碍点按横坐标从小到大的顺序将点标为1号点,2号点……
这里写图片描述
(2) 为了处理方便,在矩形的四个顶点上各增加1个障碍点。
这里写图片描述
(3) 因为左边界覆盖1号点且右边界在2号点右边的有效子矩形都不能包含2号点,所以需要修改上下边界,2号点在1号点上方,因此要修改上边界
前面的做法可以找出所有左边界覆盖了一个障碍点的极大子矩形,此外,还有两类遗漏的情况。
<1> 左边界与整个矩形的左边界重合,右边界覆盖一个障碍点的情况。 ( 解决方法:用类似的方法从右向左扫描一次。)
<2> 左边界与整个矩形的左边界重合,且右边界也与整个矩形的右边界重合的情况。( 解决方法:预处理时增加特殊判断。)
[优点:利用了极大化思想,复杂度可以接受,编程实现简单。]
[缺点:使用有一定的局限性,不适合障碍点较密集的情况。]

[算法二] (悬线法)(时间复杂度:O(NM) 空间复杂度:O(S))
( 因为算法1有使用的局限性,所以我们需要一种在障碍点很密集的时候仍能奏效的算法。设计一种复杂度依赖于整个矩形面积的算法 说明:如果整个矩形面积很大,可以通过离散化处理来优化。)
[悬线] 有效竖线:除了两个端点外,不覆盖任何障碍点的竖直线段。
悬线:上端点覆盖了一个障碍点或达到整个矩形上端的有效竖线。
如图:这里写图片描述 都是合法悬线
每个悬线都与它底部的点一一对应。 矩形中的每一个点(矩形顶部的点除外)都对应了一个悬线。[悬线的个数=(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)[右边第一个障碍点的位置])
[优点: 复杂度与障碍点个数没有直接关系。]
[缺点:障碍点少时处理较复杂,不如算法1]

[转载自:王知昆 《最大子矩形》]

转载于:https://www.cnblogs.com/lris-searching/p/9403184.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值