/// <summary> /// Find all paths starting with the given node /// </summary> /// <param name="node">Starting node</param> public void SearchFrom(NodeType node) { stack.Push(node); isBlocked[node] = true; bool canExtend = false; foreach (NodeType target in graph.TargetsOf(node)) { if (isBlocked[target]) { continue; } // recursive call SearchFrom(target); canExtend = true; } isBlocked[node] = false; if (!canExtend && stack.Count > 1) { // path has multiple nodes and cannot be extended OnBeginPath(); Stack <NodeType> temp = new Stack <NodeType>(); foreach (NodeType nodeOnStack in stack) { temp.Push(nodeOnStack); } foreach (NodeType nodeOnStack in temp) { OnAddNode(nodeOnStack); } OnEndPath(); } stack.Pop(); }
/// <summary> /// Find cycles containing root /// </summary> /// <param name="node"></param> /// <param name="root"></param> /// <returns></returns> private bool SearchFrom(NodeType node, NodeType root) { bool foundCycle = false; stack.Push(node); isBlocked[node] = true; foreach (NodeType target in graph.TargetsOf(node)) { if (excluded.Contains(target)) { continue; } if (target.Equals(root)) { foundCycle = true; OnBeginCycle(); Stack <NodeType> temp = new Stack <NodeType>(); foreach (NodeType nodeOnStack in stack) { temp.Push(nodeOnStack); } foreach (NodeType nodeOnStack in temp) { OnAddNode(nodeOnStack); } OnEndCycle(); } else if (!isBlocked[target]) { // recursive call if (SearchFrom(target, root)) { foundCycle = true; } } } // at this point, we could always set isBlocked[node]=false, // but as an optimization we leave it set if no cycle was discovered, // to prevent repeated searching of the same paths. if (foundCycle) { Unblock(node); } else { // at this point, all targets are blocked foreach (NodeType target in graph.TargetsOf(node)) { if (excluded.Contains(target)) { continue; } Set <NodeType> blockedSourcesOfTarget = blockedSources[target]; if (blockedSourcesOfTarget == null) { blockedSourcesOfTarget = new Set <NodeType>(); blockedSources[target] = blockedSourcesOfTarget; } blockedSourcesOfTarget.Add(node); } } stack.Pop(); return(foundCycle); }