找到最小数量的矩形以覆盖2D点数组

时间:2019-09-25 05:50:58

标签: algorithm geometry computational-geometry rectangles

我得到了一个二维点数组,任务是生成一个最小的矩形列表,其中所有矩形具有相同的大小和方向,它们覆盖所有的二维点位置并且可以重叠。

到目前为止,我有一个不太令人满意的解决方案,其中将数组中的第一个点选择为第一个矩形的中心,然后移动该矩形,以便最接近的点适合该点。重复此过程,直到已经如果要再次移动矩形,则覆盖点将丢失。之后,从下一个未发现的点开始重复该过程,直到没有剩余的点为止。不太令人满意。

目标是找出最佳算法。它不必是矩形的绝对最小数目,而应尽可能少。

2 个答案:

答案 0 :(得分:1)

由于只能采用启发式解决方案,因此我将尝试如下操作:

  • 找到点的全局边界框;

  • 用规则的矩形网格覆盖边界框,没有重叠也没有间隙。

  • 如果矩形碰巧是空的,则将其丢弃。

您可以添加一个后处理步骤,以尝试改进:

  • 选择成对的相邻矩形,并找到它们所覆盖的点的边界框;如果该框适合单个矩形,请合并两个矩形。

enter image description here

请注意,由于矩形具有相同的大小和方向,因此可以重新缩放数据,以使矩形成为单位正方形。 (也由小装饰品说)。

答案 1 :(得分:0)

首先,可以以如下方式平移/投影坐标:矩形大小为1x1,方向为0°(与X / Y轴对齐)。所以我会假设这种情况。

然后您可以按照以下步骤操作:

  1. 按其 x -坐标
  2. 对点进行排序
  3. 创建有向图,如下所示:
    • 对于每个点 a ,取 x 间隔 [a x ,a x < / sub> +1] ,不包括 a 本身
    • 从此列表中排除其 y 坐标不在 [a y -1,a y ”范围内的点+1]
    • 通过 y -坐标
    • 对这些点进行排序
    • 将这些点放在点 a 的邻接列表中。
  4. 将所有点标记为未访问
  5. 如果没有未访问的点,请返回0表示不需要(更多)矩形。
  6. 从排序的点列表中获取下一个未访问的点 a :将 a 标记为已访问。
  7. 如果 a 没有邻居,则增加矩形计数并从第4步开始重复
  8. 在邻居上滑动一个矩形,使其矩形的左 x 坐标始终等于a x ,这样:
    • 第一个选择的矩形具有与第一个未访问的相邻点相同的低 y 坐标
    • 通过此矩形覆盖来维护要访问的邻居的列表 L (仅当尚未将其标记为已访问时)
    • 所有下一个矩形位置均在其高 y 坐标端获得一个未访问的点。
    • L 中在滑动矩形的低 y 侧被发现的点从 L 中移除并再次标记为未访问
    • 每次标识一个新的矩形位置时,都会从第4步开始进行递归(DFS)调用。
    • DFS调用将返回覆盖所有其余未访问点所需的矩形数
    • 保留所有这些递归调用返回的最小值,并加1(对于当前矩形)
    • NB:可以通过将当前的最小结果作为截止点来修剪递归树,从而避免搜索增加太多的矩形数。
  9. 处理完所有矩形位置后,将仍在 L 中的所有点标记为未访问。
  10. 返回找到的最小矩形数。

这可能仍然是一个非常昂贵的算法,因为搜索树很容易变得很宽。

潜在的改进可能是使用BFS代替DFS,并使用优先级队列(例如Min Heap)。最小化的数字将是已经使用的矩形的数量(即,到目前为止的成本)加上最右边(未访问)的点与最左边未访问点之间的x坐标差,向上舍入(即,成本的下限)仍然领先)。这是一种A *算法,因此一旦遇到所有点都被覆盖(访问)的情况,您可以立即停止搜索。

此BFS方法的缺点是内存使用和管理,因为每个状态(在优先级队列中)都包含一组访问点。

相关问题