private static void StrongConnect(Vertex firstVertex) { Stack<Vertex> stack = new Stack<Vertex>(); stack.Push(firstVertex); while (stack.Count > 0) { Vertex v = stack.Pop(); v.index = index; v.lowlink = index; index++; S.Push(v); foreach (Vertex w in v.Adj) { if (w.index < 0) { StrongConnect(w); v.lowlink = Math.Min(v.lowlink, w.lowlink); } else if (S.Contains(w)) { v.lowlink = Math.Min(v.lowlink, w.index); } } if (v.lowlink == v.index) { var scc = new List<Vertex>(); Vertex w; do { w = S.Pop(); scc.Add(w); } while (v != w); _stronglyConnectedComponents.Add(scc); } } }
public DTuple Prog(StrategySet rho, Vertex v, Vertex w) { var rho_w = rho[w]; var ret = new DTuple(rho_w.Count); if (v.PriorityEven) { // return the least m >= (up to p(v)) rho // easily constructed by copying values up to p(v) and padding with 0 if (rho_w.IsTop) ret = MTop; else for (int i = 0; i < v.Priority; i++) ret[i] = rho_w[i]; } else { // return the least m > (up to p(v)) rho[w] // constructed by taking the first elem before p(v) that can be incremented, MTop otherwise for (int i = v.Priority; i >= 0; i--) { if (rho_w[i] < MMaxEven[i]) { ret[i] = rho_w[i] + 1; // leave stuff in front same as rho_w for (int j = 0; j < i; j++) ret[j] = rho_w[j]; // and set remainder to 0 for (int j = i + 1; j < d; j++) ret[j] = 0; break; } else if (i == 0) // nothing could be incremented ret = MTop; else // copy this val, try to incr. next ret[i] = rho_w[i]; } } return ret; }
static void tarjan_iter(Vertex u, ref int index) { u.index = index; u.lowlink = index; index++; u.vindex = 0; _tarStack.Push(u); u.caller = null; //Equivalent to the node from which the recursive call would spawn. _onStack[u] = true; Vertex last = u; while (true) { if (last.vindex < last.Adj.Count) { //Equivalent to the check in the for-loop in the recursive version Vertex w = last.Adj[last.vindex]; last.vindex++; //Equivalent to incrementing the iterator in the for-loop in the recursive version if (w.index == -1) { w.caller = last; w.vindex = 0; w.index = index; w.lowlink = index; index++; _tarStack.Push(w); _onStack[w] = true; last = w; } else if (_onStack[w] == true) { last.lowlink = Math.Min(last.lowlink, w.index); } } else { //Equivalent to the nodeSet iterator pointing to end() if (last.lowlink == last.index) { Vertex top = _tarStack.Pop(); var scc = new List<Vertex>() { top }; top.SCC = scc; _onStack[top] = false; int size = 1; while (top.Id != last.Id) { top = _tarStack.Pop(); top.SCC = scc; scc.Add(top); _onStack[top] = false; size++; } _sccs.Add(scc); } Vertex newLast = last.caller; //Go up one recursive call if (newLast != null) { newLast.lowlink = Math.Min(newLast.lowlink, last.lowlink); last = newLast; } else { //We've seen all the nodes break; } } } }
public Vertex GetV(int id) { var v = V[id]; if (v == null) { v = new Vertex(id); V[id] = v; } return v; }
public Edge(Vertex from, Vertex to) { From = from; To = to; }
private void Lift(Vertex v, StrategySet rho) { var ps = v.Adj.Select(w => Prog(rho, v, w)).OrderBy(d => d); rho[v] = v.OwnerEven ? ps.First() : ps.Last(); }