2016-06-16 102 views
3

我已經在Python中創建了一個遺傳編程系統,但是遇到了與內存限制有關的問題。問題在於將所有人存儲在我的人羣中。目前,我將所有人存儲在內存中,然後再生成下一代的人口,然後將其存儲到內存中。這意味着我有兩個人羣值得記憶加載。經過一些測試後,我發現我相當快地超過了Windows的默認2GB應用程序內存大小。將對象存儲在文件而不是內存中

目前,我寫出了整個人口的單個樹木到一個文件,然後我可以加載和重新創建人口,如果我想。我一直在考慮的不是讓所有人都加載到內存中,而是通過從文件中拉出個人並僅實例化該單個人來訪問個人信息。根據我對Python的readline功能的理解,它應該一次只加載一行文件,而不是整個文件。如果我這樣做了,我想我只能記憶我當前操縱的個人。

我的問題是,有沒有一個突出的問題,這樣做,我現在沒有看到?我明白,因爲我正在處理磁盤而不是內存中的數據,所以我的性能會受到影響,但是對於這種情況,內存比速度更重要。另外我不想增加分配給Python程序的2GB內存。

謝謝!

+0

你有沒有考慮使用數據庫的原因? –

+0

從文件中提取單個記錄意味着通過文件讀取,直到找到正確的記錄。我強烈建議移動到具有現代64位環境和合理數量的RAM的計算機。如果您想優化程序,請提供[MCVE](http://stackoverflow.com/help/mcve)。如果它目前有效,請考慮詢問代碼審覈。 – TigerhawkT3

+0

@ IgnacioVazquez-Abrams我曾考慮過,但在每代人中至少有95%的人口被替換。它似乎並不像使用數據庫是正確的方向,因爲數據記錄只能持續很短的時間。 – Tory

回答

2

由於RAM的限制,我會改變人口模型從世代到穩態

這個想法是反覆培育一兩個新的孩子,評估他們的健康狀況,然後直接重新將它們引入人羣中,殺死一些預先存在的人爲他們騰出空間。

穩態使用傳統遺傳算法的一半內存,因爲一次只有一個人口。

改變實現不應該太難,但你必須注意過早收斂(即調整參數,如變異率,聯賽大小......)。

島模型是另一個/附加可能性:人口被分成單獨的子羣(demes)。德姆斯將個人送到彼此,以幫助傳播新發現的空間合適區域的消息。

通常這是一個異步機制,但是你可以使用一個同步算法,裝載demes一個接一個,有極大地減少所需的內存資源。


當然,你可以寫人口到一個文件,你可以加載所需的個人。如果選擇這種方法,計算個體的散列簽名以優化識別/加載速度可能是一個好主意。

無論如何,你應該考慮到,根據你的GP系統正在執行的任務,你可以註冊一個巨大的性能。

+0

我認爲穩定狀態可能是我將要面對的方向。因爲你沒有真正的世代,你是否需要標記每個人的適應度是否被計算,然後每次迭代循環計算一次錯誤標記個人的健康狀況,還是隻要個人被添加到人口計算他們的健身? – Tory

+0

@Tory如果您使用某種形式的精英主義,您立即需要健身(您必須將新人與您想要替換的人進行比較)。 – manlio

0

請記住,如果您使用穩態,則需要一些方法讓Fittest個體交叉繁殖的概率高於不適合的個體。

你能想到約上幾個附加選項:

一)使用SQLLite。 (https://docs.python.org/2/library/sqlite3.html)。這將具有使用數據庫的所有性能優勢(可能更多)以及使用文件的簡單性和易用性。

b)有一個混合非穩態模型,允許保留一個大的,未評估的Polulation,尺寸M和適合的個體大小爲N的「倖存者集合」,其中M >> N。人口是一個隊列的解決方案對象,但SurvivorSet是「EvaluatedSolutions」(適用於Fitness的解決方案)的有限尺寸的Heap。所以,你繼續從普通人羣那裏獲得解決方案,對它們進行評估,然後將它們放入評估解決方案堆中(按照適應度降序排列)並剪切前N個元素。這樣,你的記憶力消耗保持不變,但你擁有內置精英的概念。這也允許通過只使用精英作爲繁殖種羣來做一些很酷的技巧,如「繁殖」。

相關問題