Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 网络流:添加新边缘_Java_C++_Performance_Algorithm_Data Structures - Fatal编程技术网

Java 网络流:添加新边缘

Java 网络流:添加新边缘,java,c++,performance,algorithm,data-structures,Java,C++,Performance,Algorithm,Data Structures,在最近的一次竞赛中,我被要求设计一个算法,对于一个有V个顶点和E个边的网络,如果通过添加一条边(其容量应为1)来增加最大流量。也就是说,我们必须设计这样一个算法来找到这样的边 算法应该比O(| E |*h(| V | E |))更快,其中h(|V | E |)是计算最大流量所花费的时间 提前谢谢。如果不清楚,请告诉我。根据最大流量最小切割定理[1],网络中的最大流量等于最小切割中所有边权重的总和。因此,解决方案可能如下所示: 通过使用Edmonds-Karp算法(Ford-Fulkerson算

在最近的一次竞赛中,我被要求设计一个算法,
对于一个有V个顶点和E个边的网络,如果通过添加一条边(其容量应为1)来增加最大流量。
也就是说,我们必须设计这样一个算法来找到这样的边

算法应该比
O(| E |*h(| V | E |))
更快,其中
h(|V | E |)是计算最大流量所花费的时间


提前谢谢。如果不清楚,请告诉我。

根据最大流量最小切割定理[1],网络中的最大流量等于最小切割中所有边权重的总和。因此,解决方案可能如下所示:

  • 通过使用Edmonds-Karp算法(Ford-Fulkerson算法的一种特化)等方法,找到总边重
    X
    的最小切割。根据[1],这是在
    O(h | V | E |)
  • 添加一条边,该边连接属于切割
    (S,S')
    的不同分区的节点,即添加一条边
    (u,v)
    ,其中
    u
    位于
    S
    中,
    v
    位于
    S'
  • 重复此操作,直到没有更多的切割具有总边缘重量
    X
    • (菲利普所说的修正版本)计算最大流量。提取一个无容量限制的有向图,该图由具有正剩余容量的弧组成。当且仅当存在从源到尾和从头到汇的路径时,添加特定弧会增加最大流量,即弧的引入会创建一条增大路径


      在你的例子
      {s->a,a->b,a->c,a->d,b->t,c->t,d->t}
      中,最大的流量是
      s-3>a,a-1>b,a-1>d,b-1>t,c-1>t,d,d-1>t
      ,残差图有每个向后的弧
      {a->{s,b->a,c->a,d->a,d->a,t,t-b,t-c,t>d
      。从
      s
      可以到达的顶点是
      {s}
      ,从
      t
      可以到达的顶点是
      {t}
      ,因此唯一可以增加最大流量的单弧是
      s->t

      我认为解决方案可以是:

    • 首先运行最大流算法。现在,我们有残差图G
    • 然后我们找到所有边(u,v),这样在剩余图G中,我们可以找到从s到u的路径和从v到t的路径

    • 最坏情况下的复杂性是O(|V|^2(|V|+|E|)+h(|V|E|))。

      另一种解决方案可能是:

      第一步。查找包含最小顶点数的最小切割(称其顶点为Vmin)

      第二步。找到包含最大顶点数的最小切割(称其顶点为Vmax)

      第三步。查找链接Vmin和V\Vmax但不是E的一部分的所有边

      为什么这样做有效?(一) 如果新uv边包含在每个最小切割中(准确地说:如果它链接最小切割的不同组件),并且(II)最小切割的“组”与并集和交集很接近,则添加新uv边是好的

      复杂性:

      对于步骤1,2,我发现了以下不错的算法:。这可以用于查找具有最小和最大顶点的最小切割。这似乎是在h(| E | | V |)+O(| V | ^3)中运行的,当您检查BFS是否结束(即不再存在新的剩余相邻)时,O(| V | ^3)来自BFS

      对于步骤3,当有O(|Vmin |*| V\Vmax |)时,即为O(| V | ^2)

      因此,步骤1,2,3=h(| E | V |)+O(| V |^3)


      请注意,这只是一个简单的示意图:)

      我认为这并不总是可行的。考虑下面的情况:<代码> {S->A,A->B,A->C,A->D,B>T,C>T,D>T } <代码> >边>代码> S->A < /代码>权重3,所有其他边具有权重1。然后,在s和s'中分别有{s,a},{b,c,d,t}。现在从
      a->t
      添加边仍然不会增加最大流量。@凯文:你的切割权重为3,但切割权重为1:S={S},S'={a,b,c,d,t}。不过,并不是所有的边都能增加最大流量。@ErikP。边
      s->a
      的权重为3,如我在第一条评论中所述。所以你考虑的重量也会是3。因此,我的切割也是有效的,然后算法在这种情况下失败。我说的对吗?对不起,我不知怎么错过了“重量3”部分。你说得对。我不明白你的复杂性计算。它不应该是
      O(| V | ^3+h(| E | V |)吗
      ,因为我们只是试图在
      O(| V |)中找到从s到u和从V到t的路径,每个可能边的时间,即
      O(| V | ^2)
      对不起,我弄错了。第一步(查找最大流)的复杂性是h(| E | V |)。对于第二步,我们必须检查所有顶点对(u,v);对于每一对(u,v),我们必须在残差图中运行BFS(或DFS)以找到从s到u和v到t的路径。BFS的复杂性是O(| v |+| E |)。因此,第二步的复杂性是O(| v | ^2(| v |+| E |))。