Мультиграфы в Mathematica 8

Я просто потратил пару часов, пытаясь преобразовать некоторый старый код, который использует Mathematica 7 GraphPlot для использования нового графика Mathematica 8 функции. Это казалось разумным, поскольку новый графический чертеж намного приятнее, и он имеет такие вещи, как AdjacencyMatrix и KirchhoffMatrix.

Проблема заключается в том, что я не могу понять, как получить графики с несколькими ребрами для работы в Mma 8.

График Фейнмана, который я использую в качестве моего канонического примера, - это двухпетлевой вакуумный граф

GraphPlot[{1 -> 2, 1 -> 2, 1 -> 2}, MultiedgeStyle -> .5, 
          DirectedEdges -> True, VertexCoordinateRules -> {{-1, 0}, {1, 0}}]

two-loop vacuum sunset graph

Попытка сделать аналогичный граф в Mma 8

Graph[{DirectedEdge[1, 2], DirectedEdge[1, 2], DirectedEdge[1, 2]}, 
      VertexCoordinates -> {{-1, 0}, {1, 0}}]

выводит сообщение об ошибке

Graph::supp: Mixed graphs and multigraphs are not supported. >>

Как я могу построить (и работать с) похожий граф, используя Mathematica 8 Graph[] objects?

Изменить: Эта проблема все еще существует в Mathematica 9

Ответы

Ответ 1

Я прошел аналогичный процесс, пытаясь использовать Graph для всего, и обнаружил, что он не заменяет Combinatorica и GraphPlot. Наилучшее использование для Graph - использовать его как тип контейнера для хранения вершин + ребер + координат.

Например, большинство функций из "Теории алгоритмических диаграмм" учебника Combinatorica недоступны для новых объектов Graph. Когда я разговаривал с разработчиком WRI в проекте Graph, я понял, что все функции Combinatorica для Graph не являются приоритетом, поскольку целью дизайна является предоставление методов, которые решают задачи алгоритмическим агностическим способом. Например, у вас может быть метод для поиска вершинной обложки и раскраски графа для нового объекта Graph, но для алгоритмических конкретных задач, таких как окраска Brelaz и Greedy Vertex Cover, вам всегда придется отложить до Combinatorica.

В дополнение к мультиграфам некоторые схемы графа недоступны для объектов Graph. Вы не можете исправить некоторые координаты вершин и позволить автоматическому расположению сделать все остальное. Кроме того, расположение LayeredGraphPlot недоступно и иногда предпочтительнее над Graph LayeredDrawing.

Способ получить лучшее из 3-х миров состоит в том, чтобы использовать объекты Graph в качестве основного носителя для хранения графа и создавать обертки для GraphPlot, Combinatorica и GraphUtilities функций, которые принимают объекты Graph

Некоторые варианты использования:

  • Вам нужен алгоритм из Combinatorica или GraphUtilities - создать оболочку someAlgorithm, которая принимает объект Graph, преобразует его в список ребер или Combinatorica graph (GraphUtilities'ToCombinatoricaGraph).), запускает алгоритм, преобразует его обратно в объект Graph, стараясь установить правильные GraphStyle и VertexCoordinates из исходного объекта графа. Из-за конфликтов убедитесь, что Combinatorica и GraphUtilities не находятся в контексте, я сделать это, используя $Pre

  • Вам понадобится график пользовательского графика, например здесь, или многогранный граф - создайте функцию обертки someGraphPlot который принимает объект Graph, преобразует его в правильное представление, затем использует GraphPlot или, возможно, создает временный объект Graph с пользовательскими формами вершин/ребер для этого участка. Обратите внимание, что вы можете прикреплять свойства к ребрам с помощью SetProperty, чтобы вы могли хранить ваши мультиграфы в Graph таким образом.

  • Вы хотите использовать один из макетов GraphPlot и хранить координаты в Graph - используйте функцию здесь, чтобы получить координаты вершин из GraphPlot и сохраните их в объекте Graph, используя VertexCoordinates

Здесь ноутбук, демонстрирующий эти варианты использования и несколько других

Ответ 2

Функция GraphPlot все еще работает в mma 8.

Мультиграфы также не поддерживались в функциях Combinatorica. Довольно сложно реализовать в матрице смежности. Возможно, работа с EdgeWeight может работать в вычислениях?

Для рисования нескольких ссылок я могу представить, что "EdgeShapeFunction" может вам помочь.

ef[pts_List, e_] :=
 Block[{g1 = 
    Insert[pts, (pts[[1]] + pts[[-1]])/
      2 + ({x, y}/5 /. 
        Solve[{Norm[{x, y}] == 1, (pts[[1]] - pts[[-1]]).{x, y} == 
            0}, {x, y}][[1]]), Round[(Length[pts] + 1)/2]],
   g2 = Insert[
     pts, (pts[[1]] + pts[[-1]])/
      2 + (-{x, y}/5 /. 
        Solve[{Norm[{x, y}] == 1, (pts[[1]] - pts[[-1]]).{x, y} == 
            0}, {x, y}][[1]]), Round[(Length[pts] + 1)/2]]}, {Arrow[
    BSplineCurve[g1]], Arrow[BSplineCurve[g2]], Arrow[pts]}]

Graph[{1 \[DirectedEdge] 2, 2 \[DirectedEdge] 3, 3 \[DirectedEdge] 1},
  EdgeShapeFunction -> ef]

enter image description here

или для выбранных ребер:

Graph[{1 \[DirectedEdge] 2, 2 \[DirectedEdge] 3, 3 \[DirectedEdge] 1},
  EdgeShapeFunction -> {3 \[DirectedEdge] 1 -> ef}]

enter image description here

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

Ответ 3

Они еще не поддерживаются, я полагаю:

In[201]:= AdjacencyGraph[{{0, 3}, {0, 0}}]

During evaluation of In[201]:= Graph::supp: Mixed graphs and multigraphs are not supported. >>

Out[201]= AdjacencyGraph[{{0, 3}, {0, 0}}]

хотя это может быть не тот ответ, который вы надеетесь получить.