使用最少的矩形覆盖折线,同时保持其连续性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用最少的矩形覆盖折线,同时保持其连续性相关的知识,希望对你有一定的参考价值。

给定形成折线的点列表,以及矩形的高度和宽度,如何找到覆盖所有点所需的所有矩形的数量和位置?

矩形应该旋转并且可以重叠,但必须遵循折线的路径(矩形可以包含线的多个线段,但每个矩形必须包含与前一个矩阵相邻的线段。)

在可能的情况下,在矩形的最小边上进行交叉是非常值得赞赏的。

到目前为止我找到的所有解决方案都不干净,这是我得到的结果:

您应该看到它在接近平坦的情况下提供良好的渲染,但在大的路缘中重叠太多。如果前一个矩形被偏移,则可以清楚地移除一个矩形。

实际上,我沿着直线放置一个以宽度/ 2为中心的矩形,并使用凸包和改进的旋转卡尺算法旋转它,并重复从前一个矩形和直线的交点开始。

您可能会发现我从最小化的矩形边界框算法中获取灵感,用于方向,但它不包括切割方面,也不包括固定大小。

谢谢你的帮助!

答案

这有点晚了,你可能已经想到了这一点。但是,我今天有空,并且研究了上次编辑中反映的约束(段的连续性)。正如我在评论中所说,我建议使用贪心算法。它由两部分组成:

  1. 搜索算法从初始点(我使用binary search algorithm)查找最远点,以便它们之间的所有点位于给定wh的矩形内。
  2. 一个重复的循环,在每一步找到最佳矩形并提升初始点。

它们的伪代码分别如下:

function getBestMBR( P, iFirst, w, h )
    nP = length(P);
    iStart = iFirst;
    iEnd = nP;
    while iStart <= iEnd
        m = floor((iStart + iEnd) / 2);
        MBR = getMBR(P[iFirst->m]);
        if (MBR.w < w) & (MBR.h < h) {*}
            iStart = m + 1;
            iLast = m;
            bestMBR = MBR;
        else
            iEnd = m - 1;
        end
    end
    return bestMBR, iLast;
end

function getRectList( P, w, h )
    nP = length(P);
    rects = [];
    iFirst = 1;
    iLast = iFirst;
    while iLast < nP
        [bestMBR, iLast] = getBestMBR(P, iFirst, w, h);
        rects.add(bestMBR.x, bestMBR.y, bestMBR.a];
        iFirst = iLast;
    end
    return rects;

测试用例1的解决方案:enter image description here

测试用例2的解决方案:enter image description here

请记住,它并不是要找到最佳解决方案,而是在合理的时间内找到次优解决方案。毕竟这是greedy

另一点是,您可以稍微改进一下,以减少矩形的数量。正如您在标有(*)的行中看到的那样,我在MBR(Minimum Bounding Rectangle)的方向上保持得到矩形,即使您可以覆盖具有相同wh的矩形的较大MBR,如果旋转矩形。 (1)(2

另一答案

我修改了k-means来解决这个问题。它并不快,它不是最佳的,它不能保证,但(恕我直言)这是一个良好的开端。有两个重要的修改:

1-距离测量

我使用Chebyshev-distance启发的测量来查看每个矩形的点数。为了找到从点到每个矩形的距离,首先我将所有点转换为新的坐标系,移动到矩形的中心并旋转到它的方向:

Transformation of original data to coordinate system of rectangle

然后我使用这些变换点来计算距离:

d = max(2*abs(X)/w, 2*abs(Y)/h);

对于距矩形每边具有相同距离的所有点,它将给出相等的值。对于位于矩形内的点,结果将小于1.0。现在我们可以将点分类为最近的矩形。

2-更新集群中心的策略

每个聚类中心都是C,矩形中心和a的组合,它的旋转角度。在每次迭代时,将新的点集分配给集群。在这里,我们必须找到Ca,以便矩形覆盖最大可能的点数。如果有解决方案,我现在不用,但我采用了统计方法。我使用点的加权平均值更新了C,并使用点的第一个principal component的方向来更新a。我使用了由500提供的建议距离的结果作为加权平均值中每个点的权重。它将矩形移向位于其外部的点。

如何找到K.

用1开始并增加它直到从点到它们相应的矩形的所有距离变得小于1.0,这意味着所有点都在矩形内。

结果

更新聚类中心(矩形)的迭代0,10,20,30,40和50:Iterations

测试用例1的解决方案:enter image description here

尝试Ks:2,4,6,8,10和12完全覆盖:Different Ks

测试用例2的解决方案:enter image description here

P.M:我使用了部分Chalous Road作为数据。从Google Maps下载它很有趣。我使用的技术描述了here来采样一组等间距点。

以上是关于使用最少的矩形覆盖折线,同时保持其连续性的主要内容,如果未能解决你的问题,请参考以下文章

如何计算最小长度的矩形数?

如何在保持圆周围位置的同时缩放多边形

bzoj1597 土地购买

UVA - 10382 Watering Grass(几何)

拆垛一个多指标熊猫数据帧,同时保持相同的列

在保持区域的同时旋转位图(矩形)