是否有可能强制cPickle使用广度优先而不是深度优先递归?

时间:2011-03-05 21:17:19

标签: python recursion pickle

我意识到答案很可能是'不'!

基本上,我有一个图形(节点和边缘类型),它代表一个正方形网格;每个节点对象包含对此节点具有边缘的每个其他节点的引用,这似乎意味着当使用cPickle.dump对图表进行序列化时,它以深度优先的方式遍历图中的每个节点,这意味着对于一个井表示16x16网格的连接图,它有效地将其视为256级深度数据结构。这意味着更大的网格很快超出默认的最大Python递归深度,特别是因为实验表明它似乎需要在堆栈上进行大约4次调用才能在数据结构中增加一个额外的级别。

问题是,我还有一个dict-of-dicts,它以这样的方式引用到这个图中,以便允许我使用笛卡尔坐标来查找特定节点(例如“node = nodes [3] [6]” )。从概念上讲,它根本不是一个高度嵌套的数据结构,它是一个相当扁平的数据结构,碰巧有很多侧面引用,但似乎cPickle完全以深度优先工作(我理解这是迄今为止最简单的方法)工作)。

现在,我了解了sys.setrecursionlimit(),并且我已经做了一些实验来找出我需要多大才能设置图形大小的限制,因此这是“最简单”的选项。我知道我可以退出节点到节点的链接,并依靠字典来保持网格和单独的扁平结构以保持边缘权重,但我有多种理由想避免 - 尤其是节点到节点链接允许更直观地使用数据结构。我相信从我读过的内容中我应该能够提供自己的__getstate____setstate__实现并覆盖酸洗功能,但显然这是一项非常重要的工作。如果有办法让cPickle(或泡菜,我不挑剔!)使用广度优先遍历,它应该很简单地解决问题!

1 个答案:

答案 0 :(得分:1)

毕竟,编写合适的__getstate__()方法似乎并不复杂。尝试像

这样的东西
class Node(object):
    def __getstate__(self):
        state = self.__dict__.copy()
        state.pop("neighbours")
        return state

这将挑选Node实例的所有属性,但neighbours属性除外,我假设该属性包含到邻居的链接。 (您不需要__setstate__()方法。)

取消整个图形的图形后,您将不得不重新创建所有节点上邻居的链接,但这也不应该那么困难。