Мои программы на C# с dfs получают Runtime Error, видимо из-за переполнения стека.
Стандартный размер стека у треда в C# -- 1 МБ. Из-за этого программа без изменения размера стека падала на крупных тестах как на сервере, так и у меня локально.
Я прочитал, что новому треду при создании можно попытаться задать максимальный размер. Я увеличил его до 100 МБ, и это решило проблему локально, но на сервере решение продолжает падать. Возможно на сервере не хватает прав на увеличения стека.
Подскажите, пожалуйста, как мне справиться с этой проблемой.
Избавляйтесь от рекурсии. На codeforces стек у C# не увеличить.
Объясните "синему" (мне) как обходить граф в глубину без рекурсии.
Моделировать ручной стек.
BFS же, не?
Это DFS, если заменить
stack
наqueue
будет BFS.А можете написать реализацию, где при обходе в глубину для вершины вычисляется параметр исходя из таких же параметров сыновей, для конкретности поиск числа потомков для каждой вершины с помощью обхода в глубину (не рекурсивная реализация)?
Тем-же шаманством делаем топологическую сортировку, и находим число потомков начиная с листьев.
Век живи, век учись, спасибо.
Шаманство в студию!
UPD. Гонево какое-то.
Что это в принципе dfs — разумеется, да. Что он имеет все свойства рекурсивного dfs — разумеется, нет!!!
Присваивание
color[s.top()]=black;
происходит ДО!!! обработки потомков в дереве dfs. И, например, проверку ацикличности (только сказать "да, цикл есть" или "нет, цикла нету"), в рекурсивном виде имеющую видтрудно перевести в вышеупомянутый dfs вида
while(!mystack.empty) { ... }
Так что прав Shaykhutdinov-T-I, просящий написать прочие подробности реализации, а не минусующие его.
Лично я вот знаю только один способ — более точно эмулировать рекурсивный dfs, храня в стеке (структуре данных) не просто вершины, а пары "какая вершина; какой по порядку её сосед уже рассмотрен".
Спасибо, исправил.
Что-то я не верю, что такие изменения действительно решили проблему...
UPD. Сам дурак.
Вариант с покраской вершин (например, для того же поиска циклов):
UPD: это ответ на правку 2, следующие ещё не читал.
Согласен, это тоже можно привести к правильному виду (именно привести, см., например, http://ideone.com/pUkoq ; так как было — неправильно). Я в общем-то и не утверждал, будто необходимо хранить текущую рассматриваемую вершину. Я утверждал, что ранее предложенные развёртывания рекурсии в цикл с использованием вместо программного стека структуры данных стек не умели различать три ситуации:
вершина ещё вообще никак не исследована, в неё ещё не вошли
в вершину вошли, но не вышли (продолжается рассмотрение подграфа, достижимого из неё)
уже произошёл откат рекурсии через эту вершину
(Например, есть граф с рёбрами 1->2, 1->3 и 2->3. Если мы уже посещали вершину 3 через 1->2->3, а потом ещё раз посетили через 1->3, это никоим образом не цикл.). Так что (1) от (2 и 3) надо отличать, чтоб принимать решение, надо ли именно тут продолжать поиск. (2) от (1 и 3) надо отличать, чтоб видеть действительно ли прямо сейчас обнаружен цикл.
Спасибо за указание способа, как это всё же можно сделать.
С другой стороны, я всё же не уверен, действительно ли указанный Вами способ объективно лучше хранения в стеке и текущей вершины, и текущего соседа (как собственно и делает рекурсия).
Например, надо опять-таки проверить ацикличность, но если цикл есть, то предъявить его (весь цикл). В реализации, предложенной мной, вершины, составляющие цикл, будут идти в структуре данных стек подряд, а в предложенной Вами — нет.
Например, орграф имеет n-1 дугу, все вида 1->i при i от 2 до n: предложенный Вами способ нарастит размер стека до n, хотя ни рекурсия ни точная её эмуляция так делать не будут.
Так что они скорее альтернативные, каждый имеет достоинства и недостатки.
Через стэк. UPD: блин, надо обновлять страничку перед тем, как комментировать -_-
Если нельзя увеличить размер стека, то это печаль Не для того я решаю задачи по СП, чтобы писать дфс без рекурсии
Не для того я решаю задачи по СП, чтобы получать WA.
Подниму старую тему. Вопросы по С#:
Во время работы c# от Microsoft проблемы со стеком не было, и вот она опять появилась