2011-03-30 9 views
14

Acabo de pasar un par de horas tratando de convertir some old code que usa Mathematica 7's GraphPlot para usar las nuevas funciones de Mathematica 8 Graph. Parecía razonable ya que el nuevo dibujo gráfico es mucho más bonito y tiene cosas como AdjacencyMatrix y KirchhoffMatrix incorporadas.Multigrafos en Mathematica 8

El problema es que no puedo encontrar la manera de obtener gráficos con múltiples aristas para trabajar en Mma 8.

el gráfico Feynman que utilizo como mi ejemplo canónico es la gráfica de vacío de doble bucle

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

two-loop vacuum sunset graph

Tratando de hacer el gráfico similar en Mma 8

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

produce el mensaje de error

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

¿Cómo puedo construir (y trabajar con) un gráfico similar usando de Mathematica 8 Graph[] objetos?

Editar: Este problema todavía existe en Mathematica 9

+2

Los tres objetos de tipo de gráfico diferentes que flotan en Mma8 no ayudan a resolver los problemas ... Sobre todo porque no juegan muy bien. – Simon

Respuesta

14

Pasé por un proceso similar de intentar usar Graph para todo, y encontré que no reemplaza Combinatorica y GraphPlot. El mejor uso para Graph es usarlo como un tipo de contenedor para almacenar vértices + bordes + coordenadas.

Por ejemplo, la mayoría de las funciones de "Algorithmic Graph Theory" del tutorial Combinatorica no están disponibles para los nuevos objetos Graph.Cuando hablé con un desarrollador de WRI en el proyecto Graph, mi entendimiento fue proporcionar todas las funciones Combinatorica para Graph no es una prioridad porque el objetivo del diseño es proporcionar métodos que resuelvan tareas de manera algorítmica agnóstica. Por ejemplo, puede tener un método para encontrar la cubierta de vértices y la coloración gráfica para el nuevo objeto Graph, pero para tareas algorítmicas específicas como el coloreado de Brelaz y la cubierta de vértices codiciosos, siempre tendrá que posponerse al Combinatorica.

Además de los gráficos múltiples, algunos diseños de gráficos no están disponibles para los objetos Graph. No puedes arreglar algunas coordenadas de vértices y dejar que el diseño automático haga el resto. Además, el diseño de LayeredGraphPlot no está disponible y algunas veces es preferred sobre .

La manera de conseguir el mejor de los 3 mundos es utilizar Graph objetos como principal vehículo para el almacenamiento gráfica y hacer envolturas para GraphPlot, Combinatorica y GraphUtilities funciones que aceptan Graph objetos

algunos casos de uso:

  • Usted necesita algún algoritmo de Combinatorica o GraphUtilities - hacer un envoltorio someAlgorithm que toma Graph objeto, convierte a la lista de los bordes o Combinatorica gráfico (GraphUtilities'ToCombinatoricaGraph es útil), ejecuta el algoritmo, lo convierte de nuevo en el objeto Graph, teniendo cuidado de establecer GraphStyle y VertexCoordinates correctos del objeto gráfico original. Debido a los conflictos, y asegúrese de que CombinatoricaGraphUtilities no están en ruta de contexto, que do it usando $ Pre

  • Usted necesita un poco de terreno gráfico personalizado como here, o la gráfica multi-borde - hacer una función de contenedor someGraphPlot que acepte Graph objeto, lo convierte en una representación correcta, luego usa GraphPlot o tal vez crea un objeto temporal Graph con formas de vértice/borde personalizadas para este único gráfico. Tenga en cuenta que puede adjuntar propiedades a los bordes usando SetProperty para que pueda almacenar sus multigrafos en Graph de esa manera.

  • que desea utilizar uno de GraphPlot diseños y almacenar coordenadas en Graph - función de su uso como here obtener coordenadas de los vértices de GraphPlot diseño, y almacenarlos en Graph objeto utilizando VertexCoordinates

Aquí hay una notebook demostrando estos casos de uso y algunos otros

+0

Gracias Yaroslav. Todos los buenos consejos y comentarios interesantes, así que te daré el "tic". Lamentablemente, es más de lo que quiero hacer con este código que no uso mucho en este momento. Espero que para cuando regrese a este proyecto, la IRG habrá completado las lagunas (extrapolar su ciclo de lanzamiento y deberíamos tener v9 o v10 para el próximo año). – Simon

2

Estos aún no son compatibles, supongo:

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

aunque esto podría no ser la respuesta que esperan obtener.

+0

Me resulta extraño que este tipo de entrada no funcione, ya que hay soporte para matrices de adyacencia ponderadas. – Simon

8

La función GraphPlot todavía funciona en las MMA 8.

multigrafos no se admiten en funciones de Combinatorica tampoco. Bastante difícil de implementar en una matriz de adjetivos también. Tal vez trabajar con EdgeWeight puede funcionar en los cálculos?

Para la elaboración de varios enlaces que puedo imaginar que 'EdgeShapeFunction' puede ayudarle.

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

o para los bordes seleccionados:

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

enter image description here

La función ef puede parametrizarse fácilmente para el número de bordes para dibujar.

+0

Gracias Sjoerd. Me imagino conectando una 'EdgeShapeFunction' para verificar automáticamente si hay bordes pesados ​​enteros, por lo que su' eft' es un código bastante útil. Pero ahora mismo he perdido el entusiasmo por actualizar mi código ... Volveré más tarde o esperaré a que WRI limpie su código 'Graph'. – Simon