2011-03-05 53 views
2

我意識到答案很可能是'不'!是否可以強制cPickle使用寬度優先而不是深度優先遞歸?

基本上,我有一個圖(節點和邊類),它表示一個正方形網格;每個節點對象都包含對該節點具有邊緣的每個其他節點的引用,這似乎意味着,當使用cPickle.dump對圖進行序列化時,它會以深度優先的方式遍歷圖中的每個節點,這意味着對於一個井表示16x16網格的連接圖,它將其視爲256級深度數據結構。這意味着更大的網格會很快超過默認的最大Python遞歸深度,特別是因爲實驗表明,似乎要在堆棧上進行大約4次調用才能在數據結構中增加一個額外的級別。

事情是,我也有一個dict-of-dicts引用這個圖表的方式,使我能夠使用笛卡爾座標來找到特定的節點(例如「node = nodes [3] [6] 「)。所以從概念上講,它不是一個高度嵌套的數據結構,它是一個相當平坦的一個,它恰好有很多側面引用,但似乎cPickle完全是深度優先的(我知道這是迄今爲止最簡單的方法工作)。

現在,我瞭解了sys.setrecursionlimit(),並且我已經做了一些實驗,以瞭解我需要設置圖表大小的限制,因此這是'最簡單的'選項。我知道我可以放棄節點到節點的鏈接,並依靠字典來維護網格和單獨的平面結構以保持邊緣權重,但是我想避免各種原因這不僅僅是節點到節點的鏈接允許更直觀地使用數據結構。我相信從我讀過的內容中,我應該能夠提供我自己的實現__getstate____setstate__並覆蓋酸洗功能,但顯然這是一個不重要的工作量。如果有一種方法可以獲得cPickle(或泡菜,我不挑剔!)使用寬度優先遍歷,它應該很簡單地解決問題!

回答

1

寫一個合適的__getstate__()方法似乎並不複雜。嘗試類似

class Node(object): 
    def __getstate__(self): 
     state = self.__dict__.copy() 
     state.pop("neighbours") 
     return state 

這將醃製Node實例的所有屬性除了neighbours屬性,我假設包含鏈接到鄰居。 (您不需要__setstate__()方法。)

取消整個圖形之後,您必須重新創建到所有節點上的鄰居的鏈接,但這也不應該那麼困難。

+0

我很擔心編碼問題,然後重新構建邊緣數據,但是我完全忘記了\ dict__屬性,而且我不確定我是否知道字典有'pop'方法,所以謝謝你的信息!出於興趣,爲什麼在這種情況下使用'流行'而不是'del' - 僅僅爲了魯棒性? (我想我必須在\ _ \ _ setstate__中完成這項工作,因爲我無法控制代碼被醃製的代碼。) – 2011-03-05 22:39:04

+0

@Jake:想想看,'del'似乎比使用'.pop()'更自然,但實際上並不重要。關鍵是你可以在酸洗之前以某種方式去除鄰居的鏈接,之後重新構建它們,整個事情不應該那麼困難。 – 2011-03-06 00:33:12