快速的二分匹配

时间:2018-03-28 02:02:25

标签: python c algorithm max-flow

在C或python中是否存在快速现成的最大基数二分匹配实现?

我试过了git branch|grep '^\s*temp',但速度很慢。我有一个两层图,每层有大约1000个节点。密度各不相同。什么时候我可以期待这个设置?

我看到这篇文章Fast max-flow min-cut library for Python,但有什么更快的吗?

2 个答案:

答案 0 :(得分:0)

好吧,如果您打算使用网络流方法,那么所有可用的算法的时间复杂度似乎至少为O(|V||E|),或者大多数(例如O(|V|^2|E|))例。

如果您有一个包含2000个节点的图形,即使边数|E|与顶点数|V|呈线性关系,也会产生时间复杂度为O(|V|^2|E|)的算法在平均每天的计算机中执行时间长达几分钟。如果图形密集,则| E |与|V|^2呈线性关系,然后可能需要数天才能执行。

解决此二分最大匹配问题的替代算法可能是Hopcroft-Karp algorithm。它首先为二分匹配设置一个空集M,然后通过在给定图中查找扩充路径来尝试展开M。该算法具有O(|E|√|V|)复杂度,优于Push Relabel或Edmonds-Karp等网络流量算法。

此外,已经有a Python library实施了Hopcroft-Karp算法,我相信这是你想要的另一件事。

答案 1 :(得分:0)

SciPy(自1.4.0版开始)包含scipy.sparse.csgraph.maximum_bipartite_matching中Hopcroft-Karp的实现,与NetworkX相比具有优势。该功能也存在于以前的版本中,但随后假定与之完美匹配;在1.4.0中取消了这一假设。

它的精确程度将取决于二分图的结构,但是仅通过生成随机图(并忽略NetworkX初始化基础数据结构将花费的时间),我可以获得200倍的性能提升:

import networkx as nx
from scipy.sparse import rand
from scipy.sparse.csgraph import maximum_bipartite_matching


n = 5000
graph = rand(n, n, density=.1, format='csr', random_state=42)
G = nx.algorithms.bipartite.from_biadjacency_matrix(graph)
>>> %timeit maximum_bipartite_matching(graph, perm_type='column')
8.95 ms ± 183 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit nx.algorithms.bipartite.maximum_matching(G, top_nodes=range(n))
2.01 s ± 118 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)