Итак, я успешно реализовал рекурсивный тарджан, который предоставляет мне SCC графика
Моя рекурсивная реализация выглядит следующим образом:
public void DFSRecursive(long currentNode){
low[currentNode] = preCount++;
visited[currentNode] = true;
stack.Push(currentNode);
long minimum = low[currentNode];
foreach(long successorNode in SuccessorMap[currentNode])
{
if(!visited[successorNode])
{
DFSRecursive(successorNode);
}
if(low[successorNode] < minimum)
{
minimum = low[successorNode];
}
}
if(minimum < low[currentNode])
{
low[currentNode] = minimum;
return;
}
List<long> component = new List<long>();
long stackTop;
do
{
stackTop = stack.Pop();
component.Add(stackTop);
}
while(stackTop != currentNode);
SCComponent.Add(component);
}
Теперь мне нужно преобразовать это в итеративное решение. Я уже проверил много ресурсов, чтобы помочь мне, включая очень похожий вопрос SO ( нерекурсивная версия алгоритма Тарьяна ). Я не могу использовать перечислитель, поскольку мне приходится иметь дело с длинными значениями, а индексы преемника текущего состояния хранятся в словаре (SuccessorMap []) (необходимо иметь дело с графами с числом узлов> 5 миллиардов).
Я следовал общим рекомендациям по преобразованию рекурсивного решения в итеративное:
- Заменил рекурсивный вызов на push в локальный стек
- Заменены «возвраты» на pop из локального стека
Установите переменные в начале цикла и выскочили из локального
стек
public void DFSIterative(long currentNode)
{
var internalStack = new Stack<long>();
low[currentNode] = preCount++;
stack.Push(currentNode);
long minimum = low[currentNode];
internalStack.Push(currentNode);
while(!(internalStack.Count == 0))
{
currentNode = internalStack.Pop();
visited[currentNode] = true;
foreach(long successorNode in SuccessorMap[currentNode])
{
if(!visited[successorNode])
{
internalStack.Push(successorNode);
}
if(low[successorNode] < minimum)
{
minimum = low[successorNode];
}
}
if(minimum < low[currentNode])
{
low[currentNode] = minimum;
return;
}
}
List<long> component = new List<long>();
long stackTop;
do
{
stackTop = stack.Pop();
component.Add(w);
}
while(stackTop != currentNode);
SCComponent.Add(component);
}
Я признаю, что цикл do-while в итеративном методе всегда будет выдавать InvalidOperationException(stack empty)
, но я не знал, как реализовать рекурсивный do-while итеративно.
Был бы очень признателен за любую помощь, чтобы помочь мне.