当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python SciPy csgraph.min_weight_full_bipartite_matching用法及代码示例


本文简要介绍 python 语言中scipy.sparse.csgraph.min_weight_full_bipartite_matching的用法。

用法:

scipy.sparse.csgraph.min_weight_full_bipartite_matching(biadjacency_matrix, maximize=False)#

返回二部图的最小权重完全匹配。

参数

biadjacency_matrix 稀疏矩阵

二分图的双邻接矩阵:CSR、CSC 或 COO 格式的稀疏矩阵,其行表示图的一个分区,其列表示另一个分区。两个顶点之间的边由矩阵中的相应条目指示,边的权重由该条目的值给出。这不应与图的完整邻接矩阵混淆,因为我们只需要定义二分结构的子矩阵。

maximize 布尔(默认值:假)

如果为真,则计算最大权重匹配。

返回

row_ind, col_ind 数组

提供最佳匹配的行索引数组和对应的列索引之一。匹配的总权重可以计算为 graph[row_ind, col_ind].sum() 。行索引将被排序;在方阵的情况下,它们将等于 numpy.arange(graph.shape[0])

注意

为权重非零的加权二部图 。这个函数然后产生一个匹配的 与基数

最小化匹配中包含的边的权重总和 ,如果不存在这样的匹配,则会引发错误。

什么时候\(\lvert U \rvert = \lvert V \rvert\) ,这通常被称为完美匹配;在这里,因为我们允许\(\lvert U \rvert\) \(\lvert V \rvert\) 不同的是,我们遵循卡普[1]并将匹配称为满的.

此函数实现 LAPJVsp 算法 [2],简称“线性分配问题,Jonker-Volgenant,稀疏”。

它解决的问题等价于矩形线性分配问题。 [3] 因此,该函数可用于解决与 scipy.optimize.linear_sum_assignment 相同的问题。当输入密集时,或者对于某些特定类型的输入,例如 条目是欧几里得空间中两点之间的距离的输入,该函数可能会表现得更好。

如果不存在完全匹配,则此函数引发 ValueError 。要确定图中最大匹配的大小,请参阅 maximum_bipartite_matching

我们要求权重非零只是为了避免在不同稀疏表示之间转换时处理显式零的问题。零权重可以通过向所有权重添加一个常数来处理,以便生成的矩阵不包含零。

如果可能存在多个有效解决方案,则输出可能会因 SciPy 和 Python 版本而异。

参考

[1]

Richard Manning Karp:在预期时间 O(mn log n) 内解决 m x n 分配问题的算法。网络,10(2):143-152,1980。

[2]

Roy Jonker 和 Anton Volgenant:密集和稀疏线性分配问题的最短增广路径算法。计算 38:325-340, 1987。

例子

>>> from scipy.sparse import csr_matrix
>>> from scipy.sparse.csgraph import min_weight_full_bipartite_matching

让我们首先考虑一个所有权重都相等的示例:

>>> biadjacency_matrix = csr_matrix([[1, 1, 1], [1, 0, 0], [0, 1, 0]])

在这里,我们得到的只是图的完美匹配:

>>> print(min_weight_full_bipartite_matching(biadjacency_matrix)[1])
[2 0 1]

即第一、二、三行分别与第三、一、二列相匹配。请注意,在此示例中,输入矩阵中的 0 不对应权重为 0 的边,而是对应于未与边配对的一对顶点。

另请注意,在这种情况下,输出与应用 maximum_bipartite_matching 的结果相匹配:

>>> from scipy.sparse.csgraph import maximum_bipartite_matching
>>> biadjacency = csr_matrix([[1, 1, 1], [1, 0, 0], [0, 1, 0]])
>>> print(maximum_bipartite_matching(biadjacency, perm_type='column'))
[2 0 1]

当多个边可用时,优先选择权重最低的边:

>>> biadjacency = csr_matrix([[3, 3, 6], [4, 3, 5], [10, 1, 8]])
>>> row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency)
>>> print(col_ind)
[0 2 1]

在这种情况下,总重量是

>>> print(biadjacency[row_ind, col_ind].sum())
9

当矩阵不是方阵时,即当两个分区具有不同的基数时,匹配与两个分区中较小的一样大:

>>> biadjacency = csr_matrix([[0, 1, 1], [0, 2, 3]])
>>> row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency)
>>> print(row_ind, col_ind)
[0 1] [2 1]
>>> biadjacency = csr_matrix([[0, 1], [3, 1], [1, 4]])
>>> row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency)
>>> print(row_ind, col_ind)
[0 2] [1 0]

当一个或两个分区为空时,匹配也为空:

>>> biadjacency = csr_matrix((2, 0))
>>> row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency)
>>> print(row_ind, col_ind)
[] []

一般来说,我们总是会达到与使用 scipy.optimize.linear_sum_assignment 相同的权重总和,但请注意,对于那个,缺失的边由 float('inf') 的矩阵条目表示。让我们生成一个具有 1 到 10 之间整数条目的随机稀疏矩阵:

>>> import numpy as np
>>> from scipy.sparse import random
>>> from scipy.optimize import linear_sum_assignment
>>> sparse = random(10, 10, random_state=42, density=.5, format='coo') * 10
>>> sparse.data = np.ceil(sparse.data)
>>> dense = sparse.toarray()
>>> dense = np.full(sparse.shape, np.inf)
>>> dense[sparse.row, sparse.col] = sparse.data
>>> sparse = sparse.tocsr()
>>> row_ind, col_ind = linear_sum_assignment(dense)
>>> print(dense[row_ind, col_ind].sum())
28.0
>>> row_ind, col_ind = min_weight_full_bipartite_matching(sparse)
>>> print(sparse[row_ind, col_ind].sum())
28.0

相关用法


注:本文由纯净天空筛选整理自scipy.org大神的英文原创作品 scipy.sparse.csgraph.min_weight_full_bipartite_matching。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。