Фон: я создаю trie для представления словаря, с помощью минимального алгоритма конструкции. Входной список 4.3M utf-8 строки, отсортированные лексикографически. Получающийся график является нециклическим и имеет максимальную глубину 638 узлов. Первая строка моего сценария устанавливает предел рекурсии к 1100 через sys.setrecursionlimit()
.
Проблема: я хотел бы смочь сериализировать свой 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
содержит булево поле, строковое поле и словарь, отображающийся от маркировки для утверждения.
Я не очень знаком с внутренними работами pickle
- моя макс. глубина рекурсии должна быть большими/равными n временами глубина trie для некоторого n? Или это могло быть вызвано чем-то еще, о чем я не знаю?
Обновление: Установка глубины рекурсии до 3 000 не помогла, таким образом, эта авеню не выглядит многообещающей.
Обновление 2: Вы парни были правы; я был близорук в предположении, что рассол будет использовать маленькую глубину вложения из-за ограничений рекурсии по умолчанию. 10,000 добился цели.
Это довольно точное отражение моего собственного понимания темы статической / динамической, сильной / слабой наборной дискуссии. Кроме того, вы можете рассмотреть эти другие языки:
на языках, таких как TCL и Bourne Shell, тип «основной» тип значения - это строка. Числовые операторы доступны, что неявно пострадают входные значения из строкового представления и значения результатов в строковое представление. Их можно считать примерами динамических, слабо напечатанных языков.
Далее может быть примером статического, слабо напечатанного языка. Язык выполняет свою собственную проверку типа, а основной стек может взаимозаменяться с взаимозаменяющимися указателями, целыми числами, строками (условно представленными как две ячейки, начало и длина). Непоследовательное использование операторов может привести к интересному или неуточненному поведению. Типичные реализации предоставляют отдельный стек для количества плавающих точек.
-121--2338751-Из документов :
Пытаться на созревание высококурсную структуру данных может превышать максимальную глубину рекурсии, в этом случае будет подниматься runceError. Вы можете тщательно поднять этот предел со уровнем
Sys.Setrocursionlimit ()
.
Хотя ваша реализация TRIE может быть проста, она использует рекурсию и может привести к проблемам при преобразовании в постоянную структуру данных.
Моя рекомендация будет продолжать повысить предел рекурсионного периода, чтобы увидеть, есть ли верхняя граница данных, с которыми вы работаете, и реализация TRIE, которую вы используете.
Другое, что вы можете попробовать изменить свою реализацию дерева, чтобы быть «менее рекурсивным», если возможно, или напишите дополнительную реализацию , которая имеет встроенный настойчивость данных (используйте соленья и полки В вашей реализации). Надеюсь, что помогает
Дважды проверьте, что ваша структура действительно AcyClic.
Вы можете попробовать наталкивать предел еще дальше. Там сложно, что зависит от платформы, но попытка 50000 будет разумной.
Также попробуйте обрезать тривиально небольшую версию вашего TRIE. Если совокупность умирает, даже если он хранят только пару трехбуквенных слов, то вы знаете, что есть какая-то фундаментальная проблема с вашим ТРИ, а не соленье. Но если это произойдет только тогда, когда вы попробуйте хранить 10K слов, то это может быть неисправность ограничения платформы в расчету.
Парил должен рекурсивно пройти твой Три. Если соленья использует только 5 уровней функционных вызовов, чтобы выполнить работу, которую ваша TRE из глубины 638 понадобится уровень, установленный на уровне более 3000.
Попробуйте намного больше числа, предел рекурсии действительно просто для защиты пользователей ждать слишком долго, если рекурсия падает в бесконечное отверстие.
Мариновые ручки циклы ОК, так что не имеет значения, даже если у вашего Три был цикл там