如何序列化图形结构?

时间:2008-09-09 12:54:05

标签: serialization graph-theory

平面文件和关系数据库为我们提供了一种序列化结构化数据的机制。 XML非常适合序列化未结构化的树状数据。

但很多问题最好用图表来表示。例如,热模拟程序将通过电阻边缘与彼此连接的温度节点一起工作。

那么序列化图形结构的最佳方法是什么?我知道XML在某种程度上可以做到这一点 - 就像关系数据库可以序列化复杂的对象网络一样:它通常可以工作,但很容易变得丑陋。

我知道graphviz程序使用的点语言,但我不确定这是最好的方法。这个问题可能是学术界可能正在研究的问题,我很乐意参考任何讨论这个问题的论文。

6 个答案:

答案 0 :(得分:13)

您如何在内存中表示图表?
基本上你有两个(好的)选择:

其中邻接列表表示最好用于稀疏图,以及密集图的矩阵表示。

如果您使用了这样的表示,那么您可以将这些表示序列化。

如果必须人类可读,您仍然可以选择创建自己的序列化算法。例如,您可以像使用任何“普通”矩阵一样记下矩阵表示:只打印出列和行,以及其中的所有数据,如下所示:

   1  2  3
1 #t #f #f
2 #f #f #t
3 #f #t #f

(这是一种非优化的非加权表示,但可以用于有向图)

答案 1 :(得分:7)

通常,父/子关系会显示XML中的关系。 XML可以处理图形数据,但不能以这种方式处理。要处理XML中的图形,您应该使用xs:IDxs:IDREF模式类型。

在一个示例中,假设node / @ id是xs:ID类型,而link / @ ref是xs:IDREF类型。以下XML显示了三个节点1 - >的循环。 2 - > 3 - > 1。

<data>
  <node id="1"> 
    <link ref="2"/>
  </node>
  <node id="2">
    <link ref="3"/>
  </node>
  <node id="3">
    <link ref="1"/>
  </node>
</data>

许多开发工具也支持ID和IDREF。我使用过Java的JAXB(Java XML Binding。它通过@XmlID@XmlIDREF注释来支持这些。您可以使用普通的Java对象构建图形,然后使用JAXB来处理实际的XML序列化。

答案 2 :(得分:5)

XML非常详细。每当我这样做,我就会自己动手。这是一个3节点有向无环图的例子。它非常紧凑,可以做我需要做的一切:

0: foo
1: bar
2: bat
----
0 1
0 2
1 2

答案 3 :(得分:1)

您可能熟悉的一个示例是Java序列化。这有效地按图形序列化,每个对象实例都是一个节点,每个引用都是一个边。使用的算法是递归的,但跳过重复。所以伪代码是:

serialize(x):
    done - a set of serialized objects
    if(serialized(x, done)) then return
    otherwise:
         record properties of x
         record x as serialized in done
         for each neighbour/child of x: serialize(child)

另一种方法当然是作为节点和边的列表,可以用XML,或任何其他首选的序列化格式,或作为邻接矩阵。

答案 4 :(得分:1)

邻接列表和邻接矩阵是在内存中表示图形的两种常用方法。在决定这两者时,您需要做出的第一个决定是您要优化的内容。如果您需要获取顶点邻居的列表,则邻接列表非常快。另一方面,如果您正在对边缘存在进行大量测试或者使用马尔可夫链的图形表示,那么您可能更喜欢邻接矩阵。

您需要考虑的下一个问题是您需要多少适合内存。在大多数情况下,图中边的数量远小于可能边的总数,因此邻接列表将更有效,因为您只需要存储实际存在的边。一个幸福的媒介是以压缩的稀疏行格式表示邻接矩阵,其中您保持从左上到右下的非零条目的向量,相应的向量指示可以在哪些列中找到非零条目,以及第三个向量,指示列条目向量中每行的开始。

[[0.0, 0.0, 0.3, 0.1]
 [0.1, 0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0, 0.0]
 [0.5, 0.2, 0.0, 0.3]]

可以表示为:

vals: [0.3, 0.1, 0.1, 0.5, 0.2, 0.3]
cols: [2,   3,   0,   0,   1,   4]
rows: [0,        2, null,  4]

压缩稀疏行实际上是一个邻接列表(列索引的功能相同),但格式使矩阵运算更加干净。

答案 5 :(得分:0)

在学术性较低,更实用的说明中,在CubicTest中,我们使用Xstream(Java)将测试与xml序列化。 Xstream处理图形结构的对象关系,因此您可以通过查看它的源和生成的xml来学习一两件事。你对丑陋的部分是对的,生成的xml文件看起来不太漂亮。