public void Init()
 {
     m_Parents       = new VertexVertexDictionary();
     m_DiscoverTimes = new VertexIntDictionary();
     m_FinishTimes   = new VertexIntDictionary();
     m_Time          = 0;
 }
Пример #2
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;
 }
Пример #3
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);
        }
Пример #7
0
        /// <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));
            }
        }
Пример #8
0
        /// <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;
        }
Пример #9
0
        /// <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);
            }
        }
Пример #10
0
        /// <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);
                    }
                }
            }
        }