Запретить автоматическое размещение объектов Graph [] в Mathematica 8 - PullRequest
6 голосов
/ 09 мая 2011

Некоторые типы объектов имеют специальное форматирование ввода / вывода в Mathematica. Это включает в себя Graphics, растровые изображения и, по состоянию на Mathematica 8, графики (Graph[]). К сожалению, для визуализации больших графиков может потребоваться очень много времени, гораздо больше, чем для большинства других операций, которые я выполняю над ними во время интерактивной работы.

Как я могу предотвратить автоматическое размещение Graph[] объектов в StandardForm и TraditionalForm и отображать их, например, как. -Graph-, предпочтительно сохраняя интерпретируемость вывода (возможно, используя Interpretation?). Я думаю, что это будет связано с изменением Format и / или MakeBoxes, но мне не удалось заставить это работать.

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

В связанной заметке, есть ли способ получить определения Format / MakeBoxes, связанные с определенными символами? FormatValues является одной соответствующей функцией, но она пуста для Graph.

Пример сеанса:

In[1]:= Graph[{1->2, 2->3, 3->1}]
Out[1]= -Graph-

In[2]:= interactiveGraphPlot[%] (* note that % works *)
Out[2]= (the usual interactive graph plot should be shown here)

Ответы [ 3 ]

2 голосов
/ 19 мая 2011

Вы можете использовать GraphLayout параметр Graph, а также граф-конструкторы для подавления рендеринга.График все еще можно визуализировать с помощью GraphPlot.Попробуйте следующее

{gr1, gr2, gr3} = {RandomGraph[{100, 120}, GraphLayout -> None], 
  PetersenGraph[10, 3, GraphLayout -> None], 
  Graph[{1 -> 2, 2 -> 3, 3 -> 1}, GraphLayout -> None]}

enter image description here

Чтобы упростить работу, вы можете использовать SetOptions, чтобы установить GraphLayout для None для всех конструкторов графа, которые вы используете.интересует.

2 голосов
/ 09 мая 2011

Хотя у меня нет Mathematica 8, чтобы попробовать это, одна возможность состоит в том, чтобы использовать эту конструкцию:

Unprotect[Graph]

MakeBoxes[g_Graph, StandardForm] /; TrueQ[$short] ^:= 
 ToBoxes@Interpretation[Skeleton["Graph"], g]

$short = True;

После этого объект Graph должен отображаться в форме скелета, и установка $short = Falseдолжен восстановить поведение по умолчанию.

Надеюсь, это поможет автоматизировать переключение:

interactiveGraphPlot[g_Graph] := Block[{$short}, Print[g]]

Забота Марка об изменении Graph заставила меня рассмотреть возможность использования $PrePrint.Я думаю, что это также должно предотвратить медленный шаг макета.Это может быть более желательно, если вы еще не используете $PrePrint для чего-то другого.

$PrePrint = 
  If[TrueQ[$short], # /. _Graph -> Skeleton["Graph"], #] &;

$short = True

Также удобно, по крайней мере, с Graphics (опять же, я не могу проверить с помощью Graph в v7)можно получить графику с помощью Print.Здесь показано с графикой:

g = Plot[Sin[x], {x, 0, 2 Pi}]

(*  Out =  <<"Graphics">>  *)

Затем

Print[g]

enter image description here

Я оставил тест $short на месте для легкого переключения через глобальный символ, но можно было бы опустить его и использовать:

    $PrePrint = # /. _Graph -> Skeleton["Graph"] &;

А затем использовать $PrePrint = . для сброса функциональности по умолчанию.

1 голос
/ 10 мая 2011

Вы пытались просто подавить вывод?Я не думаю, что команда Graph V8 делает какую-либо разметку, если вы делаете это.Чтобы исследовать это, мы можем сгенерировать большой список ребер и сравнить значения времени graph[edges];, Graph[edges]; и GraphPlot[edges];

In[23]:= SeedRandom[1];
edges = Union[Rule @@@ (Sort /@ 
      RandomInteger[{1, 5000}, {50000, 2}])];

In[25]:= t = AbsoluteTime[];
graph[edges];

In[27]:= AbsoluteTime[] - t

Out[27]= 0.029354

In[28]:= t = AbsoluteTime[];
Graph[edges];

In[30]:= AbsoluteTime[] - t

Out[30]= 0.080434

In[31]:= t = AbsoluteTime[];
GraphPlot[edges];

In[33]:= AbsoluteTime[] - t

Out[33]= 4.934918

. Инертная команда graph, конечно,быстрый.Команда Graph занимает намного больше времени, но не так близко, как команда GraphPlot.Таким образом, мне кажется, что Graph на самом деле не вычисляет раскладку, как это делает GraphPlot.

Логический вопрос заключается в том, на что Graph тратит свое время.Давайте рассмотрим вывод InputForm из Graph в простом случае:

Graph[{1 -> 2, 2 -> 3, 3 -> 1, 1 -> 4}] // InputForm

Out[123]//InputForm=
    Graph[{1, 2, 3, 4}, 
      {DirectedEdge[1, 2], 
       DirectedEdge[2, 3], 
       DirectedEdge[3, 1], 
       DirectedEdge[1, 4]}]

Обратите внимание, что вершины графа определены, и я думаю, что именно это и делает Graph.Фактически, количество времени, которое потребовалось для вычисления Graph[edges] в первом примере, сопоставимо с самым быстрым способом, который я могу себе представить, чтобы сделать это:

Union[Sequence @@@ edges]; // Timing

Это заняло 0,087045 секунд.

...