Удар Максимальной Глубины рекурсии Используя Рассол / cPickle

Фон: я создаю 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 добился цели.

51
задан martineau 1 December 2017 в 02:43
поделиться

3 ответа

Это довольно точное отражение моего собственного понимания темы статической / динамической, сильной / слабой наборной дискуссии. Кроме того, вы можете рассмотреть эти другие языки:

на языках, таких как TCL и Bourne Shell, тип «основной» тип значения - это строка. Числовые операторы доступны, что неявно пострадают входные значения из строкового представления и значения результатов в строковое представление. Их можно считать примерами динамических, слабо напечатанных языков.

Далее может быть примером статического, слабо напечатанного языка. Язык выполняет свою собственную проверку типа, а основной стек может взаимозаменяться с взаимозаменяющимися указателями, целыми числами, строками (условно представленными как две ячейки, начало и длина). Непоследовательное использование операторов может привести к интересному или неуточненному поведению. Типичные реализации предоставляют отдельный стек для количества плавающих точек.

-121--2338751-

Из документов :

Пытаться на созревание высококурсную структуру данных может превышать максимальную глубину рекурсии, в этом случае будет подниматься runceError. Вы можете тщательно поднять этот предел со уровнем Sys.Setrocursionlimit () .

Хотя ваша реализация TRIE может быть проста, она использует рекурсию и может привести к проблемам при преобразовании в постоянную структуру данных.

Моя рекомендация будет продолжать повысить предел рекурсионного периода, чтобы увидеть, есть ли верхняя граница данных, с которыми вы работаете, и реализация TRIE, которую вы используете.

Другое, что вы можете попробовать изменить свою реализацию дерева, чтобы быть «менее рекурсивным», если возможно, или напишите дополнительную реализацию , которая имеет встроенный настойчивость данных (используйте соленья и полки В вашей реализации). Надеюсь, что помогает

36
ответ дан 7 November 2019 в 10:21
поделиться

Дважды проверьте, что ваша структура действительно AcyClic.

Вы можете попробовать наталкивать предел еще дальше. Там сложно, что зависит от платформы, но попытка 50000 будет разумной.

Также попробуйте обрезать тривиально небольшую версию вашего TRIE. Если совокупность умирает, даже если он хранят только пару трехбуквенных слов, то вы знаете, что есть какая-то фундаментальная проблема с вашим ТРИ, а не соленье. Но если это произойдет только тогда, когда вы попробуйте хранить 10K слов, то это может быть неисправность ограничения платформы в расчету.

3
ответ дан 7 November 2019 в 10:21
поделиться

Парил должен рекурсивно пройти твой Три. Если соленья использует только 5 уровней функционных вызовов, чтобы выполнить работу, которую ваша TRE из глубины 638 понадобится уровень, установленный на уровне более 3000.

Попробуйте намного больше числа, предел рекурсии действительно просто для защиты пользователей ждать слишком долго, если рекурсия падает в бесконечное отверстие.

Мариновые ручки циклы ОК, так что не имеет значения, даже если у вашего Три был цикл там

9
ответ дан 7 November 2019 в 10:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: