示例#1
0
        /// <summary>
        /// Compute the condensation graph and store it in the supplied graph 'cg'
        /// </summary>
        /// <param name="cg">
        /// Instance of mutable graph in which the condensation graph
        /// transformation is stored
        /// </param>
        public void Create(IMutableVertexAndEdgeListGraph cg)
        {
            if (cg == null)
            {
                throw new ArgumentNullException("cg");
            }

            if (components == null)
            {
                ComputeComponents();
            }

            //  components list contains collection of
            // input graph Vertex for each SCC Vertex_ID
            // (i.e Vector< Vector<Vertex> > )
            //	Key = SCC Vertex ID
            sccVertexMap = BuildSCCVertexMap(components);

            //	Lsit of SCC vertices
            VertexCollection      toCgVertices = new VertexCollection();
            IDictionaryEnumerator it           = sccVertexMap.GetEnumerator();

            while (it.MoveNext())
            //	as scc_vertex_map is a sorted list, order of SCC IDs will match CG vertices
            {
                IVertex curr = cg.AddVertex();
                OnInitCondensationGraphVertex(new CondensationGraphVertexEventArgs(curr, (IVertexCollection)it.Value));
                toCgVertices.Add(curr);
            }

            for (int srcSccId = 0; srcSccId < sccVertexMap.Keys.Count; srcSccId++)
            {
                VertexCollection adj = new VertexCollection();
                foreach (IVertex u in (IVertexCollection)sccVertexMap[srcSccId])
                {
                    foreach (IEdge e in VisitedGraph.OutEdges(u))
                    {
                        IVertex v           = e.Target;
                        int     targetSccId = components[v];
                        if (srcSccId != targetSccId)
                        {
                            // Avoid loops in the condensation graph
                            IVertex sccV = toCgVertices[targetSccId];
                            if (!adj.Contains(sccV))                                            // Avoid parallel edges
                            {
                                adj.Add(sccV);
                            }
                        }
                    }
                }
                IVertex s = toCgVertices[srcSccId];
                foreach (IVertex t in adj)
                {
                    cg.AddEdge(s, t);
                }
            }
        }
        /// <summary>
        /// Adds temporary edges to the graph to make all vertex even.
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public EdgeCollection AddTemporaryEdges(IMutableVertexAndEdgeListGraph g)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }

            // first gather odd edges.
            VertexCollection oddVertices = AlgoUtility.OddVertices(g);

            // check that there are an even number of them
            if (oddVertices.Count % 2 != 0)
            {
                throw new Exception("number of odd vertices in not even!");
            }

            // add temporary edges to create even edges:
            EdgeCollection ec = new EdgeCollection();

            bool found, foundbe, foundadjacent;

            while (oddVertices.Count > 0)
            {
                IVertex u = oddVertices[0];
                // find adjacent odd vertex.
                found         = false;
                foundadjacent = false;
                foreach (IEdge e in g.OutEdges(u))
                {
                    IVertex v = e.Target;
                    if (v != u && oddVertices.Contains(v))
                    {
                        foundadjacent = true;
                        // check that v does not have an out-edge towards u
                        foundbe = false;
                        foreach (IEdge be in g.OutEdges(v))
                        {
                            if (be.Target == u)
                            {
                                foundbe = true;
                                break;
                            }
                        }
                        if (foundbe)
                        {
                            continue;
                        }
                        // add temporary edge
                        IEdge tempEdge = g.AddEdge(v, u);
                        // add to collection
                        ec.Add(tempEdge);
                        // remove u,v from oddVertices
                        oddVertices.Remove(u);
                        oddVertices.Remove(v);
                        // set u to null
                        found = true;
                        break;
                    }
                }

                if (!foundadjacent)
                {
                    // pick another vertex
                    if (oddVertices.Count < 2)
                    {
                        throw new Exception("Eulerian trail failure");
                    }
                    IVertex v        = oddVertices[1];
                    IEdge   tempEdge = g.AddEdge(u, v);
                    // add to collection
                    ec.Add(tempEdge);
                    // remove u,v from oddVertices
                    oddVertices.Remove(u);
                    oddVertices.Remove(v);
                    // set u to null
                    found = true;
                }

                if (!found)
                {
                    oddVertices.Remove(u);
                    oddVertices.Add(u);
                }
            }

            temporaryEdges = ec;

            return(ec);
        }