本文简要介绍 python 语言中 scipy.sparse.csgraph.maximum_flow
的用法。
用法:
scipy.sparse.csgraph.maximum_flow(csgraph, source, sink)#
最大化图中两个顶点之间的流。
- csgraph: csr_matrix
表示有向图的方阵,其第 (i, j) 项是一个整数,表示顶点 i 和 j 之间的边的容量。
- source: int
流从中流出的源顶点。
- sink: int
流流向的汇顶点。
- method: {‘edmonds_karp’, ‘dinic’}, optional:
用于计算最大流量的方法/算法。支持以下方法,
默认为‘dinic’。
- res: MaximumFlowResult
由
MaximumFlowResult
表示的最大流,包括flow_value
中的流值和flow
中的流图。
- TypeError::
如果输入图不是 CSR 格式。
- ValueError::
如果容量值不是整数,或者源或接收器超出范围。
参数 ::
返回 ::
抛出 ::
注意:
这解决了给定有向加权图上的最大流问题:流与每条边相关联的值,也称为流,小于边的容量,因此对于每个顶点(除了源顶点和汇顶点) ,总流入流量等于总流出流量。流的值是离开源顶点的所有边的流的总和,最大流问题包括找到值最大的流。
根据max-flow min-cut定理,流的最大值也是最小割中边的总权重。
为了解决这个问题,我们提供了Edmonds-Karp [1] 和 Dinic 算法 [4]。两种算法的实现都力求利用稀疏性。前者的时间复杂度为 ,其空间复杂度为 。后者通过构建级别图并在其中找到阻塞流来实现其性能。它的时间复杂度是 ,它的空间复杂度是 。
最大流量问题通常用实值容量来定义,但我们要求所有容量都是不可分割的,以确保收敛。在处理有理容量或某些固定 属于 的容量时,可以通过相应地缩放所有容量来将问题简化为整数情况。
解决 maximum-flow 问题可用于例如计算机视觉中的图割优化 [3]。
参考:
[1] (1,2)Edmonds, J. 和 Karp, R. M. 网络流问题算法效率的理论改进。 1972. ACM 杂志。 19 (2): 第 248-264 页
[2]Cormen, T. H. 和 Leiserson, C. E. 以及 Rivest, R. L. 和 Stein C. 算法导论。第二版。 2001. 麻省理工学院出版社。
[4] (1,2)Dinic, Efim A. 用功率估计解决网络中最大流量问题的算法。在苏联数学。多克拉迪,第一卷。 11,第 1277-1280 页。 1970 年。
例子:
也许最简单的流问题是只有两个顶点的图,其边从源 (0) 到汇 (1):
(0) --5--> (1)
这里,最大流量就是边的容量:
>>> import numpy as np >>> from scipy.sparse import csr_matrix >>> from scipy.sparse.csgraph import maximum_flow >>> graph = csr_matrix([[0, 5], [0, 0]]) >>> maximum_flow(graph, 0, 1).flow_value 5 >>> maximum_flow(graph, 0, 1, method='edmonds_karp').flow_value 5
另一方面,如果源和接收器之间存在瓶颈,则可以减少最大流量:
(0) --5--> (1) --3--> (2)
>>> graph = csr_matrix([[0, 5, 0], [0, 0, 3], [0, 0, 0]]) >>> maximum_flow(graph, 0, 2).flow_value 3
[2] 的第 26.1 章给出了一个不那么简单的例子:
>>> graph = csr_matrix([[0, 16, 13, 0, 0, 0], ... [0, 0, 10, 12, 0, 0], ... [0, 4, 0, 0, 14, 0], ... [0, 0, 9, 0, 0, 20], ... [0, 0, 0, 7, 0, 4], ... [0, 0, 0, 0, 0, 0]]) >>> maximum_flow(graph, 0, 5).flow_value 23
可以将在二分图中找到最大匹配的问题简化为最大流问题:让 为二分图。然后,向图中添加一个源顶点,该顶点与 中的每个顶点的边,以及一个与 中每个顶点的边的汇顶点。最后,给结果图中的每条边赋予 1 的容量。然后,新图中的最大流给出原始图中的最大匹配,该匹配由 中流为正的边组成。
假设边由CSR格式的
maximum_bipartite_matching
所需的形式。然后上面构造的图的 CSR 表示包含这个矩阵作为一个块。这是一个例子: 矩阵表示,如果从 到 有边,则其 'th entry为1,否则为0;也就是说,输入是>>> graph = csr_matrix([[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 1, 0]]) >>> print(graph.toarray()) [[0 1 0 1] [1 0 1 0] [0 1 1 0]] >>> i, j = graph.shape >>> n = graph.nnz >>> indptr = np.concatenate([[0], ... graph.indptr + i, ... np.arange(n + i + 1, n + i + j + 1), ... [n + i + j]]) >>> indices = np.concatenate([np.arange(1, i + 1), ... graph.indices + i + 1, ... np.repeat(i + j + 1, j)]) >>> data = np.ones(n + i + j, dtype=int) >>> >>> graph_flow = csr_matrix((data, indices, indptr)) >>> print(graph_flow.toarray()) [[0 1 1 1 0 0 0 0 0] [0 0 0 0 0 1 0 1 0] [0 0 0 0 1 0 1 0 0] [0 0 0 0 0 1 1 0 0] [0 0 0 0 0 0 0 0 1] [0 0 0 0 0 0 0 0 1] [0 0 0 0 0 0 0 0 1] [0 0 0 0 0 0 0 0 1] [0 0 0 0 0 0 0 0 0]]
此时,我们可以找到添加的Sink和添加的Source之间的最大流量,并且通过将流量函数限制在原始图对应的块上可以得到所需的匹配:
>>> result = maximum_flow(graph_flow, 0, i+j+1, method='dinic') >>> matching = result.flow[1:i+1, i+1:i+j+1] >>> print(matching.toarray()) [[0 1 0 0] [1 0 0 0] [0 0 1 0]]
这告诉我们 中的第一个、第二个和第三个顶点分别与 中的第二个、第一个和第三个顶点匹配。
虽然这通常解决了最大二分匹配问题,但请注意,专门针对该问题的算法,例如
maximum_bipartite_matching
,通常会表现得更好。这种方法也可用于解决最大二分匹配问题的各种常见推广。例如,如果某些顶点可以与多个其他顶点匹配,则可以通过适当地修改新图的容量来处理。
相关用法
- Python SciPy csgraph.maximum_bipartite_matching用法及代码示例
- Python SciPy csgraph.min_weight_full_bipartite_matching用法及代码示例
- Python SciPy csgraph.minimum_spanning_tree用法及代码示例
- Python SciPy csgraph.csgraph_to_dense用法及代码示例
- Python SciPy csgraph.breadth_first_order用法及代码示例
- Python SciPy csgraph.connected_components用法及代码示例
- Python SciPy csgraph.dijkstra用法及代码示例
- Python SciPy csgraph.breadth_first_tree用法及代码示例
- Python SciPy csgraph.csgraph_from_dense用法及代码示例
- Python SciPy csgraph.floyd_warshall用法及代码示例
- Python SciPy csgraph.bellman_ford用法及代码示例
- Python SciPy csgraph.csgraph_to_masked用法及代码示例
- Python SciPy csgraph.csgraph_masked_from_dense用法及代码示例
- Python SciPy csgraph.shortest_path用法及代码示例
- Python SciPy csgraph.reconstruct_path用法及代码示例
- Python SciPy csgraph.johnson用法及代码示例
- Python SciPy csgraph.depth_first_order用法及代码示例
- Python SciPy csgraph.csgraph_from_masked用法及代码示例
- Python SciPy csgraph.construct_dist_matrix用法及代码示例
- Python SciPy csgraph.reverse_cuthill_mckee用法及代码示例
- Python SciPy csgraph.depth_first_tree用法及代码示例
- Python SciPy csgraph.laplacian用法及代码示例
- Python SciPy csgraph.structural_rank用法及代码示例
- Python SciPy csc_array.diagonal用法及代码示例
- Python SciPy csc_matrix.nonzero用法及代码示例
注:本文由纯净天空筛选整理自scipy.org大神的英文原创作品 scipy.sparse.csgraph.maximum_flow。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。