public void Init() { m_Parents = new VertexVertexDictionary(); m_DiscoverTimes = new VertexIntDictionary(); m_FinishTimes = new VertexIntDictionary(); m_Time = 0; }
/// <summary> /// /// </summary> /// <param name="g"></param> public StrongComponentsAlgorithm(IVertexListGraph g) { if (g == null) { throw new ArgumentNullException("g"); } m_VisitedGraph = g; m_Components = new VertexIntDictionary(); m_Roots = new VertexVertexDictionary(); m_DiscoverTimes = new VertexIntDictionary(); m_Stack = new Stack(); m_Count = 0; m_DfsTime = 0; }
/// <summary> /// Construct a strong component algorithm /// </summary> /// <param name="g">graph to apply algorithm on</param> /// <exception cref="ArgumentNullException">graph is null</exception> public StrongComponentsAlgorithm(IVertexListGraph g) { if (g == null) { throw new ArgumentNullException("g"); } this.visitedGraph = g; this.components = new VertexIntDictionary(); this.roots = new VertexVertexDictionary(); this.discoverTimes = new VertexIntDictionary(); this.stack = new Stack(); this.count = 0; this.dfsTime = 0; }
/// <summary> /// Builds a new Bellman Ford searcher. /// </summary> /// <param name="g">The graph</param> /// <param name="weights">Edge weights</param> /// <exception cref="ArgumentNullException">Any argument is null</exception> /// <remarks>This algorithm uses the <seealso cref="BreadthFirstSearchAlgorithm"/>.</remarks> public BellmanFordShortestPathAlgorithm( IVertexAndEdgeListGraph g, EdgeDoubleDictionary weights ) { if (weights == null) { throw new ArgumentNullException("Weights"); } m_VisitedGraph = g; m_Colors = new VertexColorDictionary(); m_Weights = weights; m_Distances = new VertexDoubleDictionary(); m_Predecessors = new VertexVertexDictionary(); }
public void Init() { parents = new VertexVertexDictionary(); discoverTimes = new VertexIntDictionary(); finishTimes = new VertexIntDictionary(); time = 0; g = new BidirectionalGraph(true); dfs = new UndirectedDepthFirstSearchAlgorithm(g); dfs.StartVertex += new VertexEventHandler(this.StartVertex); dfs.DiscoverVertex += new VertexEventHandler(this.DiscoverVertex); dfs.ExamineEdge += new EdgeEventHandler(this.ExamineEdge); dfs.TreeEdge += new EdgeEventHandler(this.TreeEdge); dfs.BackEdge += new EdgeEventHandler(this.BackEdge); dfs.FinishVertex += new VertexEventHandler(this.FinishVertex); }
public void Init() { parents = new VertexVertexDictionary(); discoverTimes = new VertexIntDictionary(); finishTimes = new VertexIntDictionary(); time = 0; g = new AdjacencyGraph(true); dfs = new DepthFirstSearchAlgorithm(g); dfs.StartVertex += new VertexEventHandler(this.StartVertex); dfs.DiscoverVertex += new VertexEventHandler(this.DiscoverVertex); dfs.ExamineEdge += new EdgeEventHandler(this.ExamineEdge); dfs.TreeEdge += new EdgeEventHandler(this.TreeEdge); dfs.BackEdge += new EdgeEventHandler(this.BackEdge); dfs.ForwardOrCrossEdge += new EdgeEventHandler(this.FowardOrCrossEdge); dfs.FinishVertex += new VertexEventHandler(this.FinishVertex); }
/// <summary> /// Checks if the child vertex is a child of the parent vertex /// using the predecessor map. /// </summary> /// <param name="parent"></param> /// <param name="child"></param> /// <param name="predecessors"></param> /// <returns></returns> public static bool IsChild( IVertex parent, IVertex child, VertexVertexDictionary predecessors ) { Object o = predecessors[child]; if (o == null || o == child) // child is the root of the tree { return(false); } else if (o == parent) { return(true); } else { return(IsChild(parent, (IVertex)o, predecessors)); } }
/// <summary> /// Builds a new Dijsktra searcher. /// </summary> /// <param name="g">The graph</param> /// <param name="weights">Edge weights</param> /// <exception cref="ArgumentNullException">Any argument is null</exception> /// <remarks>This algorithm uses the <seealso cref="BreadthFirstSearchAlgorithm"/>.</remarks> public DijkstraShortestPathAlgorithm( IVertexListGraph g, EdgeDoubleDictionary weights ) { if (g == null) { throw new ArgumentNullException("g"); } if (weights == null) { throw new ArgumentNullException("Weights"); } m_VisitedGraph = g; m_Colors = new VertexColorDictionary(); m_Distances = new VertexDoubleDictionary(); m_Predecessors = new VertexVertexDictionary(); m_Weights = weights; m_VertexQueue = null; }
/// <summary> /// Clones the <paramref name="source"/> to <paramref name="target"/> and /// reverses the edges. /// </summary> /// <remarks> /// <para> /// Use this class to create clone of different graphs with possible different /// provider types. /// </para> /// <para> /// The <see cref="CloneVertex"/> and <see cref="CloneEdge"/> events can be /// used to copy the custom properties /// attached to each vertex and edge. /// </para> /// </remarks> public void ReversedClone(IVertexAndEdgeListGraph source, IEdgeMutableGraph target) { VertexVertexDictionary vertexMap = new VertexVertexDictionary(); // copy vertices foreach (IVertex v in source.Vertices) { IVertex vc = target.AddVertex(); // clone properties OnCloneVertex(v, vc); // store in table vertexMap[v] = vc; } // copy edges foreach (IEdge e in source.Edges) { IEdge ec = target.AddEdge(vertexMap[e.Target], vertexMap[e.Source]); // cone properties OnCloneEdge(e, ec); } }
/// <summary> /// Compute the transitive closure and store it in the supplied graph 'tc' /// </summary> /// <param name="tc"> /// Mutable Graph instance to store the transitive closure /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="tc"/> is a <null/>. /// </exception> public void Create(IMutableVertexAndEdgeListGraph tc) { if (tc == null) { throw new ArgumentNullException("tc"); } CondensationGraphAlgorithm cgalgo = new CondensationGraphAlgorithm(VisitedGraph); cgalgo.Create(cg); ArrayList topo_order = new ArrayList(cg.VerticesCount); TopologicalSortAlgorithm topo = new TopologicalSortAlgorithm(cg, topo_order); topo.Compute(); VertexIntDictionary in_a_chain = new VertexIntDictionary(); VertexIntDictionary topo_number = new VertexIntDictionary(); for (int order = 0; order < topo_order.Count; order++) { IVertex v = (IVertex)topo_order[order]; topo_number.Add(v, order); if (!in_a_chain.Contains(v)) // Initially no vertex is present in a chain { in_a_chain.Add(v, 0); } } VertexListMatrix chains = new VertexListMatrix(); int position = -1; foreach (IVertex v in topo_order) { if (in_a_chain[v] == 0) { // Start a new chain position = chains.AddRow(); IVertex next = v; for (;;) { chains[position].Add(next); in_a_chain[next] = 1; // Get adjacent vertices ordered by topological number // Extend the chain by choosing the adj vertex with lowest topo# ArrayList adj = TopoSortAdjVertices(next, cg, topo_number); if ((next = FirstNotInChain(adj, in_a_chain)) == null) { break; } } } } VertexIntDictionary chain_number = new VertexIntDictionary(); VertexIntDictionary pos_in_chain = new VertexIntDictionary(); // Record chain positions of vertices SetChainPositions(chains, chain_number, pos_in_chain); VertexListMatrix successors = new VertexListMatrix(); successors.CreateObjectMatrix(cg.VerticesCount, chains.RowCount, int.MaxValue); if (topo_order.Count > 0) { for (int rtopo = topo_order.Count - 1; rtopo > -1; rtopo--) { IVertex u = (IVertex)topo_order[rtopo]; foreach (IVertex v in TopoSortAdjVertices(u, cg, topo_number)) { if (topo_number[v] < (int)successors[u.ID][chain_number[v]]) { // {succ(u)} = {succ(u)} U {succ(v)} LeftUnion(successors[u.ID], successors[v.ID]); // {succ(u)} = {succ(u)} U {v} successors[u.ID][chain_number[v]] = topo_number[v]; } } } } // Create transitive closure of condensation graph // Remove existing edges in CG & rebuild edges for TC from // successor set (to avoid duplicating parallel edges) ArrayList edges = new ArrayList(); foreach (IEdge e in cg.Edges) { edges.Add(e); } foreach (IEdge e in edges) { cg.RemoveEdge(e); } foreach (IVertex u in cg.Vertices) { int i = u.ID; for (int j = 0; j < chains.RowCount; j++) { int tnumber = (int)successors[i][j]; if (tnumber < int.MaxValue) { IVertex v = (IVertex)topo_order[tnumber]; for (int k = pos_in_chain[v]; k < chains[j].Count; k++) { cg.AddEdge(u, (IVertex)chains[j][k]); } } } } // Maps a vertex in input graph to it's transitive closure graph graphTransitiveClosures = new VertexVertexDictionary(); // Add vertices to transitive closure graph foreach (IVertex v in visitedGraph.Vertices) { if (!graphTransitiveClosures.Contains(v)) { IVertex vTransform = tc.AddVertex(); OnInitTransitiveClosureVertex( new TransitiveClosureVertexEventArgs( v, vTransform) ); // Fire the TC Vertex Event graphTransitiveClosures.Add(v, vTransform); } } //Add edges connecting vertices within SCC & adjacent // SCC (strongly connected component) IVertexCollection scc_vertices = null; foreach (IVertex s_tccg in cg.Vertices) { scc_vertices = (IVertexCollection)cgalgo.SCCVerticesMap[s_tccg.ID]; if (scc_vertices.Count > 1) { foreach (IVertex u in scc_vertices) { foreach (IVertex v in scc_vertices) { OnExamineEdge(tc.AddEdge(graphTransitiveClosures[u], graphTransitiveClosures[v])); } } } foreach (IEdge adj_edge in cg.OutEdges(s_tccg)) { IVertex t_tccg = adj_edge.Target; foreach (IVertex s in (IVertexCollection)cgalgo.SCCVerticesMap[s_tccg.ID]) { foreach (IVertex t in (IVertexCollection)cgalgo.SCCVerticesMap[t_tccg.ID]) { OnExamineEdge(tc.AddEdge(graphTransitiveClosures[s], graphTransitiveClosures[t])); } } } } }
public void Init() { m_Parents = new VertexVertexDictionary(); m_Distances = new VertexIntDictionary(); }
//======================================================================= // remove excess flow, the "second phase" // This does a DFS on the reverse flow graph of nodes with excess flow. // If a cycle is found, cancel it. Unfortunately it seems that we can't // easily take advantage of DepthFirstSearchAlgorithm // Return the nodes with excess flow in topological order. // // Unlike the prefl_to_flow() implementation, we use // "color" instead of "distance" for the DFS labels // "parent" instead of nl_prev for the DFS tree // "topo_next" instead of nl_next for the topological ordering private void ConvertPreflowToFlow() { IVertex r, restart, u; IVertex bos = null, tos = null; VertexVertexDictionary parents = new VertexVertexDictionary(); VertexVertexDictionary topoNext = new VertexVertexDictionary(); foreach (IVertex v in VisitedGraph.Vertices) { //Handle self-loops foreach (IEdge a in VisitedGraph.OutEdges(v)) { if (a.Target == v) { ResidualCapacities[a] = Capacities[a]; } } //Initialize Colors[v] = GraphColor.White; parents[v] = v; current[v] = 0; } // eliminate flow cycles and topologically order the vertices IVertexEnumerator vertices = VisitedGraph.Vertices.GetEnumerator(); while (vertices.MoveNext()) { u = vertices.Current; if (Colors[u] == GraphColor.White && excessFlow[u] > 0 && u != src && u != sink) { r = u; Colors[r] = GraphColor.Gray; while (true) { for (; current[u] < VisitedGraph.OutDegree(u); ++current[u]) { IEdge a = VisitedGraph.OutEdges(u)[current[u]]; if (Capacities[a] == 0 && IsResidualEdge(a)) { IVertex v = a.Target; if (Colors[v] == GraphColor.White) { Colors[v] = GraphColor.Gray; parents[v] = u; u = v; break; } else if (Colors[v] == GraphColor.Gray) { //find minimum flow on the cycle double delta = ResidualCapacities[a]; while (true) { IEdge e = VisitedGraph.OutEdges(v)[current[v]]; delta = Math.Min(delta, ResidualCapacities[e]); if (v == u) { break; } else { v = e.Target; } } //remove delta flow units v = u; while (true) { a = VisitedGraph.OutEdges(v)[current[v]]; ResidualCapacities[a] -= delta; ResidualCapacities[ReversedEdges[a]] += delta; v = a.Target; if (v == u) { break; } } // back-out of DFS to the first saturated edge restart = u; for (v = VisitedGraph.OutEdges(u)[current[u]].Target; v != u; v = a.Target) { a = VisitedGraph.OutEdges(v)[current[v]]; if (Colors[v] == GraphColor.White || IsSaturated(a)) { Colors[VisitedGraph.OutEdges(v)[current[v]].Target] = GraphColor.White; if (Colors[v] != GraphColor.White) { restart = v; } } } if (restart != u) { u = restart; ++current[u]; break; } } } } if (current[u] == VisitedGraph.OutDegree(u)) { // scan of i is complete Colors[u] = GraphColor.Black; if (u != src) { if (bos == null) { bos = u; tos = u; } else { topoNext[u] = tos; tos = u; } } if (u != r) { u = parents[u]; ++current[u]; } else { break; } } } } } // return excess flows // note that the sink is not on the stack if (bos != null) { IEdgeEnumerator ai; for (u = tos; u != bos; u = topoNext[u]) { ai = VisitedGraph.OutEdges(u).GetEnumerator(); while (excessFlow[u] > 0 && ai.MoveNext()) { if (Capacities[ai.Current] == 0 && IsResidualEdge(ai.Current)) { PushFlow(ai.Current); } } } // do the bottom u = bos; ai = VisitedGraph.OutEdges(u).GetEnumerator(); while (excessFlow[u] > 0 && ai.MoveNext()) { if (Capacities[ai.Current] == 0 && IsResidualEdge(ai.Current)) { PushFlow(ai.Current); } } } }