Направлен расчет графика сходство -- оптимизация кода системы Mathematica


Я ищу, чтобы оптимизировать следующее вычисление. Во-первых, некоторые пояснения:

Объяснение

У меня есть направленный граф, чья матрица смежности может содержать только 1S и 0s. На подобие узлов я и Джей определяется следующим образом:

  1. посчитайте, сколько узлов пограничного указывая как я и Джей, и посчитайте, сколько узлов делать как я и J в точке с
  2. разделите сумму этих двух счетчиков на общее количество узлов либо я или Джей подключен к

Мне нужно найти максимальное сходство каждого узла в графе (его сходство с любой другой узел, кроме себя), и вычислить среднее значение этих чисел.

Графиков я работаю с не обязательно связаны, но они не имеют составляющих размер 1 (т. е. узлы, которые не подключены к любым другим узлам).

Код

meanMaxSim[g_Graph] :=
 Module[{am, pList, similarityMatrix},
  am = AdjacencyMatrix[g];
  pList = Transpose@Join[am, Transpose[am]];
  similarityMatrix = Outer[Total[#1 #2]/Total[Sign[#1 + #2]] &, pList, pList, 1];
  Mean[Max /@ dropDiagonal[similarityMatrix]]
]

(Знак используется, чтобы держать 0С и конвертировать ничего крупнее в 1С.)

Эта функция просто удаляет элементы по диагонали к Н К Н матрицы, заканчивая с н по Н - 1 матрица:

dropDiagonal[matrix_] := 
 MapThread[Drop[#1, {#2}] &, {matrix, Range@Length[matrix]}]

График[] доступна только в Mathematica 8, но это не имеет значения здесь, так как большую часть времени провел в космическом[] в любом случае. Если у вас более ранняя версия, просто предположим, что у вас есть матрица смежности как SparseArray как отправная точка.

Я ищу модификаций, что существенно ускорить этот процесс (более чем в 3 раза), но любое другое комментировать код приветствуется. Надеюсь, ускорение возможно без значительного увеличения сложности кода.

Примечания

Делаем вычисления с машиной-цифры-это хорошо, но я не стал делать, так как он не обеспечивает значительное ускорение.

Примечание петель: они разрешены в графе, и да, они дважды в этой реализации.

Редактировать:

Я был слишком быстр, чтобы задать этот вопрос. Вот ~4х ускорение с помощью компиляции. Я по-прежнему заинтересован в комментариях / дальнейшее ускорение.

simMatCompiled = 
  Compile[{{p, _Real, 2}},
    Table[Total[a b]/Total@Sign[a + b], {a, p}, {b, p}]
  ];

mxSim[g_Graph] :=
  Module[{am, pList, similarityMatrix},
    am = N@AdjacencyMatrix[g];
    pList = Transpose@Join[am, Transpose[am]];
    similarityMatrix = simMatCompiled[Normal[pList]];
    Mean[Max /@ dropDiagonal[similarityMatrix]]
  ]

Мне нужно, чтобы изменить внешний к таблице для того, для компиляции , чтобы быть в состоянии выполнить свою работу.



Комментарии
1 ответ

Незначительные улучшения, но рекомендуется использовать:

pList = ArrayFlatten[{{am\[Transpose], am}}];

и

dropDiagonal = MapThread[Delete, {#, Range@Length@#}] &;

Я тоже пробовал dropDiagonal = MapIndexed[капля, #] & , но это медленнее, по крайней мере, в В7.


Заменить:

Total[#1 #2]/Total[Sign[#1 + #2]] &

С:

#.#2 / Tr@Unitize[#1 + #2] &


Я считаю, что это улучшение скомпилированную функцию:

Compile[{{p, _Real, 2}}, 
With[{b = p\[Transpose]},
#.b / Total@Sign[# + b] & /@ p
]
]

5
ответ дан 12 мая 2011 в 02:05 Источник Поделиться