找到最小矩形数量的算法

Posted

技术标签:

【中文标题】找到最小矩形数量的算法【英文标题】:Algorithm to dins minimal number of rectangles 【发布时间】:2013-11-21 18:13:03 【问题描述】:

我在坐标系中有一个矩形区域 R 和一组位于 R 内的点 P。所有边都平行于轴,所有点都是整数。我想以这样的方式将 R 分成更小的矩形

(a) 矩形的边要么紧贴 R 的边,要么包含至少一个来自 P 和的点

(b) 在每个矩形内,距离 P 正好有一个点

我必须找到覆盖 P 中所有点的最小矩形数量。这里绘制了一个示例:http://i5.minus.com/jC5LnVhjk6soT.png 紫色线表示不正确的划分,因为上面的矩形不包含 P 中的点。然而,蓝线是完全可以的,因为两个矩形都有一个从 P 开始的点,所以正确的输出应该是:2,因为这是矩形的最小数量。

有人知道找到最小数字的算法/方法吗?

【问题讨论】:

我会查看动态编程解决方案。 有一件事我不清楚:如何创建这些矩形? (例如,2x2 矩形是有效的吗?) 如果每个矩形都必须包含一个点,那么你需要正好 |P|矩形。边角上的点呢?他们被允许吗?如果是,它们是否计算所有相邻的矩形,它们都不计算或不同的东西? 重读问题后,我猜边角上的点是允许的,有时甚至是必需的,但不算在任何矩形内,对吧? 丹尼尔,没错。每个矩形内必须恰好有一个点,但边缘/角上的这些点不算在内。边缘上的点可能很多。所以例如你可以在 P 中有 12 个点,但只形成 2 个矩形,因为其中 10 个在一条直线上,另外两个算作其中的点。您需要边缘上的这些点来创建分割线。你不能随心所欲地越线:) 【参考方案1】:

根据您的规范,我最终得到了这个递归算法:(伪代码~ruby 实现)

def resolve R, P
    if P.empty?
        return nil
    elsif P.size == 1
        return 1
    end

    results = []

    P.each do |p|
        rect1, rect2 = split_vertical(R, P, p)
        s1 = split_resolve(rect1, rect2)

        rect1, rect2 = split_horizontal(R, P, p)
        s2 = split_resolve(rect1, rect2)

        results.push [s1, s2].min
    end

    return results.min
end


def split_resolve rect1, rect2
    sum1 = resolve(rect1.R, rect1.P)
    sum2 = resolve(rect2.R, rect2.P)

    if !sum1.nil? and !sum2.nil?
        return sum1 + sum2
    else
        return nil
    end
end

函数split_verticalsplit_horizontal 用通过点p 的垂直线和水平线分割区域R

您还可以使用动态规划优化此算法。您可以存储子矩形的结果,而无需再次计算。当多个点位于同一条线上时会发生这种情况。

ps : 不要复制原始源代码,nil 成语可能会出现一些问题。这只是整个过程的伪代码示例。

【讨论】:

这个算法如何使用动态规划技术 它递归地将主要问题分解为两个子问题。 确实如此,所以它递归地解决了问题,而不是动态地 我可能在正确的术语上错了。如果我的子问题与原始问题不同,它会是动态的吗? Here 是将动态规划应用于背包问题的一个很好的例子。

以上是关于找到最小矩形数量的算法的主要内容,如果未能解决你的问题,请参考以下文章

什么算法可用于以相当优化的方式将不同大小的矩形打包成最小的矩形?

凸包多边形最小外切矩形算法

数据结构与算法之深入解析“最小矩形面积”的求解思路与算法示例

我需要一种算法,可以适应任何大小的n个矩形,在较大的矩形中最小化其面积

leetcode 452 用最少数量的箭引爆气球 贪心算法

leetcode 452 用最少数量的箭引爆气球 贪心算法