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 |))。