Python Networkx:saving/serializing 网络到硬盘时保留节点 ID

Python Networkx: preserving nodes ID when saving/serializing networks to hardisk

我在 Python 中使用 networkx1.10 的项目需要将网络转储到硬盘上,然后重新加载它们,以便继续执行一些操纵此类网络的算法。

我一直在尝试以几种不同的方式做到这一点:首先使用 nx.write_gml() 和 nx_read_gml(),现在使用 pickle/cpickle.

虽然从表面上看一切似乎都正常,但我注意到无论 saving/loading 在某个时间点是否发生,我在模拟中得到了不同的结果。

我认为这可能与某些网络似乎被 dumping/reloading 程序修改有关(这当然是意外的)。

为了调试,现在我用 pickle 保存并重新加载每个网络,比较它们在 dumping/reloading 前后的 gml 表示(通过 nx.write_gml / nx.generate_gml 实现)。这样做时,我注意到了一些差异。

在某些情况下,修改的只是一些图形属性的顺序,不会对我的程序造成任何损害。在其他情况下,gml 表示中两条边出现的顺序不同,同样没有坏处。

但是,经常会修改某些节点的 ID,如本例所示:

https://www.diffchecker.com/zvzxrshy

虽然边缘似乎被相应地修改,因此网络看起来是等效的,但 ID 中的这种变化可能会改变我的模拟(出于我不打算解释的原因)。

我相信这可能是我问题的根源。

您知道为什么会发生这种情况吗,即使是在使用 pickle/cpickle 实现的低级序列化机制时也是如此?

如何保证序列化前后的网络完全一致?

我正在做这样的事情:

with open('my_network.pickle', 'wb') as handle:
    pickle.dump(my_network, handle, protocol=pickle.HIGHEST_PROTOCOL)
...
with open('my_network.pickle', 'rb') as handle:
    my_network_reloaded = pickle.load(handle)

# compare nx.write_gml for my_network and my_network_reloaded

非常感谢任何帮助:过去三天我一直在与这个问题作斗争,我快要疯了!

谢谢

它们似乎是相同的图形,甚至同构。

您的问题可能是节点顺序。的确,networkx使用dicts来存储节点和边,这些节点和边是无序和随机的。

您有两个解决方案:要么忽略它,要么使用有序图:

>>> class OrderedGraph(nx.Graph):
...    node_dict_factory = OrderedDict
...    adjlist_dict_factory = OrderedDict
>>> G = OrderedGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1), (1,1)) )
>>> G.edges()
[(2, 2), (2, 1), (1, 1)]

(示例来自 the documentation of the Graph class