Мультиграфы в Математике 8 - PullRequest
15 голосов
/ 30 марта 2011

Я просто потратил пару часов, пытаясь преобразовать какой-то старый код , который использует Mathematica 7 GraphPlot, чтобы использовать новые функции Mathematica 8 Graph. Это казалось разумным, так как новый графический рисунок намного приятнее и в него встроены такие вещи, как 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. >>

Как я могу построить (и работать с) подобный граф, используя Graph[] объекты Mathematica 8?

Редактировать: Эта проблема все еще существует в Mathematica 9

Ответы [ 3 ]

15 голосов
/ 30 марта 2011

Я прошел аналогичный процесс, пытаясь использовать 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 граф (GraphUtilities'ToCombinatoricaGraph полезно ), запускает алгоритм, преобразует его обратно в Graph объект, стараясь установить правильные значения GraphStyle и VertexCoordinates из исходного графического объекта. Из-за конфликтов убедитесь, что Combinatorica и GraphUtilities не находятся в контекстном пути, я делаю это , используя $ Pre

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

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

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

9 голосов
/ 30 марта 2011

Функция 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 может быть легко параметризована для количества отрисовываемых ребер.

2 голосов
/ 30 марта 2011

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

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}}]

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

...