80、计算最大空任意定向矩形:理论与实现

计算最大空任意定向矩形:理论与实现

1. 引言

几何优化是快速发展的计算几何领域中一个非常活跃的研究方向。该研究的动机源于各种实际问题,如材料切割、特定的填充和最优布局问题等。

其中,最大空矩形问题备受关注。给定一个矩形区域 $R$ 内的 $n$ 个点的集合 $P = {p_1, p_2, \ldots, p_n}$,该问题是要找到一个面积(或周长)最大的矩形,其边与原矩形 $R$ 的边平行。一个实际应用场景是,从一块带有“瑕疵”点的矩形金属板 $R$ 中,切割出一个没有任何瑕疵点的最大面积(或周长)的矩形。

这个问题最早由 [NHL84] 提出,他们给出的算法最坏情况下的运行时间为 $O(n^2)$,期望运行时间为 $O(n \log^2 n)$。随后,[CDL86] 将最坏情况复杂度改进到 $O(n \log^3 n)$,[AS87] 进一步将其改进为 $O(n \log^2 n)$。[Orl90] 提出了一个输出敏感的算法,其最坏情况复杂度为 $O(n \log n + s)$,空间复杂度为 $O(n)$。

2. 概述

假设给定的 $n$ 个点都位于直角坐标系的第一象限。通过每个点绘制一对与两个固定方向平行的正交线,得到一个网格图。网格的方向 $\theta$ 是这两个方向与坐标系 $x$ 轴所成两个角度中的较小者。

网格线确定了许多不同的空矩形。最大空矩形(MER)是指内部不包含任何点,且不被其他任何空矩形完全包含的矩形。我们关注的是四条边上都有一个点界定的 MER。

由于当连续改变网格方向(如逆时针)时,所有 MER 会一直存在,直到集合中的某两个点在某一个正交方向上共线,此时会生成新的 MER,这些情况构成一个事件,对于每一对点的选择,有 $O(n^2)$ 个这样的事件。

我们用 $< p_t, p_b, p_l, p_r, \alpha, \beta >$ 表示由点 $p_t$、$p_b$、$p_l$ 和 $p_r$ 界定的 MER 范围,其中 $\alpha$ 是该范围出现时的网格方向,$\beta$ 是其消失时的网格方向。在这个范围内,某个中间值 $\theta$ 处,MER 会达到最大面积,这可以通过微积分来确定。我们的解决方案的核心是生成这个离散的事件集合,并计算所有矩形范围内的最大面积 MER。

3. 算法
3.1 楼梯结构与最大空矩形

对于给定的点 $p_i \in P$ 和网格方向,我们对一条边上由点 $p_i$ 界定的 MER 进行如下特征描述:
- 通过点 $p_i$ 的一对正交线(由给定的网格方向确定)将点集划分为四个不相交的子集,分别标记为 $I_i$、$II_i$、$III_i$ 和 $IV_i$。
- 每个子集的最大值具有楼梯结构,我们用 $S_{X_i}$ 表示点 $p_i$ 的 $X$ 组的楼梯结构。每条边上有 $p_i$ 的每个最大空矩形,其另外三条边上的点位于相邻象限的一对楼梯上。
- $S_{I_i}$(以及 $S_{II_i}$、$S_{III_i}$ 和 $S_{IV_i}$)上的点可以相对于 $p_i$ 逆时针排序。我们用 $next(S_{I_i}, p_j)$($previous(S_{I_i}, p_j)$)表示在这个排序中 $p_j$ 的下一个(前一个)点(如果存在)。

对于给定的网格方向,通过点 $p_i$ 的正交线分别记为 $h_i$ 和 $v_i$,其中 $h_i$ 与 $x$ 轴的夹角较小。设 $p_l$ 是 $S_{II_i}$ 上的一个点,我们用 $p_{lb}$(类似地,$p_{la}$)表示 $S_{I_i}$ 中 $h_i$ 线正下方(正上方)的点;用 $p_{ll}$(类似地,$p_{lr}$)表示 $S_{III_i}$ 中 $v_l$ 线正左侧(正右侧)的点。同样,我们可以为 $S_{I_i}$、$S_{III_i}$ 和 $S_{IV_i}$ 上的每个点定义这四个指针。我们用 $S_i$ 表示点 $p_i$ 的这四个楼梯结构以及每个点上的上下左右指针。

以下是相关的引理:
- 引理 1 :给定按 $x$ 坐标排序的 $n$ 个点的集合 $P$ 和点 $p_i \in P$,我们可以在 $O(n)$ 时间内,使用 $O(n)$ 空间计算楼梯结构 $S_i$。
- 观察 3.1 :右边(类似地,左边)边包含点 $p_i$ 的最大空等轴矩形,被 $S_{II_i}$ 和 $S_{III_i}$($S_{I_i}$ 和 $S_{IV_i}$)以及通过点 $p_i$ 的垂直线所界定。同样,顶部(类似地,底部)边包含点 $p_i$ 的最大空等轴矩形,被 $S_{III_i}$ 和 $S_{IV_i}$($S_{I_i}$ 和 $S_{III_i}$)以及通过点 $p_i$ 的水平线所界定。
- 引理 2 :给定 $S_i$,可以在 $O(n)$ 时间内确定由点 $p_i$ 界定的 MER。

3.2 基本连续优化问题

在本小节中,我们讨论如何计算对应于 $\theta = \alpha$ 和 $\theta = \beta$ 的事件之间的 MER 的最大度量。

设 $r$ 是一个由点 $p_t$、$p_b$、$p_l$ 和 $p_r$ 界定的 MER。由于 $r$ 总是包含四边形 $< p_t, p_b, p_l, p_r >$,其面积度量在构成 $r$ 其余部分的三角形面积之和最大时达到最大,这可以很容易地转化为一个单参数优化问题。

触发上述类别的 MER 消失的事件可能以两种方式发生:一是有新的点进入其中,使其不再为空;二是 MER 的一条边与内接四边形的一条边重合。我们下面仅详细讨论第一种情况,第二种情况可以类似处理。

设该事件由点 $p_j$ 出现在 $r$ 的顶部边缘触发。如果我们设 $p_{tr}$ 是 $h_t$ 和 $v_r$ 的交点,则有以下观察:
- 观察 3.2 :三角形 $< p_t, p_r, p_{tr} >$ 的面积为 $\frac{1}{4}|p_t p_r|^2 \sin 2(\alpha_1 + \theta)$,其中 $\theta \in [0, \beta - \alpha]$。
- 观察 3.3 :$< p_t, p_b, p_l, p_r, \alpha, \beta >$ 范围内的最大面积矩形为 $\frac{1}{4}\max_{\theta \in [0, \beta - \alpha]}{|p_t p_r|^2 \sin 2(\alpha_1 + \theta) + |p_l p_t|^2 \sin 2(\alpha_2 + \theta) + |p_l p_b|^2 \sin 2(\alpha_3 + \theta) + |p_r p_b|^2 \sin 2(\alpha_4 + \theta)}$。

我们可以使用微积分在常数时间内解决这个最大化问题,因此有以下引理:
- 引理 3 :在给定范围 $< p_t, p_b, p_l, p_r, \alpha, \beta >$ 内,可以在 $O(1)$ 时间内找到最大面积/周长的空任意定向矩形。

需要注意的是,如果进一步旋转,可能会找到由点 $p_t$、$p_b$、$p_l$ 和 $p_r$ 界定的另一个空矩形范围。

3.3 事件队列和楼梯结构更新

我们首先考虑以下问题:对于给定的点 $p_i \in P$,找到一条边上由点 $p_i$ 界定的最大度量的任意定向 MER。

矩形范围在事件点开始和结束。在我们的方案中,事件点是当网格在 $\theta = 0$ 到 $\theta = \frac{\pi}{2}$ 范围内旋转时,两个点 $p_j$ 和 $p_k$ 在某一个正交方向上共线的情况。设 $E_h(p_j, p_k)$(分别地,$E_v(p_j, p_k)$)表示 $p_j$ 和 $p_k$ 沿“水平”(“垂直”)方向共线触发的事件,此时 $\theta = angle(p_j, p_k)$($\theta + \frac{\pi}{2} = angle(p_j, p_k)$)。

事件点保存在一个事件队列 $Q$ 中,它是由 $P$ 中两两取点确定的线段的支撑线斜率绝对值的有序列表,可以在 $O(n^2 \log n)$ 时间内初始化。我们取绝对值,因为事件可以是“水平”或“垂直”的。

由于每个 MER 隐式地保存在楼梯结构 $S_i$ 中,并且可以在 $O(n \log n)$ 时间内初始化,我们需要解决以下问题:
- 如何在事件发生时更新 $S_i$?
- 如何跟踪 MER 的范围?

$S_i$ 的每个角(由楼梯上两个连续点的正交线定义)定义了两个空矩形。我们根据某种约定,在 $S_i$ 中与这个角相邻的顶点处维护这些矩形出现的方向 $O_1$ 和 $O_2$(我们将 $O_1$ 与跨越到逆时针组的矩形关联;将 $O_2$ 与跨越到顺时针组的矩形关联)。

假设事件是一个“垂直”事件,即 $E_v(p_j, p_k)$,我们可以将这个事件分为以下几种情况:
- $S_i$ 上的新点 :设 $p_j$ 已经在 $S_i$ 上,而新点 $p_k$ 进入 $S_i$。当 $p_k$ 接触到 $v_j$ 上的一个线段 $e$ 时会发生这种情况。不失一般性,假设 $p_j \in S_{II_i}$。$< p_i, next(p_m, S_{I_i}), p_m, p_j >$ 这些矩形会变为非空,其中 $p_m \in S_{I_i}$ 且位于 $S_i$ 上的 $p_{lb}$ 和 $p_{ka}$ 之间。因此,对于 $S_{I_i}$ 中位于 $p_{lb}$ 和 $p_{ka}$ 之间的每个点 $p_m$,矩形范围为 $< p_i, next(p_m, S_{I_i}), p_m, p_j, O_{1_{next(p_m, S_{I_i})}}, \theta >$,其中 $O_1$ 是该矩形范围在 $S_i$ 中出现的方向。$< p_i, p_{lb}, p_l, p_j >$ 的矩形范围为 $< p_i, p_{lb}, p_l, p_j, O_{2_{p_l}}, \theta >$。同样,我们可以确定由 $S_{II_i}$ 和 $S_{III_i}$ 上的点界定的、由该事件终止的矩形范围。新的矩形 $< p_i, next(p_m, S_{I_i}), p_m, p_k >$(其中 $p_m \in S_{I_i}$ 位于 $p_{lb}$ 和 $p_{ka}$ 之间)会出现在 $S_i$ 中。因此,对于 $p_{lb}$ 和 $p_{ka}$ 之间的每个 $p_m$,我们将 $O_{1_{next(p_m, S_{I_i})}}$ 设置为 $\theta$。同样,我们将 $O_{2_{p_l}}$ 设置为 $\theta$。对于出现在 $S_{II_i}$ 和 $S_{III_i}$ 上的点之间的新矩形,我们也进行同样的操作。
- $S_i$ 上点的消失 :设 $p_j$ 和 $p_k$ 是 $S_{I_i}$ 上的相邻点。事件发生后,$p_k$ 支配 $p_j$。与前一种情况一样,由点 $p_j$ 界定的矩形会终止。新出现的矩形是通过适当改变这些矩形的界定点 $p_j$ 得到的。
- 点的迁移 :设 $i = k$ 且 $p_j \in S_{II_i}$,这意味着该事件是由点 $p_i$ 和 $p_j$ 共线触发的。假设点 $p_j$ 迁移到 $S_{I_i}$,在迁移前后都出现在楼梯上。实际上,根据事件是 $E_v(p_j, p_i)$ 还是 $E_h(p_j, p_i)$,该点从事件发生前所属的组迁移到事件发生后顺时针方向的组。与前一种情况一样,我们可以确定由该事件终止的矩形范围。点 $p_j$ 可能会支配 $S_{I_i}$ 中的一部分楼梯,以及 $S_{II_i}$ 中下一层的一部分(如图中虚线所示),这些部分在事件发生后会分别消失和出现。边界包含消失点的 MER 会终止,我们相应地更新 $S_i$。
- 第四种类型 :点 $p_j$ 和 $p_k$ 分别属于 $S_{II_i}$ 和 $S_{III_i}$。在这种情况下,楼梯结构 $S_i$ 的拓扑结构不变,但矩形 $< p_k, next(S_{III_i}, p_k), p_i, prev(S_{II_i}, p_j) >$ 和 $< p_j, p_k, p_i, prev(S_{II_i}, p_j) >$ 的范围会终止,而新矩形 $< p_j, next(S_{III_i}, p_k), p_i, prev(S_{II_i}, p_j) >$ 和 $< p_k, next(S_{III_i}, p_k), p_i, p_j >$ 的范围会开始。

引理 4 :给定一个矩形 $R$ 内的 $n$ 个点的集合,由点 $p_i$ 界定的最大空任意定向矩形可以在 $O(n^3)$ 时间内,使用 $O(n)$ 空间计算得到。

证明过程如下:
我们使用链表来实现 $S_i$ 的楼梯结构。为了在常数时间内确定事件类型和事件中涉及的点在 $S_i$ 中的位置,我们需要一个额外的数据结构:$Pointer_i[]$ 来存储指向 $S_i$ 的交叉指针。如果点 $p_j$ 在 $S_i$ 中,$Pointer_i[j]$ 指向它在 $S_i$ 中的位置,否则其值为 nil。$Q$ 的实现是标准的。

$S_i$ 和 $Q$ 的初始化分别可以在 $O(n \log n)$ 和 $O(n^2 \log n)$ 时间内完成。我们分析上述每种情况的复杂度:
- 设事件是一个“垂直”事件:$E_v(p_j, p_k)$。我们知道 $j \neq k$。如果 $k \neq i$,$p_j \in S_i$,$p_k \notin S_i$,并且 $p_k$ 在 $v_j$ 位于 $S_i$ 的部分上,那么 $p_k$ 是 $S_i$ 上的新点。使用 $Pointer_i[j]$ 和 $p_{jb}$,可以在 $O(k_1)$ 时间内完成由该事件终止的矩形范围和方向的更新,其中 $k_1$ 是终止的矩形数量。
- 如果 $p_j$ 和 $p_k$ 是 $S_{I_i}$ 中的两个相邻点,事件发生后,其中一个点支配另一个点。设事件发生后 $p_k$ 支配 $p_j$。与前一种情况一样,可以在 $O(k_2)$ 时间内完成由该事件终止的矩形范围和方向的更新,其中 $k_2$ 是终止的矩形数量。
- 如果 $k \neq i$,$p_j$,$p_k \in S_i$,并且 $p_j$,$p_k$ 在相邻组中,我们有上述讨论的最后一种情况。该事件终止的矩形数量为两个,并且开始两个新的矩形。因此,更新时间为 $O(1)$。
- 如果 $k = i$,$p_j$ 迁移到另一个组。同样,我们可以在与矩形数量成比例的时间内找到由该事件终止的矩形范围,并通过重新计算 $S_i$ 在 $O(n)$ 时间内更新 $S_i$。为此,我们需要按顺序排列的点列表(这是网格方向 $\theta$ 的函数)。可以按如下方式无额外成本地维护排序顺序:最初,我们按 $x$ 坐标对这些点进行排序。每当事件是“垂直”事件时,由于这些点在排序列表中相邻,我们交换它们在排序列表中的位置。

因此,处理一个事件所需的时间为 $O(n)$。由于有 $O(n^2)$ 个事件,所以引理成立。

下面是事件处理流程的 mermaid 流程图:

graph TD;
    A[事件发生] --> B{事件类型};
    B -- 新点在Si上 --> C[更新相关矩形范围和方向];
    B -- 点在Si上消失 --> D[终止相关矩形并更新];
    B -- 点迁移 --> E[确定终止矩形范围并更新Si];
    B -- 第四种类型 --> F[更新矩形范围];
    C --> G[处理完成];
    D --> G;
    E --> G;
    F --> G;

事件处理情况总结如下表:
| 事件类型 | 处理方式 | 复杂度 |
| ---- | ---- | ---- |
| 新点在 $S_i$ 上 | 使用 $Pointer_i[j]$ 和 $p_{jb}$ 更新矩形范围和方向 | $O(k_1)$ |
| 点在 $S_i$ 上消失 | 终止相关矩形并更新 | $O(k_2)$ |
| 点迁移 | 确定终止矩形范围并重新计算 $S_i$ | $O(n)$ |
| 第四种类型 | 更新矩形范围 | $O(1)$ |

3.4 算法复杂度

直接将该算法扩展到所有 $n$ 个楼梯结构需要 $O(n^4)$ 时间。然而,以下观察结果使我们能够改进这个界限:
- 观察 3.4 :一个 MER 最多出现在四个楼梯结构中。
- 观察 3.5 :每个楼梯结构有 $n - 1$ 次迁移。

引理 5 :给定一个矩形 $R$ 和其中的 $n$ 个点的集合 $P$,可以在 $O(n^3 + s)$ 时间内,使用 $O(n^2)$ 空间计算出 $R$ 内的最大空任意定向矩形,其中 $s$ 是矩形范围的总数。

证明 :处理所有迁移所需的时间为 $O(n^3)$,因为有 $O(n^2)$ 次迁移。对于所有其他事件,所需时间为 $O(n^3 + s)$,因为对于每个事件,我们要查看每个楼梯结构以确定终止的矩形范围,并且每个 MER 最多出现在四个楼梯结构中,其中 $s$ 是矩形范围的总数。因此,引理成立。

$s$ 的估计

由通过一对点 $(p_i, p_j)$ 的水平(类似地,垂直)线 $h_i$($v_i$)和 $h_j$($v_j$)界定的 MER(如果存在)是唯一确定的。我们估计由 $p_i$、$p_j$、$h_i$ 和 $h_j$ 界定的 MER 的数量。同样,我们可以估计由 $v_i$ 和 $v_j$ 形成的垂直条带以及点 $p_i$ 和 $p_j$ 界定的 MER 的数量。

下面是整个算法流程的 mermaid 流程图:

graph TD;
    A[初始化事件队列Q和楼梯结构Si] --> B[遍历事件队列Q];
    B --> C{事件类型};
    C -- 新点在Si上 --> D[更新Si和矩形范围];
    C -- 点在Si上消失 --> E[更新Si和矩形范围];
    C -- 点迁移 --> F[更新Si和矩形范围];
    C -- 第四种类型 --> G[更新矩形范围];
    D --> H[计算当前最大面积MER];
    E --> H;
    F --> H;
    G --> H;
    H --> I{是否遍历完所有事件};
    I -- 否 --> B;
    I -- 是 --> J[输出最大面积MER];

总结

本文提出了一种计算平面上给定 $n$ 个点的最大空任意定向矩形的算法。该算法通过离散事件集合和楼梯结构来跟踪最大空矩形(MER)的范围,并利用微积分在每个范围内找到最大面积的 MER。具体步骤如下:
1. 初始化
- 按 $x$ 坐标对 $n$ 个点排序。
- 初始化事件队列 $Q$,时间复杂度为 $O(n^2 \log n)$。
- 初始化每个点 $p_i$ 的楼梯结构 $S_i$,时间复杂度为 $O(n \log n)$。
2. 事件处理
- 遍历事件队列 $Q$ 中的每个事件。
- 根据事件类型(新点在 $S_i$ 上、点在 $S_i$ 上消失、点迁移、第四种类型)更新 $S_i$ 和矩形范围。
- 对于每个事件,计算当前最大面积的 MER。
3. 输出结果 :遍历完所有事件后,输出最大面积的 MER。

算法的复杂度为 $O(n^3 + s)$ 时间和 $O(n^2)$ 空间,其中 $s$ 是矩形范围的总数。通过对事件队列和楼梯结构的有效管理,该算法在处理最大空矩形问题上具有较好的性能。

该算法的优势在于能够处理任意定向的矩形,并且通过离散事件的方式减少了不必要的计算。然而,其复杂度仍然较高,对于大规模的点集可能需要进一步优化。未来的研究可以考虑如何降低事件处理的复杂度,或者探索更高效的数据结构来存储和更新矩形范围。

以下是算法复杂度总结表:
| 操作 | 时间复杂度 | 空间复杂度 |
| ---- | ---- | ---- |
| 初始化事件队列 $Q$ | $O(n^2 \log n)$ | - |
| 初始化楼梯结构 $S_i$ | $O(n \log n)$ | $O(n)$ |
| 处理单个事件 | $O(n)$ | - |
| 处理所有事件 | $O(n^3 + s)$ | $O(n^2)$ |

通过以上的分析和总结,我们对计算最大空任意定向矩形的算法有了更深入的理解,并且可以根据实际需求对算法进行优化和改进。

源码来自:https://pan.quark.cn/s/d16ee28ac6c2 ### 上线流程 Java Web平台在实施Java Web应用程序的发布过程时,通常包含以下几个关键阶段:应用程序归档、生产环境配置文件替换、系统部署(涉及原有应用备份、Tomcat服务关闭、缓存数据清除、新版本WAR包上传及服务重启测试)以及相关异常情况记录。以下将对各阶段进行深入说明。#### 一、应用程序归档1. **归档前的准备工作**: - 需要事先验证Java开发环境的变量配置是否正确。 - 一般情况下,归档操作会在项目开发工作结束后执行,此时应确认所有功能模块均已完成测试并符合发布标准。 2. **具体执行步骤**: - 采用`jar`指令执行归档操作。例如,在指定文件夹`D:\apache-tomcat-7.0.2\webapps\prsncre`下运行指令`jar –cvf prsncre.war`。 - 执行该指令后,会生成一个名为`prsncre.war`的Web应用归档文件,其中包含了项目的全部资源文件及编译后的程序代码。#### 二、生产环境配置文件调换1. **操作目标**:确保线上运行环境开发或测试环境的参数设置存在差异,例如数据库连接参数、服务监听端口等信息。2. **执行手段**: - 将先前成功部署的WAR包中`xml-config`文件夹内的配置文件进行复制处理。 - 使用这些复制得到的配置文件对新生成的WAR包内的对应文件进行覆盖更新。 #### 三、系统部署1. **原版应用备份**: - 在发布新版本之前,必须对当前运行版本进行数据备份。例如,通过命令`cp -r prsncre ../templewebapps/`将旧版应用复...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值