设 G 为图。所以 G 是一组节点和一组链接。我需要找到一种快速划分图形的方法。我现在正在处理的图表只有 120*160 个节点,但我可能很快就会在另一个上下文(不是医学,而是网站开发)中处理一个具有数百万个节点的等效问题。
所以,我所做的是将所有链接存储到一个图形矩阵中:
M=numpy.mat(numpy.zeros((len(data.keys()),len(data.keys()))))
现在,如果节点 s 连接到节点 t,则 M 在位置 s,t 中保持 1。我确保 M 是对称的 M[s,t]=M[t,s] 并且每个节点都链接到自身 M[s,s]=1。
如果我记得很清楚,如果我将 M 与 M 相乘,结果是一个矩阵,它表示连接通过两个步骤到达的顶点的图。
所以我继续将 M 与自身相乘,直到矩阵中零的数量不再减少。现在我有了连接组件的列表。现在我需要对这个矩阵进行聚类。
到目前为止,我对算法非常满意。我认为它简单、优雅且相当快。我在这部分遇到了麻烦。
本质上,我需要将此图拆分为其连接的组件。
我可以遍历所有节点,看看它们连接到什么。
但是如何对矩阵进行排序以重新排序行。但我不知道是否有可能做到这一点。
以下是到目前为止的代码:
def findzeros(M):
nZeros=0
for t in M.flat:
if not t:
nZeros+=1
return nZeros
M=numpy.mat(numpy.zeros((len(data.keys()),len(data.keys()))))
for s in data.keys():
MatrixCells[s,s]=1
for t in data.keys():
if t<s:
if (scipy.corrcoef(data[t],data[s])[0,1])>threashold:
M[s,t]=1
M[t,s]=1
nZeros=findzeros(M)
M2=M*M
nZeros2=findzeros(M2)
while (nZeros-nZeros2):
nZeros=nZeros2
M=M2
M2=M*M
nZeros2=findzeros(M2)
编辑:
有人建议我使用 SVD 分解。这是 5x5 图上的问题的简单示例。我们将使用它,因为在 19200x19200 方阵中不容易看到簇。
import numpy
import scipy
M=numpy.mat(numpy.zeros((5,5)))
M[1,3]=1
M[3,1]=1
M[1,1]=1
M[2,2]=1
M[3,3]=1
M[4,4]=1
M[0,0]=1
print M
u,s,vh = numpy.linalg.linalg.svd(M)
print u
print s
print vh
这里基本上有 4 个集群:(0),(1,3),(2),(4) 但我仍然看不到 svn 在这种情况下如何提供帮助。