您可以从simple 开始。假设您将图表存储在字典中:
#!/usr/bin/env python2
# coding: utf-8
def read(filename):
"""
Read a graph from a file. Returns a dictionary.
The file must be in the format:
SRC DST DST ...
SRC DST
...
where SRC and DST are names of nodes.
Node names must not contain whitespace.
"""
g = {}
with open(filename) as handle:
for line in handle:
line = line.strip()
if line == "":
continue
parts = line.split()
src, targets = parts[0], parts[1:]
if src not in g:
g[src] = set()
for target in targets:
g[src].add(target)
return g
def write(filename, g):
""" Write dictionary `g` to file. """
with open(filename, "w") as handle:
for src, targets in g.iteritems():
handle.write("%s %s\n" % (src, " ".join(targets)))
示例用法:
if __name__ == '__main__':
g = {
"A": ["B", "C"],
"B": ["D"],
"C": ["B"],
}
write("test.g", g)
g = read("test.g")
print(g) # {'A': set(['C', 'B']), 'C': set(['B']), 'B': set(['D'])}
上面定义了一个图的简单序列化格式,实现了读写方法。虽然效率确实很低,但您可以单独使用这两种方法创建、更新和更改图表并将它们保存到磁盘。
这会将整个图形存储在内存中。作为下一个优化,您可以编写方法 - 例如read_node(filename, nodename) 只会将给定节点加载到内存中。通过这种方式,您可以存储和使用大于可用内存的图形。
这当然仍然非常低效,因为您需要读取整个文件才能找到您正在寻找的节点。
然后您可以添加进一步的优化,例如存储排序的数据并使用二进制搜索快速找到具有给定名称的节点。或者,您可以沿图表数据存储其他数据以用于索引目的。您可以将一个小索引加载到内存中,查找您关心的节点,然后寻找存储数据的位置并仅读取相关块。
等等。经过大量探索后,您可能会得到更高级的数据结构,例如 B-trees、Log-structured merge-trees 或 inverted indices。