当前位置: 首页 > 知识库问答 >
问题:

找到重叠区间的最小子集

关飞翼
2023-03-14

考虑一个问题来寻找区间图的最小支配集。在区间调度的上下文中,它被转换为以下问题:

存在多个可能相互重叠的间隔。找到区间的最小子集,以便对于未包含在子集中的每个区间,它将在与它重叠的子集中找到至少1个区间。

有一个公认的贪婪解决方案可从互联网上的各种来源,例如康奈尔大学的一个解决方案http://www.cs.cornell.edu/Courses/cs4820/2011sp/handouts/samplesolutions.pdf

我们的工作是填充一组C,组成委员会(区间子集)。我们使用一组M来保持“覆盖”的时间间隔以便记账。

  1. 按最早完成时间和最早完成时间对间隔进行排序。
  2. 取S中最早完成时间的间隔i。
  3. 构造集O={s≥S|s相交i}
  4. 取最晚结束时间的o⑵O并将o加到C,将所有与o相交的区间加到M
  5. 重复2-4,直到覆盖所有间隔。

这类似于interjay在2012年SO上提供的投票结果:找到最小的重叠作业集

但我注意到一个反例,证明上述解决方案不产生最小子集:

考虑区间:[0,2]、[1,4]、[3,10]、[5,6]、[7,8]、[9,10]。

最小子集应具有2个间隔:[3,10]加上[0,2]或[1,4]。

但是上述解决方案将返回4个间隔的子集:[1,4]、[5,6]、[7,8]和[9,10]。最长的间隔[3,10]在步骤4被过早拒绝。

还有比上面贴的更好的贪婪解决方案吗?谢谢!

共有1个答案

裴威
2023-03-14

你引用的算法是不正确的,因为集合S永远不会改变,所以在第2步中,将始终选取相同的间隔,并且你将进入一个无限循环。如果将步骤2更改为“以最早完成时间为单位,以S-M为间隔i。”,这将是正确的。

然而,你所链接的我的答案是正确的。它和上面的修正算法都将给出一个集{[1,4],[3,10]},作为您的示例。

您所犯的错误可能是,在上面的步骤3(或我的链接答案中的步骤2)中,您只查看S-M中的集合(在我的答案中称为A)。但你应该看看所有与i相交的间隔,即使它们已经在M中了。

 类似资料:
  • 我正在学习贪婪算法,遇到了一个我不知道如何解决的问题。给定一组开始时间为a,结束时间为b的区间(a,b),给出一个贪婪算法,该算法返回该集合中每隔一个区间重叠的最小区间数。例如,如果我有: (1,4) (2,3) (5,8) (6,9) (7,10) 我将返回(2,3)和(7,8),因为这两个区间覆盖了集合中的每个区间。我现在得到的是: 通过增加结束时间对间隔进行排序 将结束时间最小的间隔推到堆栈

  • 给定一个数组< code>a[0..< code>0之间的整数的N-1] 例: 输入 预期输出:

  • 问题内容: 假设您有一个包含标识符,开始时间和结束时间的表。这些开始和结束时间可以是任何时间长度。开始时间总是早于结束时间。假设没有空值。 哪种查询会告诉我最“受欢迎”的时间,即每行中的两个范围与其他大多数行重叠的地方? 现实生活中的应用是,它是一个记录用户登录和注销时间的表格。我想编写一个查询,该查询将告诉我何时有最多并发用户登录,并查看这段时间。 谢谢你。 问题答案: 这是使用简单自连接和a的

  • 我试图在N大小的数组的k个元素中找到最小和次最小的元素(没有排序和最小/最大堆)。 使用传统的方法,首先从第< code>0个元素开始,在第< code>k个元素中找到最小的和第二小的元素,然后将起始点移动< code>1并重复该过程。但是它的复杂度是< code>O(Nk)。如果可能,我需要一个复杂度为< code>O(N)的解决方案。对此有什么建议吗? 在Jubobs的注释后编辑:例如,如果s

  • 问题内容: 我在数据库中有2个表,这些表具有以下属性: 第二个表是“预订”和“资源”之间的关联实体(即1个预订可以包含许多资源)。属性booking_start和booking_end是带有日期和时间的时间戳。 我是否可以知道如果日期/时间与其他类似resource_id的预订重叠或冲突,我如何能够找到每个resource_id(预订的)? 我以图形方式在纸上涂上答案,以查看它是否可以帮助我形象化

  • 我有一组可能重叠的输入日期范围。我想创建具有调整日期的新日期范围,而不是组合这些重叠的日期范围,例如: 最终应为: 有没有有效的方法用Java解决这个问题? 提前感谢! 更新:在我的第一个问题中,我没有提到我自己的方法,所以它是这样的:我简单地获取间隔的开始和结束日期,并将其添加到一个排序的集合中。之后,我会遍历集合并根据重新排序的日期创建新的间隔。