这实际上是一个双重问题。首先:作为一个来自 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 数据结构,这是一个好习惯还是坏习惯?我这样做的原因之一是我可以附加任意属性,比如颜色:
AppendTo[graph, Colors->{Red, Red, Blue, Red, Red}]; (* Labels ea. vert with a color *)
而且我的函数不必知道添加特定属性的确切顺序。例如,您可能定义了一个 GetColor 函数,如下所示:
GetColor[graph_, vertIdx_]:=(Colors/.graph)[[vertIdx]];
这是可取的,因为我可能并不总是希望拥有具有颜色信息的图形数据结构,因此不想在列表中保留一个位置(如图形[[[3]]])用于颜色信息。
第二:我看到 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 中输入一个与另一个?
我在文档中找不到任何关于此(或在线)的任何内容。谢谢。