Предотвращение автоматической компоновки объектов Graph[] в Mathematica 8
некоторые типы объектов имеют специальное форматирование ввода / вывода в Mathematica. Это включает в себя Graphics, растровые изображения и, начиная с Mathematica 8, графики (Graph[]). К сожалению, визуализация больших графиков может занять очень много времени, гораздо больше, чем большинство других операций, которые я выполняю с ними во время интерактивной работы.
как я могу предотвратить автоматическое размещение Graph[] объекты в стандарте и 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 ответов
хотя у меня нет 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]

я покинул $short тест на месте для легкого переключения через глобальный символ, но можно оставить его и использовать:
$PrePrint = # /. _Graph -> Skeleton["Graph"] &;
и затем использовать $PrePrint = . для сброса функций по умолчанию.
можно использовать на Graph а также graph-конструкторы для подавления рендеринга. График все еще можно визуализировать с помощью GraphPlot. Попробуйте следующее
{gr1, gr2, gr3} = {RandomGraph[{100, 120}, GraphLayout -> None],
PetersenGraph[10, 3, GraphLayout -> None],
Graph[{1 -> 2, 2 -> 3, 3 -> 1}, GraphLayout -> None]}

для того, чтобы сделать работу проще, вы можете использовать SetOptions установить до None для всех графовых конструкторов, которые вас интересуют.
вы пытались просто подавить вывод? Я не думаю, что 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 команда, конечно, самая быстрая. The Graph команда занимает гораздо больше времени, но не где-то так долго, как . Таким образом, мне кажется, что Graph на самом деле не вычисляет макет, как GraphPlot делает.
логический вопрос в том, что такое Graph тратить время на. Рассмотрим InputForm of 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 считанные секунды.