在内存空间或构建时间方面,有没有人知道保存图形信息的更有效方法(即比将其保留为二维数组更有效)?
你可以假设它的值限制在0-255之间。
感谢名单!
答案 0 :(得分:3)
以下是表示(定向)图表的几种标准方法:
对于4个节点的图表:
邻接矩阵:
0 1 2 3
0 F F T F
1 T F T T
2 T F F F
3 F F F F
边缘清单:
((0, 2), (1, 0), (1, 2), (1, 3), (2, 0))
邻接清单:
(
(0, (2,) ),
(1, (0, 2, 3)),
(2, (0,) ),
(4, (,) ),
)
邻接矩阵是简单且最快的表示,但占用的内存最多(N * N,其中N是行数),除非你有一个非常密集的图形。如果你只有一个简单的未加权图,你可以通过使用位数来节省一些内存。
边缘列表很简单,但比邻接矩阵慢,如果你有一个稀疏图形(2 * M,其中M是边数),则内存效率很高。
邻接列表稍微复杂一些(因为你需要可变大小的数组),但是如果你有大量的边(2 * N + M,其中N是顶点的数量,M,则边缘列表的内存效率更高)边数)
邻接矩阵占用(N N b)空间。边缘列表采用((2 + b)* N)内存。并且邻接列表采用(2 * N + M *(1 + b))存储器。
如果您知道总是少于256个顶点(8位),并且权重小于256(8位),则邻接矩阵需要(N * N * 8)个空格。边缘列表占用(24 * N)内存。邻接列表采用(16 * N + M * 16)内存。
答案 1 :(得分:2)
如果创建后不需要修改图形,请查看压缩稀疏行(CSR)格式。来自BGL的说明:
CSR格式存储顶点和 在单独的数组中的边,与 这些数组的索引 对应于的标识符 分别是顶点或边缘。该 edge数组按来源排序 每个边缘,但只包含 边缘的目标。顶点 数组将偏移存储到边缘 数组,提供偏移量 从每个顶点传出的第一条边。 迭代在外边缘 图中的顶点是通过 访问edge_array [vertex_array [i]], edge_array [vertex_array [i] +1],..., edge_array [vertex_array [I + 1]]。这个 格式最小化内存使用到O(n + m),其中n和m是数字 顶点和边分别。该 常数乘以n和m 基于整数的大小 需要将指数表示为 边和顶点数组,分别为(...)
Here是偏移数组的一个很好的解释:
Offset Neighbours 1 1 --------------> 2 2 3 ------------ 3 3 5 ---------- |-> 1 4 9 -------- | 3 5 10 ------ | |---> 1 6 12 ---- | | 2 7 14 -- | | | 4 | | | | 6 | | | -----> 3 | | -------> 6 | | 7 | ---------> 5 | 7 -----------> 5 6
创建后允许插入边缘可以通过将Neighbours
数组基本上变成“链表”来实现。偏移点
进入第一个邻居,每个邻居包含一个Next
字段。这指向下一个边缘。
来自同一来源:
Offset Node Next 1 1 --------------> 2 2 2 3 ------------ 3 -1 3 5 ---------- |-> 1 4 4 9 -------- | 3 -1 5 10 ------ | |---> 1 6 6 12 ---- | | 2 7 7 14 -- | | | 4 8 | | | | 6 9 | | | -----> 3 -1 | | -------> 6 11 | | 7 -1 | ---------> 5 13 | 7 -1 -----------> 5 15 6 -1
答案 2 :(得分:1)
如果图形相当稀疏,那么您将通过将其存储为边缘列表(从节点到节点)而不是邻接矩阵来节省空间。如果所有边都是双向的,那么你当然只需要存储一次边。
答案 3 :(得分:0)
我在这里找到了有用的图表表示列表: