Пусть G - граф. Итак, G - это набор узлов и множество ссылок. Мне нужно найти быстрый способ разбить график. График, который я сейчас работаю, имеет только 120 * 160 узлов, но я мог бы вскоре работать над эквивалентной проблемой, в другом контексте (не в медицине, а в разработке сайтов), с миллионами узлов.
Итак, я сделал, чтобы сохранить все ссылки в матрице графа:
M=numpy.mat(numpy.zeros((len(data.keys()),len(data.keys()))))
Теперь M удерживает 1 в позиции s, t, если node s связано с node t. Я убеждаюсь, что M симметрично M [s, t] = M [t, s], и каждый node связывается с собой 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)
Edit:
Было высказано предположение, что я использую разложение 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 может помочь в этом контексте.