流通问题的“下界”是什么意思?

时间:2012-05-13 09:51:50

标签: c++ data-structures graph-theory directed-graph

问题:循环问题允许您在通过特定弧的流量上具有下限和上限。我理解的上界(就像管道一样,只有很多东西可以通过)。但是,我很难理解下限的想法。这是什么意思?是一种解决问题的算法......

  • 尝试确保每个具有下限的弧线至少会获得那么大的流量,如果找不到方法则完全失败?
  • 如果不能满足下限,只需忽略弧线?这对我来说更有意义,但是意味着在结果图中可能存在流量为0的弧,即lower ≤ f ≤ upper v f = 0

上下文:我正在尝试找到一种方法来快速安排一组事件,每个事件都有一个长度和一组可能的时间来安排。我正在尝试将此问题简化为循环问题,因为存在有效的算法。

我将每个事件作为一个节点放在有向图中,并为它提供应该填充的时隙量。然后我将所有可能的时间添加为节点,最后添加所有时间段,如下所示(所有弧点都指向右侧):

My graph

前两个事件有一个可能的时间,长度为1,最后一个事件的长度为4,可能有两个。

这个图表有意义吗?更具体地说,“填充”的时段数量是2(只有'简单')还是6,如图所示?

(我正在使用LEMON库中的push-relabel算法,如果这有任何区别的话。)

2 个答案:

答案 0 :(得分:4)

关于一般流通问题:

我同意@Helen;尽管设想下限的实际使用可能不那么直观,但是必须的约束。即使流量为零,我也不相信你能够忽略这个约束。

flow = 0的情况诉诸于更直观的最大流问题(正如@KillianDS所指出的那样)。在这种情况下,如果一对节点之间的流量为零,那么它们不会影响“流量和的守恒”: enter image description here

当没有给出下界时(假设流是非负的),零流不能影响结果,因为

  1. 它不能对约束引入违规行为
  2. 它不能影响总和(因为它增加了一个零项)。
  3. 由于某些外部约束(相关问题需要至少X水通过某个管道,如@Helen所指出的),可能存在最小流量的实际示例。下限约束也可能来自等效的对偶问题,其使流量最小化,使得某些边缘具有下限(并且找到与具有上限的最大化问题的最佳等效)。

    针对您的具体问题:

    看起来你正试图在固定的一组时隙中完成尽可能多的事件(在一个时隙中没有两个事件可以重叠)。

    考虑可以分配给给定事件的时隙集:

      

    E1 - {9:10}
      E2 - {9:00}
      E3 - {9:20,9:9,9:40,9:50}   E3 - {9:00,9:10,9:20,9:30}

    因此,您希望最大化任务分配的数量(即,事件发生在“打开”边缘的事件)s.t.得到的集合是成对不相交的(即没有指定的时隙重叠)。

    我认为这是NP-Hard,因为如果你能解决这个问题,你可以用它来解决maximal set packing problem(即最大集合包装减少到此)。您的问题可以通过整数线性编程来解决,但在实践中,这些问题也可以通过贪婪的方法/分支和绑定很好地解决。

    例如,在您的示例问题中。事件E1与E3“冲突”,E2与E3冲突。如果分配了E1(只有一个选项),则只剩下一个可能的E3分配(后一个分配)。如果对E3进行此分配,那么E2只剩下一个分配。此外,可以单独解决不相交的子图(不可能与资源冲突的事件集)。

    如果是我,我会从一个非常简单的贪婪解决方案开始(首先分配具有较少可能“槽”的任务),然后将其用作分支和绑定求解器的种子(如果贪婪解决方案找到4个任务赋值,然后绑定,如果你的递归子任务不能超过3)。您甚至可以通过创建集合之间的成对交叉图表来挤出一些额外的性能,并且仅在进行分配时通知相邻的集合。你可以在继续分支和绑定时更新你的最佳作业数量(我认为这是正常的),所以如果你早点运气,你会很快收敛。

    我使用同样的想法找到可以解释一组已鉴定的肽(蛋白质片段)的最小蛋白质组,并发现它对于实际问题已经足够了。这是一个非常相似的问题。

    如果您需要前沿性能: 重新定义时,整数线性编程几乎可以完成您想要的任何此类问题的变体。当然,在非常糟糕的情况下,它可能会很慢(实际上,它可能适合您,特别是如果您的图形不是非常密集地连接)。如果不是这样,常规线性编程松弛近似于ILP的解决方案,并且通常对这类问题非常有利。

    希望这有帮助。

答案 1 :(得分:1)

弧流的下限是一个硬约束。如果不能满足约束,则算法失败。在你的情况下,他们肯定无法满足。

即使是下限,也无法使用纯网络流模型建模您的问题。您试图获得流量为0或至少某个下限的约束。这需要整数变量。但是,LEMON包有一个interface,您可以在其中添加整数约束。每个第一层弧的流出必须是0或n,其中n是所需时隙的数量,或者你可以说每个“事件”中至多有一个弧具有非零流。

你的“脱节”约束,  lower ≤ f ≤ upper v f = 0 可以建模为

f >= y * lower
f <= y * upper

y限制为0或1.如果y为0,则f只能为0.如果y为1,则f可以是低位和高位之间的任何值。混合整数编程算法比网络流算法慢几个数量级,但它们会模拟你的问题。