#python #алгоритм #рекурсия
Во время выполнения моего алгоритма, много раз вызывается рекурсивный dfs, после чего я получаю RuntimeError: maximum recursion depth exceeded in instancecheck Такое ощущение, что происходит накопление рекурсивных вызовов за всё время работы программы. После превышения порога в сумме sys.setrecursionlimit(20000) программа падает. Как с этим бороться? Я приведу псевдокод моего алгоритма: func dfs(current): global labels labels[current] = true for neighbour in get_neighbours(current): if not (labels[neighbour]): dfs(neighbour) do_smth() for item in range(0, n): dfs(item) // Происходит несколько итераций цикла, после чего прога падает. При увеличении значения n в sys.setrecursionlimit(n) алгоритм выполняет больше итераций в цикле, но всё равно падает. Таким образом, в некоторый момент возникает вышеуказанная ошибка. Замечу, что данная ошибка возникает у меня уже не первый раз. Возникает она в любом месте, где есть достаточное количество вызовов рекурсивных алгоритмов с большой глубиной рекурсии. Замечу, что в коде нет терминального условия, но это не означает, что код будет выполняться бесконечно. Прокомментирую. Мы рассматриваем граф G(V, E). Будем перебирать вершины, начиная с любой. Каждую вершину мы будем помечать, если мы в ней были. Это делается следующей командой: labels[current] = true Для каждой вершины мы перебираем всех её соседей: for neighbour in get_neighbours(current): Если в вершине-соседе мы были, то в неё заходить не следует. Если же нет, то перейдём в нее. Проверка были мы там или нет осуществляется так: if not (labels[neighbour]): Далее переходим в вершину: dfs(neighbour) О конкретном алгоритме можно прочесть здесь. Но спешу заметить, что вопрос заключается не в алгоритме, а в принципах устройства python. Подробное описание кода я привёл лишь для того, чтобы снять сомнения в его работоспособности. Код взят лишь как пример и не более того.
Ответы
Ответ 1
Посмотрите внимательно на Вашу функцию func dfs(current): global labels labels[current] = true for neighbour in get_neighbours(current): if not (labels[neighbour]): dfs(current) do_smth() Я удалю несколько часть строк, что бы показать явную проблему func dfs(current): # dfs(current) # переменная current не меняется внутри функции. И получается, что значение фукнции зависит от значения функции. Такая рекурсия никогда не закончится. Именно для этого в большинстве интерпретаторов есть защита от таких бесконечных рекурсий - лучше программисту сразу намекнуть, что его код подозрительный. Что делать? Исправить код. Как минимум, думаю нужно изменить параметр. А вот как именно - это только Вы знаете.Ответ 2
Может вам надо переписать DFS на нерекурсивную версию? Я в алгоритмах 0 но https://stackoverflow.com/a/21508819/1717474 вот ответ на ваш вопрос по моему, а если вам надо времена входа/выхода "корректные" то все сложнее: https://stackoverflow.com/a/43906820/1717474
Комментариев нет:
Отправить комментарий