基于最大边权重分割SciPy最小生成树的方法?

时间:2014-06-24 21:36:00

标签: python numpy scipy minimum-spanning-tree

有没有办法通过删除树中最大的边权重值来分割scipy.sparse.csgraph.minimum_spanning_tree操作的输出?我试图访问每个子树,如果该边缘不是最小生成树的外边缘,则通过删除最大边缘权重得到。

使用SciPy文档示例:

from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import minimum_spanning_tree
X = csr_matrix([[0, 8, 0, 3],
                [0, 0, 2, 5],
                [0, 0, 0, 6],
                [0, 0, 0, 0]])
Tcsr = minimum_spanning_tree(X)
# print(Tcsr)
# (0,3) 3.0
# (3,1) 5.0
# (1,2) 2.0

在上面的最小生成树中删除中间值并分别访问其他两个边的最佳方法是什么?我试图在大型图上执行此操作,并尝试尽可能避免大型Python循环。感谢。

1 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,并设法仅使用scipy找出解决方案。所有这一切都是采用MST,找到最大加权边缘,删除它(即将其清零),然后使用connected_components方法确定哪些节点保持连接。

以下是包含注释的完整脚本:

import numpy as np
from scipy.sparse.csgraph import minimum_spanning_tree, connected_components
from scipy.sparse import csr_matrix

# Create a random "distance" matrix.
# Select only the upper triangle since the distance matrix array would be symmetrical.
a = np.random.rand(5,5)
a = np.triu(a)

# Create the minimum spanning tree.
mst = minimum_spanning_tree(csr_matrix(a))
mst = mst.toarray()

# Get the index of the maximum value.
# `argmax` returns the index of the _flattened_ array;
# `unravel_index` converts it back.
idx = np.unravel_index(mst.argmax(), mst.shape)

# Clear out the maximum value to split the tree.
mst[idx] = 0

# Label connected components.
num_graphs, labels = connected_components(mst, directed=False)

# We should have two trees.
assert(num_graphs == 2)

# Use indices as node ids and group them according to their graph.
results = [[] for i in range(max(labels) + 1)]
for idx, label in enumerate(labels):
    results[label].append(idx)

print(results)

这会产生类似的结果:

[[0, 1, 4], [2, 3]]