关于序列化:如何序列化图形结构?

关于序列化:如何序列化图形结构?

How to serialize a graph structure?

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

但是许多问题最好用图形表示。 例如,热仿真程序将与通过电阻性边缘相互连接的温度节点一起工作。

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

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


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

  • 邻接表表示
  • 邻接矩阵表示

其中,邻接表表示最好用于稀疏图,矩阵表示最好用于稠密图。

如果使用这样的表示形式,则可以序列化这些表示形式。

如果必须可读,您仍然可以选择创建自己的序列化算法。例如,您可以像处理任何"常规"矩阵一样写下矩阵表示形式:只需打印出列和行以及其中的所有数据,如下所示:

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

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


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

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

1
2
3
4
5
6
7
8
9
10
11
<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绑定。它通过@XmlID和@XmlIDREF批注支持它们。您可以使用纯Java对象构建图形,然后使用JAXB来处理对XML的实际序列化。


XML非常冗长。每当我这样做时,我都会自己滚动。这是3节点有向无环图的示例。它非常紧凑,可以完成我需要做的所有事情:

1
2
3
4
5
6
7
0: foo
1: bar
2: bat
----
0 1
0 2
1 2

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

您需要考虑的下一个问题是需要容纳多少内存。在大多数情况下,图形中的边数比可能的边总数小得多,因此邻接表将更加有效,因为您只需要存储实际存在的边即可。一个快乐的媒介是用压缩的稀疏行格式表示邻接矩阵,在该矩阵中,您从左上角到右下角保留了非零条目的向量,指示了可以在哪些列中找到非零条目的对应向量,以及第三个向量表示列输入向量中每行的开始。

1
2
3
4
[[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]]

可以表示为:

1
2
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]

压缩的稀疏行实际上是一个邻接表(列索引的功能相同),但是格式更适合矩阵操作。


您可能熟悉的一个示例是Java序列化。这有效地通过图进行了序列化,每个对象实例是一个节点,每个引用是一个边。使用的算法是递归的,但是跳过重复项。因此,伪代码为:

1
2
3
4
5
6
7
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或任何其他首选的序列化格式或作为邻接矩阵来完成。


在一个不太学术,更实用的注释上,在CubicTest中,我们使用Xstream(Java)在XML前后进行测试序列化。 Xstream处理图结构的对象关系,因此您可以通过查看它的源和生成的xml来学习一两个东西。您对丑陋的部分是正确的,但是生成的xml文件看起来并不漂亮。


推荐阅读

    linux上数据库的命令?

    linux上数据库的命令?,服务,系统,信息,地址,命令,密码,工具,管理,数据,单位,

    linux命令dm数据库?

    linux命令dm数据库?,地址,软件,时间,设备,名字,服务,位置,名称,公司,命令,lin

    linux存储数据命令?

    linux存储数据命令?,系统,管理,数据,设备,情况,地址,工作,命令,服务,平台,Lin

    linux数据库查找命令?

    linux数据库查找命令?,位置,名称,状态,服务,软件,信息,系统,命令,名字,密码,

    linux数据库同步命令?

    linux数据库同步命令?,信息,系统,汽车,车辆,服务,工作,通信,一致,分析,数据,D

    linux建立数据库命令?

    linux建立数据库命令?,软件,系统,工作,数据,密码,工具,数据库,一致,网络,服

    linux命令进数据库?

    linux命令进数据库?,地址,系统,名字,服务,密码,命令,读法,数据库,操作系统,

    linux清空表数据命令?

    linux清空表数据命令?,系统,数据,软件,名称,不了,命令,文件,电脑,地址,位置,L

    linux拷贝数据命令?

    linux拷贝数据命令?,系统,地址,文件,数据,命令,目录,服务,基本知识,项目,密

    linux数据库检查命令?

    linux数据库检查命令?,服务,状态,地址,位置,系统,信息,命令,工作,情况,密码,

    linux命令进去数据库?

    linux命令进去数据库?,地址,服务,名字,系统,数据库,工具,基础,工作,管理,网

    linux数据库基础命令?

    linux数据库基础命令?,地址,工作,基础,系统,命令,信息,情况,工具,设备,目录,l

    linux数据共享命令?

    linux数据共享命令?,情况,系统,工具,网络,数据,软件,发行,设备,命令,文件,Lin

    命令发送数据linux?

    命令发送数据linux?,数据,地址,时间,工具,系统,设计,工作,网络,命令,综合,lin

    数据库导出命令linux?

    数据库导出命令linux?,数据,系统,名称,密码,软件,服务,情况,网上,工具,文件,L

    linux命令清空数据?

    linux命令清空数据?,服务,数据,名称,不了,百度,管理,档案,产品,命令,文件,删

    linux大数据在线命令?

    linux大数据在线命令?,工作,地址,系统,信息,管理,命令,数据,在线,目录,网络,l

    linux数据库删除命令?

    linux数据库删除命令?,软件,服务,产品,名称,系统,不了,地址,管理,电脑,命令,L

    linux数据库操作命令?

    linux数据库操作命令?,信息,系统,网络,地址,分析师,数据,名称,管理,基础,命

    linux连数据库命令?

    linux连数据库命令?,服务,地址,密码,名字,系统,软件,一致,命令,数据库,读法,