これは実際には 2 つの質問です。最初に: OO プログラミングのバックグラウンドを持っている者として、Mathematica がすべての基礎としてリストを使用するのは少し面倒だと思います。したがって、Mathematica プログラマーが (私が知る限り) グラフを定義する方法は次のとおりです。
graph={{1, 2, 3, 4, 5}, {1->2, 2->4, 4->4, 4->5}};
そして、プログラマーはそれを覚えておく必要があります
graph[[1]]
頂点のリストを参照し、
graph[[2]]
エッジのリストを参照します (この場合、一連のルールとして定義されます)。
そのため、Mathematica のルールについて学んでいたときに、データ構造をもう少しオブジェクト指向に近づける機会を見つけました。次のようなグラフを定義することにしました。
graph={Verts->{1,2,3,4,5}, Edges->{1->2, 2->4, 4->4, 4->5}};
次に、頂点とエッジを (それぞれ) によって参照します。
Verts/.graph
Edges/.graph
ただし、ルールの左側は識別子ではなく、それ自体がオブジェクトであるため、他の Mathematica ファイルが Verts または Edges をどこかでグローバル変数として定義している場合、これには奇妙な副作用が生じる可能性があります。
質問 1 は次のとおりです。これは Mathematica データ構造を作成するための良い方法ですか、それとも悪い方法ですか? このようにしている理由の 1 つは、色などの任意のプロパティをアタッチできるようにするためです。
AppendTo[graph, Colors->{Red, Red, Blue, Red, Red}]; (* Labels ea. vert with a color *)
私の関数は、特定のプロパティが追加された正確な順序を知る必要はありません。たとえば、次のように定義された関数 GetColor があるとします。
GetColor[graph_, vertIdx_]:=(Colors/.graph)[[vertIdx]];
色情報を持つグラフデータ構造を常に持ちたいとは限らず、色情報のためにリスト内のスポットを予約したくないので(グラフ[[[3]]]のように)、これが望ましいです。
2 つ目: GraphEdit が、上で説明したルールのようなものを返すことがわかりました。たとえば、実行(およびグラフを描画)すると
Needs["GraphUtilities`"];
g = GraphEdit[];
g[[2]]
次のような出力が得られます。
Graph->{1->2,3->3,4->4,5->4}
ルールのように見えます!だから私はこれを試します:
Graph/.g[[2]]
期待して
{1->2,3->3,4->4,5->4}
戻ってきた。しかし、代わりに出力は
Graph
しかし、代わりに実行すると
g[[2]][[1]] /. g[[2]]
期待される出力が得られます。
{1->2,3->3,4->4,5->4}
つまり、g[[2]] は実際にはルールですが、何らかの理由で g[[2]][[1]] (実行すると Graph が出力されます) は、Graph と入力することと同じではありません。では、g[[2]][[1]] とは一体何なのでしょうか?
それは本物の識別子のように思えます。もしそうなら、上記の質問 1 の問題を解決するために使用したいと思います。誰でも違いを知っていますか、またはどちらか一方を Mathematica に入力する方法はありますか?
これに関するドキュメント(またはオンライン)には何も見つかりません。ありがとう。