【问题标题】:Fast algorithm for selecting two intervals from this set从该集合中选择两个区间的快速算法
【发布时间】:2012-06-02 03:18:02
【问题描述】:

假设给定一组闭区间,其中每个区间的形式为 [l,r]。如果我们想从这个集合中选择两个区间,使得它们的交集的大小乘以它们的并集的大小是最大值。我们能否提供一个非平凡的算法来解决这个问题?

例如,如果我们有四个区间,[1,6]、[4,8]、[2,7]、[3,5]。最佳解决方案是选择[1,6]和[2,7]。答案是 (7-1) * (6-2) = 24。

其实原问题需要我们选择(N>=2)个区间,但我认为我们可以证明最优解只包含两个区间:

如果最优解具有三个或更多区间:

[                     ]
            [               ]
                   [                          ]

我们可以看到,如果我们删除中间区间,权重不会减少。

【问题讨论】:

  • 你看动态编程来解决这个问题了吗?
  • @Nupul 我试过了,但不知道如何使用动态编程来解决这个问题......
  • 为什么你认为你只需要 2 个间隔?如果给您[3,5]、[-100,5] 和[3,100],该怎么办?你不会三个都选吗?
  • @RayToal 当我们选择所有三个时,它们的交集仅为 [3,5],因此权重为 [3,5] * [3,5] = 4。但是如果我们选择 [- 100, 5] 和 [3, 100] 更好,因为权重是 [-100, 100] * [3, 5] = 400。
  • 那我不明白你的问题。如果我选择所有三个,交叉点是[3,5]。但是这三个的联合是[-100, 100]。您为此拥有的值也是 400。哦,我看到 this 案例为什么两个间隔就足够了。但你确定一般吗?

标签: algorithm


【解决方案1】:

给定一组 N > 2 个重叠区间,这些区间可以最大化联合时间的交集,留出一个包含联合中最左边点的区间和一个包含联合中最右边点的区间。由于 N > 2,您至少还有一个其他区间。如果从集合中删除此区间,则不会减小区间并集的大小,因为您留出了区间以覆盖最左边和最右边的点。您只能通过删除间隔来增加交叉点的大小。因此,通过删除此间隔,您只能增加您试图最大化的产品,因此确实可以在 N = 2 处找到最佳解决方案。

对区间的端点集进行排序,并按升序遍历它。在平局的情况下,在最右边的点之前考虑最左边的点。跟踪一组区间,当您看到其最左边的点时向该集合添加一个区间,并在您看到其最右边的点时从该集合中删除一个区间。

对于任何两个重叠的间隔,当其中一个已经存在并且您正要添加另一个时,将会有一个点。因此,如果在将区间添加到集合之前,将其与集合中已有的所有其他区间进行比较,则可以比较所有重叠区间对。因此,您可以计算即将添加的区间与集合中所有其他区间之间的并集和交集的乘积,并跟踪看到的最大区间。

【讨论】:

  • 我认为这个算法是 O(n^2)。如果所有区间都相同,则需要 n*(n-1)/2 次比较。
  • 绝对是 N^2 最坏的情况。但由于我想不出更好的办法,而且我们从一个案例开始,我们甚至不确定 N=2 是否总能给出最佳解决方案,所以我想我会记下一些实际可行的东西,然后如果没有大量的重叠间隔,那将做得相当好(n log n 排序时间)。
【解决方案2】:

证明两个区间就足够了:选择适当包含在另一个区间中的区间是没有意义的。不失一般性,让区间为 [a1, b1], ..., [an, bn] 使得 a1

O(n log n)-time算法:重新表述,问题是找到区间[a, b]和[c, d]最大化(d - a) * (b - c ),因为如果区间不相交,则此乘积为负。我们的算法是进行 O(n log n) 预处理,使我们能够在 O(log n) 时间内为每个间隔找到最佳配对。

让我们努力为 [a, b] 寻找最佳伴侣。做一些代数:(d - a) * (b - c) = d*b - d*c - a*b + a*c。由于 a, b 是固定的,我们可以去掉 -a*b 项并在所有区间 [c, d] 上最大化内积 。由于向量集 (d, c, -d*c) 是固定的,这本质上是模拟静止多面体与垂直于 (a, b, 1) 的移动平面的碰撞。感谢 Edelsbrunner 和 Maurer (Finding extreme points in three dimensions and solving the post-office problem in the plane, 1984),有一种算法可以在 O(n log n) 时间内进行预处理,并在 O(log n) 时间内解决不同 a 和 b 的此类查询。

一个糟糕的细节是我们必须至少选择两个区间,但最好的“解决方案”可能只是与自身最长的区间。我相信这很麻烦,但可以扩展 Edelsbrunner--Maurer 以在相同的运行时间内找到第二个最极端的点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    相关资源
    最近更新 更多