質問

その背景:私の構築trieを表す辞書を使用し、最小限の構築アルゴリズムです。の入力一覧表は4.3M utf-8文字列、並び辞書的.このグラフは非環式で、最大深度の638ノード。最初の行のスクリプトの再帰制限1100介 sys.setrecursionlimit().

の問題:持ってき方など、さすがだなと私がserialize私のtrieをディスクだったので、読み込みメモリな初から再取得(約22分)しかし、両 pickle.dump()cPickle.dump(), 両方のテキストおよびバイナリプロトコル各時間を取得しますスタックトレースとは、以下に示すようになります:

  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 725, in save_inst
    save(stuff)
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 648, in save_dict
    self.memoize(obj)
RuntimeError: maximum recursion depth exceeded

私のデータ構造は比較的シンプルです: trie への参照が含まれて始め、義されています。 dfa_state 含まれるbooleanフィールドは、文字列の分野では、辞書のマッピングからラベルの状態です。

私はあまり馴染みの仕組み pickle -は私の最大再帰深度が必要なよ/equal n倍の深さは、trieの一n?またはこのようん知らなか?

更新: 設定の再帰深度3000ん、このavenueんが期待できます。

更新2: だった右;また近視眼と漬物をご利用い小さな入れ子の深さによりデフォルトの再帰限界がある。10,000かったですよね。

役に立ちましたか?

解決

から のドキュメント:

う漬けの高い再帰的データ構造を超える場合がありますの最大限の再帰深度、RuntimeErrorまで引き上げられます。き厳し上げ限界 sys.setrecursionlimit().

がtrieを実施するシンプルですが、利用再帰な考えを持つこと自体が問題に変換する場合に永続的なデータ構造です。

私のお薦めいき上げの再帰制限がきていることを確認して下さい小限のデータを使って作業の再生実装されています。

その他そのお試しいただくことが可能で変更するツリーを実施する"以下"再帰的な"できれば、書き 追加で実施 るデータ残存型の利用や漬物 に実施。のこ

他のヒント

ピクルスは、再帰的にあなたのトライを歩くする必要がありません。ピクルスは、仕事をするために、関数呼び出しのちょうど5つのレベルを使用している場合は深さ638のあなたのトライは3000以上にレベルセットが必要になります。

がはるかに大きい数を試してみて、再帰制限は再帰が無限の穴に落ちる場合が長すぎる待つことからプロテクトのユーザーにただそこに実際にある。

ピクルスハンドルサイクル[OK]を、ので、それはあなたのトライがある

でサイクルを持っていても問題ではありません

スタックサイズのものとともに増加し resource.setrlimit 防segfault

ご利用の場合だけで sys.setrecursionlimit, することができsegfaultに到達した場合、最大スタックサイズによって許可されるLinuxカーネルです。

この値を増すことができると resource.setrlimit としてお話ししたように、これまで: 設定が大きく、pythonスクリプト

import pickle
import resource
import sys

print resource.getrlimit(resource.RLIMIT_STACK)
print sys.getrecursionlimit()

max_rec = 0x100000

# May segfault without this line. 0x100 is a guess at the size of each stack frame.
resource.setrlimit(resource.RLIMIT_STACK, [0x100 * max_rec, resource.RLIM_INFINITY])
sys.setrecursionlimit(max_rec)

a = []
# 0x10 is to account for subfunctions called inside `pickle`.
for i in xrange(max_rec / 0x10):
    a = [a]
print pickle.dumps(a, -1)

参照: が必要な場合は、当社まで再帰深度ドするにはどうしたらいいのか、ですか?

デフォルトの最大値というのは8Mb.

試Ubuntu16.10、Python2.7.12.

あなたの構造は確かに非環式であることをダブルチェックます。

あなたも、さらに制限をぶつけてみてください。そこプラットフォーム依存のハード最大のだが、50000をしようとすることは合理的である。

また、あなたのトライの些細な小さなバージョンを酸洗してみてください。ピクルスは、それが唯一のカップル3文字の単語を格納していますにもかかわらず死亡した場合、あなたはあなたのトライといくつかの根本的な問題があると知って、酸洗いません。あなたは10Kの単語を格納しようとすると、それだけで発生した場合でも、それはピクルスで、プラットフォームの制限の故障かもしれません。

私は.txt形式で私の辞書を保存することで、この問題を解決したように、

私のニーズはややすぐに出ました。唯一のことは、あなたがあなたのファイルをロードする際、再びあなたが辞書に戻ってそれを変換しなければならないということです。

import json

# Saving the dictionary
with open('filename.txt', 'w') as file_handle:
    file_handle.write(str(dictionary))

# Importing the .txt file
with open('filename.txt', 'r') as file_handle:
    f = '"' + file_handle.read() + '"'

# From .txt file to dictionary
dictionary = eval(json.loads(f))

これはあなたがJSON形式を使用して辞書をエクスポートしようとして動作しない場合ます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top