gomory_hu_tree#
- gomory_hu_tree(G, capacity='capacity', flow_func=None)[source]#
返回无向图 G 的 Gomory-Hu 树。
无向图的 Gomory-Hu 树是一个加权树,表示图中所有 s-t 对的 最小 s-t 割。
它只需要
n-1次最小割计算,而不是明显的n(n-1)/2次。 该树表示所有 s-t 割,因为任意一对节点之间的最小割值是 Gomory-Hu 树中这两节点之间最短路径上的最小边权重。Gomory-Hu 树还具有以下性质:删除任意两节点之间最短路径上 的最小权重边后,剩下的两个连通分量形成了 G 中节点的划分, 定义了最小 s-t 割。
详见下面的示例部分。
- Parameters:
- GNetworkX 图
无向图
- capacity字符串
图 G 的边应具有一个 capacity 属性,表示该边能支持的流量。 如果该属性不存在,则认为该边具有无限容量。默认值:’capacity’。
- flow_func函数
执行底层流量计算的函数。默认值:
edmonds_karp()。 该函数在具有右尾度分布的稀疏图中表现更好。shortest_augmenting_path()在更密集的图中表现更好。
- Returns:
- TreeNetworkX 图
表示输入图的 Gomory-Hu 树的 NetworkX 图。
- Raises:
- NetworkXNotImplemented
如果输入图是有向图,则引发此异常。
- NetworkXError
如果输入图是空图,则引发此异常。
See also
Notes
此实现基于 Gusfield 的方法 [1] 来计算 Gomory-Hu 树, 该方法不需要节点收缩,并且具有与原始方法相同的计算复杂度。
References
[1]Gusfield D: Very simple methods for all pairs network flow analysis. SIAM J Comput 19(1):143-155, 1990.
Examples
>>> G = nx.karate_club_graph() >>> nx.set_edge_attributes(G, 1, "capacity") >>> T = nx.gomory_hu_tree(G) >>> # G 中任意一对节点之间的最小割值是 ... # Gomory-Hu 树中这两节点之间最短路径上的最小边权重。 ... def minimum_edge_weight_in_shortest_path(T, u, v): ... path = nx.shortest_path(T, u, v, weight="weight") ... return min((T[u][v]["weight"], (u, v)) for (u, v) in zip(path, path[1:])) >>> u, v = 0, 33 >>> cut_value, edge = minimum_edge_weight_in_shortest_path(T, u, v) >>> cut_value 10 >>> nx.minimum_cut_value(G, u, v) 10 >>> # Gomory-Hu 树还具有以下性质:删除任意两节点之间最短路径上 ... # 的最小权重边后,剩下的两个连通分量形成了 G 中节点的划分, ... # 定义了最小 s-t 割。 ... cut_value, edge = minimum_edge_weight_in_shortest_path(T, u, v) >>> T.remove_edge(*edge) >>> U, V = list(nx.connected_components(T)) >>> # 因此 U 和 V 形成了一个划分,定义了 G 中 u 和 v 之间的最小割。 ... # 你可以用这些信息计算边割集,即,如果从 G 中移除这些边, ... # 将使 u 和 v 在 G 中不连通: ... cutset = set() >>> for x, nbrs in ((n, G[n]) for n in U): ... cutset.update((x, y) for y in nbrs if y in V) >>> # 因为我们设置了所有边的容量为 1 ... # 所以割集包含十条边 ... len(cutset) 10 >>> # 你可以使用任何最大流算法进行底层流量计算, ... # 使用 flow_func 参数 ... from networkx.algorithms import flow >>> T = nx.gomory_hu_tree(G, flow_func=flow.boykov_kolmogorov) >>> cut_value, edge = minimum_edge_weight_in_shortest_path(T, u, v) >>> cut_value 10 >>> nx.minimum_cut_value(G, u, v, flow_func=flow.boykov_kolmogorov) 10