【发布时间】:2008-11-15 22:41:08
【问题描述】:
假设我有一个区间 (a,b) 和多个子区间 {(ai,bi)}i其并集是 (a,b) 的全部。有没有一种有效的方法来选择这些子区间的最小基数子集,它仍然覆盖 (a,b)?
【问题讨论】:
-
您是在寻找最少数量的子区间,还是寻找元素最少(因此重复次数最少)的子区间集?
标签: algorithm optimization math geometry
假设我有一个区间 (a,b) 和多个子区间 {(ai,bi)}i其并集是 (a,b) 的全部。有没有一种有效的方法来选择这些子区间的最小基数子集,它仍然覆盖 (a,b)?
【问题讨论】:
标签: algorithm optimization math geometry
从 a 或 b 开始的贪心算法总是给出最优解。
证明:考虑覆盖a的所有子区间的集合Sa。显然,其中之一必须属于最优解。如果我们用右端点 bmax 的 Sa 的子区间 (amax,bmax) 替换它在 Sa 中最大(到达最右边),剩余的未覆盖区间 (bmax,b) 将是最优解的剩余区间的子集,所以它不能被比最优解的类似未覆盖区间更多的子区间覆盖。因此,由 (amax,bmax) 和剩余区间 (bmax,b) 的最优解构成的解也将是最优的。
所以,只需从 a 开始,然后迭代地选择到达最右边的区间(并覆盖前一个区间的末尾),重复直到你点击 b。我相信如果您将区间存储在扩充区间树中,则可以在 log(n) 中选择下一个区间。
【讨论】:
听起来像动态编程。
这里是算法的说明(假设间隔在一个按结束时间排序的列表中):
//works backwards from the end
int minCard(int current, int must_end_after)
{
if (current < 0)
if (must_end_after == 0)
return 0; //no more intervals needed
else
return infinity; //doesn't cover (a,b)
if (intervals[current].end < must_end_after)
return infinity; //doesn't cover (a,b)
return min( 1 + minCard(current - 1, intervals[current].start),
minCard(current - 1, must_end_after) );
//include current interval or not?
}
但它也应该涉及缓存(记忆)。
【讨论】:
minCard() 旨在获得最小基数,但问题要求具有最小基数的子集。
有两种情况需要考虑:
情况1:在一个区间的结束时间之后没有重叠的区间。在这种情况下,选择开始时间最短、结束时间最长的下一个区间。 (amin, bmax)。
情况 2:有 1 个或多个间隔与您正在查看的最后一个间隔重叠。在这种情况下,开始时间无关紧要,因为您已经涵盖了这一点。所以优化完成时间。 (a, bmax)。
案例 1 也总是选择第一个区间作为最优集中的第一个区间(证明与 @RafalDowgrid 提供的相同)。
【讨论】:
time 的头在哪里?
您的意思是,子区间仍然以这样的方式重叠,使得 (a,b) 在所有点上都保持完全覆盖?
也许将子区间本身拆分为与其来源相关联的基本块,因此您可以列出每个基本块区间的选项,同时考虑子区间覆盖的其他区域。然后,您可以使用基于每个子子间隔的搜索,并且至少确保没有留下任何间隙。
然后需要搜索..有效..这会更难。
可以消除任何完全被另一组较小数字覆盖的区间集合,并在预处理后解决问题。
对整体的最小化不就是对至少一半的最小化吗?我不知道。
在日记中找到link,但无法阅读。 :(
这将是一个hitting set 问题,通常是 NP_hard。
也无法阅读this,但看起来是相反的问题。
无法阅读,但另一个 link 提到了拆分间隔。
Here 是有关几何优化问题的随机算法的可用参考。
此 pdf 的页面 35 有一个贪心算法。
Karp (1972) 的第 11 页提到 hit-set 并被大量引用。
谷歌result。研究很有趣,但我现在得走了。
【讨论】: