我正在寻找一种可以用来解决这个问题的算法,而不是代码。我想知道使用线性编程和放松,但也许有更有效的方法来解决这个问题?
问题
我有一组重量间隔。间隔可以重叠。我需要找到析取区间子集的最大权重和。
示例
重量间隔:
|--3--| |---1-----| |----2--| |----5----|
答案:8
答案 0 :(得分:2)
如果没有重量,你很容易使用贪婪算法,按时间间隔对它们进行排序,并在每一步中得到最小的结束时间间隔。
但是在你的情况下我认为它是NPC(应该考虑一下),但你可以使用类似的贪婪算法,按每个时间间隔乘以Weigth / Length,并且每次以排序格式得到一个可能的间隔,也可以使用模拟退火,意味着每次您通过概率P
(p接近1
)获得上述值的最佳答案,或者选择概率为1的另一个区间 - P
。你可以在n
次循环中进行,以找到一个好的答案。
答案 1 :(得分:2)
这是一个想法:
请考虑以下图表:为每个间隔创建一个节点。如果间隔I1和间隔I2不重叠且I1在I2之前,则从节点I1向节点I2添加有向边。请注意,此图表是非循环的。每个节点的成本等于相应间隔的长度。
现在,我们的想法是找到此图中最长的路径,可以在非循环图的多项式时间中找到(例如,使用动态编程)。问题是成本是在节点中,而不是在边缘。这是一个技巧:将每个节点v分成v'和v''。进入v的所有边缘现在将进入v',离开v的所有边缘现在将离开v''。然后,使用节点的开销,从v'到v''添加边,在这种情况下,是间隔的长度。所有其他边缘的成本为0。
好吧,如果我没弄错,这张图中最长的路径将对应于具有最大总和的不相交间隔的集合。
答案 2 :(得分:1)
您可以将此问题表示为一般IP(整数编程)问题,其中二进制变量指示是否选择了间隔。然后,目标函数将是变量的加权线性组合。然后,您需要适当的约束来强制间隔中的析取...这应该足以满足homework
标记。
另外,仅仅因为问题可以表示为整数程序(求解是NP-Hard),并不意味着问题类本身就是NP-Hard。因此,正如Ulrich指出的那样,可能存在一个多项式可解的公式/算法,例如将问题表述/解决为线性程序。
答案 3 :(得分:1)
我有一个精确的O(nlog n)DP算法。由于这是家庭作业,这里有一个线索:
按照Saeed的建议,按右边缘位置对间隔进行排序,然后从1开始对它们进行编号。将f(i)定义为可以通过仅使用不延伸到右边缘右边的间隔来获得的最高权重。 / p>
编辑:线索2:按i的递增顺序计算每个f(i)。请记住,每个间隔都将存在或不存在。要计算“当前”案例的分数,您需要寻找与间隔i兼容的“最右边”间隔,这需要通过您已经计算过的解决方案进行二进制搜索。
这是一个很大的问题,不确定如果没有完全拼写出来,我可以提供更多线索;)
答案 4 :(得分:0)