Example #1
0
        public static void Clone <TVertex, TEdge>(
            IVertexAndEdgeListGraph <TVertex, TEdge> g,
            IMutableVertexAndEdgeListGraph <TVertex, TEdge> clone)
            where TVertex : ICloneable
            where TEdge : ICloneableEdge <TVertex>
        {
            GraphContracts.AssumeNotNull(g, "g");
            GraphContracts.AssumeNotNull(clone, "clone");

            var vertexClones = new Dictionary <TVertex, TVertex>();

            foreach (var v in g.Vertices)
            {
                var vc = (TVertex)v.Clone();
                clone.AddVertex(vc);
                vertexClones.Add(v, vc);
            }

            foreach (var edge in g.Edges)
            {
                var ec = (TEdge)edge.Clone(
                    vertexClones[edge.Source],
                    vertexClones[edge.Target]);
                clone.AddEdge(ec);
            }
        }
Example #2
0
        public static void Clone <TVertex, TEdge>(
            IVertexAndEdgeListGraph <TVertex, TEdge> g,
            IMutableVertexAndEdgeListGraph <TVertex, TEdge> clone)
            where TVertex : ICloneable
            where TEdge : ICloneableEdge <TVertex>
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (clone == null)
            {
                throw new ArgumentNullException("clone");
            }

            Dictionary <TVertex, TVertex> vertexClones = new Dictionary <TVertex, TVertex>();

            foreach (TVertex v in g.Vertices)
            {
                TVertex vc = (TVertex)v.Clone();
                clone.AddVertex(vc);
                vertexClones.Add(v, vc);
            }

            foreach (TEdge edge in g.Edges)
            {
                TEdge ec = (TEdge)edge.Clone(
                    vertexClones[edge.Source],
                    vertexClones[edge.Target]);
                clone.AddEdge(ec);
            }
        }
Example #3
0
        private static void MaxBipartiteMatch <TVertex, TEdge>(
            [NotNull] IMutableVertexAndEdgeListGraph <TVertex, TEdge> graph,
            [NotNull, ItemNotNull] TVertex[] vertexSetA,
            [NotNull, ItemNotNull] TVertex[] vertexSetB,
            [NotNull] VertexFactory <TVertex> vertexFactory,
            [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory,
            int expectedMatchSize)
            where TEdge : IEdge <TVertex>
        {
            Assert.IsTrue(graph.VertexCount > 0);

            var maxMatch = new MaximumBipartiteMatchingAlgorithm <TVertex, TEdge>(
                graph,
                vertexSetA,
                vertexSetB,
                vertexFactory,
                edgeFactory);

            DateTime startTime = DateTime.Now;

            maxMatch.Compute();

            TimeSpan computeTime = DateTime.Now - startTime;

            Assert.IsTrue(computeTime < TimeSpan.FromMinutes(5));

            AssertThatMaxMatchEdgesAreValid(vertexSetA, vertexSetB, maxMatch);

            Assert.AreEqual(expectedMatchSize, maxMatch.MatchedEdges.Length);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="YenShortestPathsAlgorithm{TVertex}"/> class.
        /// </summary>
        /// <remarks>
        /// <see cref="double"/> for tag type (edge) which comes from Dijkstra’s algorithm, which is used to get one shortest path.
        /// </remarks>
        /// <param name="graph">Graph to visit.</param>
        /// <param name="source">Source vertex.</param>
        /// <param name="target">Target vertex.</param>
        /// <param name="k">Maximum number of path to search.</param>
        /// <param name="edgeWeights">Optional function that computes the weight for a given edge.</param>
        /// <param name="filter">Optional filter of found paths.</param>
        public YenShortestPathsAlgorithm(
            AdjacencyGraph <TVertex, EquatableTaggedEdge <TVertex, double> > graph,
            TVertex source,
            TVertex target,
            int k,
            Func <EquatableTaggedEdge <TVertex, double>, double> edgeWeights  = null,
            Func <IEnumerable <SortedPath>, IEnumerable <SortedPath> > filter = null)
        {
            if (graph is null)
            {
                throw new ArgumentNullException(nameof(graph));
            }
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (k < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(k), "Value must be positive.");
            }

            _sourceVertex = source;
            _targetVertex = target;
            _k            = k;
            _graph        = graph.Clone();
            _weights      = edgeWeights ?? DefaultGetWeights;
            _filter       = filter ?? DefaultFilter;
        }
Example #5
0
 protected static void TryGetOutEdges_Test(
     [NotNull] IMutableVertexAndEdgeListGraph <int, Edge <int> > graph)
 {
     TryGetOutEdges_Test(
         graph,
         edges => graph.AddVerticesAndEdgeRange(edges));
 }
Example #6
0
 protected static void OutEdge_Test(
     IMutableVertexAndEdgeListGraph <int, Edge <int> > graph)
 {
     OutEdge_Test(
         graph,
         edges => graph.AddVerticesAndEdgeRange(edges));
 }
Example #7
0
        protected static void RemoveOutEdgeIf_Test(
            [NotNull] IMutableVertexAndEdgeListGraph <int, Edge <int> > graph)
        {
            int verticesRemoved = 0;
            int edgesRemoved    = 0;

            // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
            graph.VertexRemoved += v =>
            {
                Assert.IsNotNull(v);
                ++verticesRemoved;
            };
            // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
            graph.EdgeRemoved += e =>
            {
                Assert.IsNotNull(e);
                // ReSharper disable once AccessToModifiedClosure
                ++edgesRemoved;
            };

            Assert.AreEqual(0, graph.RemoveOutEdgeIf(1, _ => true));
            CheckCounters(0);
            AssertEmptyGraph(graph);

            var edge12    = new Edge <int>(1, 2);
            var edge13    = new Edge <int>(1, 3);
            var edge13Bis = new Edge <int>(1, 3);
            var edge14    = new Edge <int>(1, 4);
            var edge24    = new Edge <int>(2, 4);
            var edge31    = new Edge <int>(3, 1);
            var edge33    = new Edge <int>(3, 3);

            graph.AddVerticesAndEdgeRange(new[] { edge12, edge13, edge13Bis, edge14, edge24, edge31, edge33 });

            Assert.AreEqual(3, graph.RemoveOutEdgeIf(1, edge => edge.Target >= 3));
            CheckCounters(3);
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertHasEdges(graph, new[] { edge12, edge24, edge31, edge33 });

            Assert.AreEqual(0, graph.RemoveOutEdgeIf(3, edge => edge.Target > 5));
            CheckCounters(0);
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertHasEdges(graph, new[] { edge12, edge24, edge31, edge33 });

            Assert.AreEqual(2, graph.RemoveOutEdgeIf(3, _ => true));
            CheckCounters(2);
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertHasEdges(graph, new[] { edge12, edge24 });

            #region Local function

            void CheckCounters(int expectedRemovedEdges)
            {
                Assert.AreEqual(0, verticesRemoved);
                Assert.AreEqual(expectedRemovedEdges, edgesRemoved);
                edgesRemoved = 0;
            }

            #endregion
        }
		/// <summary>
		/// Transitive closure constructor
		/// </summary>
		/// <param name="g">
		/// Graph whose transitive closre needs to be 
		/// computed
		/// </param>
		/// <exception cref="ArgumentNullException">
		/// <paramref name="g"/> is a <null/>.
		/// </exception>
		public TransitiveClosureAlgorithm(IVertexListGraph g)
		{
			if (g==null)
				throw new ArgumentNullException("g");
			this.visitedGraph = g;	
			cg = new AdjacencyGraph();
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="ReversedEdgeAugmentorAlgorithm{TVertex,TEdge}"/> class.
 /// </summary>
 /// <param name="visitedGraph">Graph to visit.</param>
 /// <param name="edgeFactory">Edge factory method.</param>
 public ReversedEdgeAugmentorAlgorithm(
     [NotNull] IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
     [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory)
 {
     VisitedGraph = visitedGraph ?? throw new ArgumentNullException(nameof(visitedGraph));
     EdgeFactory  = edgeFactory ?? throw new ArgumentNullException(nameof(edgeFactory));
 }
Example #10
0
        public void Deserialize(
            XmlReader reader,
            IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
            IIdentifiableVertexFactory <TVertex> vertexFactory,
            IIdentifiableEdgeFactory <TVertex, TEdge> edgeFactory)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            if (visitedGraph == null)
            {
                throw new ArgumentNullException("visitedGraph");
            }
            if (vertexFactory == null)
            {
                throw new ArgumentNullException("vertexFactory");
            }
            if (edgeFactory == null)
            {
                throw new ArgumentNullException("edgeFactory");
            }

            ReaderWorker worker = new ReaderWorker(
                this,
                reader,
                visitedGraph,
                vertexFactory,
                edgeFactory);

            worker.Deserialize();
        }
        private void VerifyCounts(IMutableVertexAndEdgeListGraph <string, Edge <string> > g)
        {
            int i = 0;

            foreach (string v in g.Vertices)
            {
                i++;
            }
            Assert.Equal(g.VertexCount, i);

            i = 0;
            foreach (string v in g.Vertices)
            {
                foreach (Edge <string> e in g.OutEdges(v))
                {
                    i++;
                }
            }
            Assert.Equal(g.EdgeCount, i);

            i = 0;
            foreach (Edge <string> e in g.Edges)
            {
                i++;
            }
            Assert.Equal(g.EdgeCount, i);
        }
        private static void RunAugmentationAndCheck(
            [NotNull] IMutableVertexAndEdgeListGraph <string, Edge <string> > graph)
        {
            int vertexCount = graph.VertexCount;
            int edgeCount   = graph.EdgeCount;
            int vertexId    = graph.VertexCount + 1;

            using (var augmentor = new AllVerticesGraphAugmentorAlgorithm <string, Edge <string> >(
                       graph,
                       () => (vertexId++).ToString(),
                       (s, t) => new Edge <string>(s, t)))
            {
                bool added = false;
                augmentor.EdgeAdded += _ => { added = true; };

                augmentor.Compute();
                Assert.IsTrue(added);
                VerifyVertexCount(graph, augmentor, vertexCount);
                VerifySourceConnector(graph, augmentor);
                VerifySinkConnector(graph, augmentor);
            }

            Assert.AreEqual(graph.VertexCount, vertexCount);
            Assert.AreEqual(graph.EdgeCount, edgeCount);
        }
 protected static void ContainsEdge_SourceTarget_Test(
     [NotNull] IMutableVertexAndEdgeListGraph <int, Edge <int> > graph)
 {
     ContainsEdge_SourceTarget_Test(
         graph,
         edge => graph.AddVerticesAndEdge(edge));
 }
        /// <summary>
        /// Computes the Edmonds-Karp maximums flow
        /// for a graph with positive capacities and
        /// flows.
        /// </summary>
        /// <typeparam name="TVertex">The type of the vertex.</typeparam>
        /// <typeparam name="TEdge">The type of the edge.</typeparam>
        /// <param name="visitedGraph">The visited graph.</param>
        /// <param name="edgeCapacities">The edge capacities.</param>
        /// <param name="source">The source.</param>
        /// <param name="sink">The sink.</param>
        /// <param name="flowPredecessors">The flow predecessors.</param>
        /// <param name="edgeFactory">the edge factory</param>
        /// <returns></returns>
        public static double MaximumFlowEdmondsKarp <TVertex, TEdge>(
#if !NET20
            this
#endif
            IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
            Func <TEdge, double> edgeCapacities,
            TVertex source,
            TVertex sink,
            out TryFunc <TVertex, TEdge> flowPredecessors,
            EdgeFactory <TVertex, TEdge> edgeFactory
            )
            where TEdge : IEdge <TVertex>
        {
            Contract.Requires(visitedGraph != null);
            Contract.Requires(edgeCapacities != null);
            Contract.Requires(source != null);
            Contract.Requires(sink != null);
            Contract.Requires(!source.Equals(sink));



            // compute maxflow
            var flow = new EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge>(
                visitedGraph,
                edgeCapacities,
                edgeFactory
                );

            flow.Compute(source, sink);
            flowPredecessors = flow.Predecessors.TryGetValue;
            return(flow.MaxFlow);
        }
        private MaximumBipartiteMatchingAlgorithm <TVertex, TEdge> MaxBipartiteMatch <TVertex, TEdge>(
            IMutableVertexAndEdgeListGraph <TVertex, TEdge> g,
            IEnumerable <TVertex> vertexSetA,
            IEnumerable <TVertex> vertexSetB,
            VertexFactory <TVertex> vertexFactory,
            EdgeFactory <TVertex, TEdge> edgeFactory,
            int expectedMatchSize)
            where TEdge : IEdge <TVertex>
        {
            Assert.True(g.VertexCount > 0);

            var maxMatch = new MaximumBipartiteMatchingAlgorithm <TVertex, TEdge>(g,
                                                                                  vertexSetA, vertexSetB, vertexFactory, edgeFactory);

            DateTime startTime = DateTime.Now;

            maxMatch.Compute();

            TimeSpan computeTime = DateTime.Now - startTime;

            Assert.True(computeTime < TimeSpan.FromMinutes(5));

            AssertThatMaxMatchEdgesAreValid <TVertex, TEdge>(vertexSetA, vertexSetB, maxMatch);

            Assert.True(maxMatch.MatchedEdges.Count == expectedMatchSize);

            return(maxMatch);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="EulerianTrailAlgorithm{TVertex,TEdge}"/> class.
 /// </summary>
 /// <param name="host">Host to use if set, otherwise use this reference.</param>
 /// <param name="visitedGraph">Graph to visit.</param>
 public EulerianTrailAlgorithm(
     IAlgorithmComponent host,
     IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph)
     : base(host, visitedGraph)
 {
     _currentVertex = default(TVertex);
 }
Example #17
0
 public CloneableVertexGraphExplorerAlgorithm(
     IAlgorithmComponent host,
     IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph
     )
     : base(host, visitedGraph)
 {
 }
        private void ComputeTrail <TVertex, TEdge>(
            IMutableVertexAndEdgeListGraph <TVertex, TEdge> g,
            Func <TVertex, TVertex, TEdge> edgeCreator)
            where TEdge : IEdge <TVertex>
        {
            if (g.VertexCount == 0)
            {
                return;
            }

            int oddCount = 0;

            foreach (var v in g.Vertices)
            {
                if (g.OutDegree(v) % 2 == 0)
                {
                    oddCount++;
                }
            }

            int circuitCount = EulerianTrailAlgorithm <TVertex, TEdge> .ComputeEulerianPathCount(g);

            if (circuitCount == 0)
            {
                return;
            }

            var trail = new EulerianTrailAlgorithm <TVertex, TEdge>(g);

            trail.AddTemporaryEdges((s, t) => edgeCreator(s, t));
            trail.Compute();
            var trails = trail.Trails();

            trail.RemoveTemporaryEdges();

            //TestConsole.WriteLine("trails: {0}", trails.Count);
            //int index = 0;
            //foreach (var t in trails)
            //{
            //    TestConsole.WriteLine("trail {0}", index++);
            //    foreach (Edge<string> edge in t)
            //        TestConsole.WriteLine("\t{0}", t);
            //}

            // lets make sure all the edges are in the trail
            var edgeColors = new Dictionary <TEdge, GraphColor>(g.EdgeCount);

            foreach (var edge in g.Edges)
            {
                edgeColors.Add(edge, GraphColor.White);
            }
            foreach (var t in trails)
            {
                foreach (var edge in t)
                {
                    Assert.True(edgeColors.ContainsKey(edge));
                }
            }
        }
Example #19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmondsKarpMaximumFlowAlgorithm{TVertex,TEdge}"/> class.
 /// </summary>
 /// <param name="visitedGraph">Graph to visit.</param>
 /// <param name="capacities">Function that given an edge return the capacity of this edge.</param>
 /// <param name="edgeFactory">Edge factory method.</param>
 /// <param name="reversedEdgeAugmentorAlgorithm">Algorithm that is in of charge of augmenting the graph (creating missing reversed edges).</param>
 public EdmondsKarpMaximumFlowAlgorithm(
     [NotNull] IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
     [NotNull] Func <TEdge, double> capacities,
     [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory,
     [NotNull] ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reversedEdgeAugmentorAlgorithm)
     : this(null, visitedGraph, capacities, edgeFactory, reversedEdgeAugmentorAlgorithm)
 {
 }
Example #20
0
 protected static void OutEdge_Throws_Test(
     IMutableVertexAndEdgeListGraph <int, Edge <int> > graph)
 {
     OutEdge_Throws_Test(
         graph,
         vertex => graph.AddVertex(vertex),
         edge => graph.AddEdge(edge));
 }
Example #21
0
 public void SetUp(IMutableVertexAndEdgeListGraph <string, Edge <string> > g)
 {
     this.augmentor = new AllVerticesGraphAugmentorAlgorithm <string, Edge <string> >(
         g,
         new StringVertexFactory(),
         new EdgeFactory <string>()
         );
 }
 public ReversedEdgeAugmentorAlgorithm(IMutableVertexAndEdgeListGraph visitedGraph)
 {
     if (visitedGraph == null)
     {
         throw new ArgumentNullException("visitedGraph");
     }
     this.visitedGraph = visitedGraph;
 }
 public ReversedEdgeAugmentorAlgorithm(IMutableVertexAndEdgeListGraph visitedGraph)
 {
     if (visitedGraph == null)
     {
         throw new ArgumentNullException("visitedGraph");
     }
     this.visitedGraph = visitedGraph;
 }
 /// <summary>
 /// Construct an eulerian trail builder
 /// </summary>
 /// <param name="g"></param>
 public EulerianTrailAlgorithm(IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph)
     : base(visitedGraph)
 {
     this.circuit          = new List <TEdge>();
     this.temporaryCircuit = new List <TEdge>();
     this.currentVertex    = default(TVertex);
     this.temporaryEdges   = new List <TEdge>();
 }
 public EdmondsKarpMaximumFlowAlgorithm(
     IMutableVertexAndEdgeListGraph <TVertex, TEdge> g,
     Func <TEdge, double> capacities,
     EdgeFactory <TVertex, TEdge> edgeFactory
     )
     : this(null, g, capacities, edgeFactory)
 {
 }
Example #26
0
 public AllVerticesGraphAugmentorAlgorithm(
     IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
     IVertexFactory <TVertex> vertexFactory,
     IEdgeFactory <TVertex, TEdge> edgeFactory
     )
     : this(null, visitedGraph, vertexFactory, edgeFactory)
 {
 }
        public void AddVertexOnly(IMutableVertexAndEdgeListGraph <string, Edge <string> > g, string v)
        {
            int vertexCount = g.VertexCount;

            g.AddVertex(v);
            Assert.Equal(vertexCount + 1, g.VertexCount);
            Assert.True(g.ContainsVertex(v));
            VerifyCounts(g);
        }
Example #28
0
 /// <summary>
 /// Transitive closure constructor
 /// </summary>
 /// <param name="g">
 /// Graph whose transitive closre needs to be
 /// computed
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// <paramref name="g"/> is a <null/>.
 /// </exception>
 public TransitiveClosureAlgorithm(IVertexListGraph g)
 {
     if (g == null)
     {
         throw new ArgumentNullException("g");
     }
     this.visitedGraph = g;
     cg = new AdjacencyGraph();
 }
 public EdmondsKarpMaximumFlowAlgorithm(
     IAlgorithmComponent host,
     IMutableVertexAndEdgeListGraph <TVertex, TEdge> g,
     Func <TEdge, double> capacities,
     EdgeFactory <TVertex, TEdge> edgeFactory
     )
     : base(host, g, capacities, edgeFactory)
 {
 }
Example #30
0
 public MaximumBipartiteMatchingAlgorithm(
     IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph
     )
     : this(visitedGraph,
            FactoryCompiler.GetVertexFactory <TVertex>(),
            FactoryCompiler.GetEdgeFactory <TVertex, TEdge>()
            )
 {
 }
Example #31
0
 public AllVerticesGraphAugmentorAlgorithm(
     IAlgorithmComponent host,
     IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
     IVertexFactory <TVertex> vertexFactory,
     IEdgeFactory <TVertex, TEdge> edgeFactory
     )
     : base(host, visitedGraph, vertexFactory, edgeFactory)
 {
 }
Example #32
0
 public AllVerticesGraphAugmentorAlgorithm(
     IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph
     )
     : this(visitedGraph,
            FactoryCompiler.GetVertexFactory <TVertex>(),
            FactoryCompiler.GetEdgeFactory <TVertex, TEdge>()
            )
 {
 }
        public static void Loop(IMutableVertexAndEdgeListGraph<string,Edge<string>> g)
        {
            string x = "x"; g.AddVertex(x);
            string y = "y"; g.AddVertex(y);
            string z = "z"; g.AddVertex(z);

            g.AddEdge(new Edge<string>(x, y));
            g.AddEdge(new Edge<string>(y, z));
            g.AddEdge(new Edge<string>(z, x));
        }
 public void Create(IMutableVertexAndEdgeListGraph cg)
 {
     if (cg == null)
     {
         throw new ArgumentNullException("cg");
     }
     if (this.components == null)
     {
         this.ComputeComponents();
     }
     this.sccVertexMap = this.BuildSCCVertexMap(this.components);
     VertexCollection vertexs = new VertexCollection();
     IDictionaryEnumerator enumerator = this.sccVertexMap.GetEnumerator();
     while (enumerator.MoveNext())
     {
         IVertex cgVertex = cg.AddVertex();
         this.OnInitCondensationGraphVertex(new CondensationGraphVertexEventArgs(cgVertex, (IVertexCollection) enumerator.Value));
         vertexs.Add(cgVertex);
     }
     for (int i = 0; i < this.sccVertexMap.Keys.Count; i++)
     {
         VertexCollection vertexs2 = new VertexCollection();
         IVertexEnumerator enumerator2 = ((IVertexCollection) this.sccVertexMap[i]).GetEnumerator();
         while (enumerator2.MoveNext())
         {
             IVertex vertex2 = enumerator2.get_Current();
             IEdgeEnumerator enumerator3 = this.VisitedGraph.OutEdges(vertex2).GetEnumerator();
             while (enumerator3.MoveNext())
             {
                 IVertex vertex3 = enumerator3.get_Current().get_Target();
                 int num2 = this.components.get_Item(vertex3);
                 if (i != num2)
                 {
                     IVertex vertex4 = vertexs.get_Item(num2);
                     if (!vertexs2.Contains(vertex4))
                     {
                         vertexs2.Add(vertex4);
                     }
                 }
             }
         }
         IVertex vertex5 = vertexs.get_Item(i);
         VertexCollection.Enumerator enumerator4 = vertexs2.GetEnumerator();
         while (enumerator4.MoveNext())
         {
             IVertex vertex6 = enumerator4.get_Current();
             cg.AddEdge(vertex5, vertex6);
         }
     }
 }
        public static void UnBalancedFlow(IMutableVertexAndEdgeListGraph<string, Edge<string>> g)
        {
            string x = "x"; g.AddVertex(x);
            string y = "y"; g.AddVertex(y);
            string z = "z"; g.AddVertex(z);
            string w = "w"; g.AddVertex(w);

            g.AddEdge(new Edge<string>(x, y));
            g.AddEdge(new Edge<string>(x, z));
            g.AddEdge(new Edge<string>(y, z));
            g.AddEdge(new Edge<string>(x, w));
            g.AddEdge(new Edge<string>(w, y));
            g.AddEdge(new Edge<string>(w, z));
        }
        private void VerifyCounts(IMutableVertexAndEdgeListGraph<string, Edge<string>> g)
        {
            int i = 0;
            foreach (string v in g.Vertices)
                i++;
            Assert.AreEqual(g.VertexCount, i);

            i = 0;
            foreach (string v in g.Vertices)
                foreach (Edge<string> e in g.OutEdges(v))
                    i++;
            Assert.AreEqual(g.EdgeCount, i);

            i = 0;
            foreach (Edge<string> e in g.Edges)
                i++;
            Assert.AreEqual(g.EdgeCount, i);
        }
        public static void Simple(IMutableVertexAndEdgeListGraph<string, Edge<string>> g)
        {
            string x = "x"; g.AddVertex(x);
            string y = "y"; g.AddVertex(y);
            string z = "z"; g.AddVertex(z);
            string w = "w"; g.AddVertex(w);
            string u = "u"; g.AddVertex(u);
            string v = "v"; g.AddVertex(v);

            g.AddEdge(new Edge<string>(u, x));
            g.AddEdge(new Edge<string>(u, v));
            g.AddEdge(new Edge<string>(w, z));
            g.AddEdge(new Edge<string>(w, y));
            g.AddEdge(new Edge<string>(w, u));
            g.AddEdge(new Edge<string>(x, v));
            g.AddEdge(new Edge<string>(v, y));
            g.AddEdge(new Edge<string>(y, x));
            g.AddEdge(new Edge<string>(z, y));
        }
        public static void FileDependency(IMutableVertexAndEdgeListGraph<string, Edge<string>> g)
        {
            // adding files and storing names
            string zig_cpp = "zip.cpp"; g.AddVertex(zig_cpp);
            string boz_h = "boz.h"; g.AddVertex(boz_h);
            string zag_cpp = "zag.cpp"; g.AddVertex(zag_cpp);
            string yow_h = "yow.h"; g.AddVertex(yow_h);
            string dax_h = "dax.h"; g.AddVertex(dax_h);
            string bar_cpp = "bar.cpp"; g.AddVertex(bar_cpp);
            string zow_h = "zow.h"; g.AddVertex(zow_h);
            string foo_cpp = "foo.cpp"; g.AddVertex(foo_cpp);

            string zig_o = "zig.o"; g.AddVertex(zig_o);
            string zag_o = "zago"; g.AddVertex(zag_o);
            string bar_o = "bar.o"; g.AddVertex(bar_o);
            string foo_o = "foo.o"; g.AddVertex(foo_o);
            string libzigzag_a = "libzigzig.a"; g.AddVertex(libzigzag_a);
            string libfoobar_a = "libfoobar.a"; g.AddVertex(libfoobar_a);

            string killerapp = "killerapp.exe"; g.AddVertex(killerapp);

            // adding dependencies
            g.AddEdge(new Edge<string>(dax_h, foo_cpp));
            g.AddEdge(new Edge<string>(dax_h, bar_cpp));
            g.AddEdge(new Edge<string>(dax_h, yow_h));
            g.AddEdge(new Edge<string>(yow_h, bar_cpp));
            g.AddEdge(new Edge<string>(yow_h, zag_cpp));
            g.AddEdge(new Edge<string>(boz_h, bar_cpp));
            g.AddEdge(new Edge<string>(boz_h, zig_cpp));
            g.AddEdge(new Edge<string>(boz_h, zag_cpp));
            g.AddEdge(new Edge<string>(zow_h, foo_cpp));
            g.AddEdge(new Edge<string>(foo_cpp, foo_o));
            g.AddEdge(new Edge<string>(foo_o, libfoobar_a));
            g.AddEdge(new Edge<string>(bar_cpp, bar_o));
            g.AddEdge(new Edge<string>(bar_o, libfoobar_a));
            g.AddEdge(new Edge<string>(libfoobar_a, libzigzag_a));
            g.AddEdge(new Edge<string>(zig_cpp, zig_o));
            g.AddEdge(new Edge<string>(zig_o, libzigzag_a));
            g.AddEdge(new Edge<string>(zag_cpp, zag_o));
            g.AddEdge(new Edge<string>(zag_o, libzigzag_a));
            g.AddEdge(new Edge<string>(libzigzag_a, killerapp));
        }
        public void ComputeTrail(IMutableVertexAndEdgeListGraph<string,Edge<string>> g)
        {
            if (g.VertexCount == 0)
                return;

            GraphConsoleSerializer.DisplayGraph(g);

            int oddCount = 0;
            foreach (string v in g.Vertices)
                if (g.OutDegree(v) % 2 == 0)
                    oddCount++;

            int circuitCount = EulerianTrailAlgorithm<string,Edge<string>>.ComputeEulerianPathCount(g);
            if (circuitCount == 0)
                return;

            EulerianTrailAlgorithm<string, Edge<string>> trail = new EulerianTrailAlgorithm<string, Edge<string>>(g);
            trail.AddTemporaryEdges(new EdgeFactory<string>());
            trail.Compute();
            ICollection<ICollection<Edge<string>>> trails = trail.Trails();
            trail.RemoveTemporaryEdges();

            Console.WriteLine("trails: {0}", trails.Count);
            int index = 0;
            foreach (ICollection<Edge<string>> t in trails)
            {
                Console.WriteLine("trail {0}", index++);
                foreach (Edge<string> edge in t)
                    Console.WriteLine("\t{0}", t);
            }

            // lets make sure all the edges are in the trail
            Dictionary<Edge<string>, GraphColor> edgeColors = new Dictionary<Edge<string>, GraphColor>(g.EdgeCount);
            foreach (Edge<string> edge in g.Edges)
                edgeColors.Add(edge, GraphColor.White);
            foreach (ICollection<Edge<string>> t in trails)
                foreach (Edge<string> edge in t)
                    CollectionAssert.ContainsKey(edgeColors, edge);

        }
		/// <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);
			}
		}
 public static void NoEdges(IMutableVertexAndEdgeListGraph<string, Edge<string>> g)
 {
     string x = "x"; g.AddVertex(x);
     string y = "y"; g.AddVertex(y);
     string z = "z"; g.AddVertex(z);
 }
 public EdgeCollection AddTemporaryEdges(IMutableVertexAndEdgeListGraph g)
 {
     if (g == null)
     {
         throw new ArgumentNullException("g");
     }
     VertexCollection vertexs = QuickGraph.Algorithms.AlgoUtility.OddVertices(g);
     if ((vertexs.Count % 2) != 0)
     {
         throw new Exception("number of odd vertices in not even!");
     }
     EdgeCollection edges = new EdgeCollection();
     while (vertexs.Count > 0)
     {
         IVertex vertex = vertexs.get_Item(0);
         bool flag = false;
         bool flag3 = false;
         IEdgeEnumerator enumerator = g.OutEdges(vertex).GetEnumerator();
         while (enumerator.MoveNext())
         {
             IVertex vertex2 = enumerator.get_Current().get_Target();
             if ((vertex2 != vertex) && vertexs.Contains(vertex2))
             {
                 flag3 = true;
                 bool flag2 = false;
                 IEdgeEnumerator enumerator2 = g.OutEdges(vertex2).GetEnumerator();
                 while (enumerator2.MoveNext())
                 {
                     if (enumerator2.get_Current().get_Target() == vertex)
                     {
                         flag2 = true;
                         break;
                     }
                 }
                 if (!flag2)
                 {
                     IEdge edge3 = g.AddEdge(vertex2, vertex);
                     edges.Add(edge3);
                     vertexs.Remove(vertex);
                     vertexs.Remove(vertex2);
                     flag = true;
                     break;
                 }
             }
         }
         if (!flag3)
         {
             if (vertexs.Count < 2)
             {
                 throw new Exception("Eulerian trail failure");
             }
             IVertex vertex3 = vertexs.get_Item(1);
             IEdge edge4 = g.AddEdge(vertex, vertex3);
             edges.Add(edge4);
             vertexs.Remove(vertex);
             vertexs.Remove(vertex3);
             flag = true;
         }
         if (!flag)
         {
             vertexs.Remove(vertex);
             vertexs.Add(vertex);
         }
     }
     this.temporaryEdges = edges;
     return edges;
 }
 private void GenerateActivityGraph()
 {
     _graph = new AdjacencyGraph<int, Edge<int>>();
 }
 public void Create(IMutableVertexAndEdgeListGraph tc)
 {
     if (tc == null)
     {
         throw new ArgumentNullException("tc");
     }
     CondensationGraphAlgorithm algorithm = new CondensationGraphAlgorithm(this.VisitedGraph);
     algorithm.Create(this.cg);
     ArrayList vertices = new ArrayList(this.cg.get_VerticesCount());
     new TopologicalSortAlgorithm(this.cg, vertices).Compute();
     VertexIntDictionary dictionary = new VertexIntDictionary();
     VertexIntDictionary dictionary2 = new VertexIntDictionary();
     for (int i = 0; i < vertices.Count; i++)
     {
         IVertex vertex = (IVertex) vertices[i];
         dictionary2.Add(vertex, i);
         if (!dictionary.Contains(vertex))
         {
             dictionary.Add(vertex, 0);
         }
     }
     VertexListMatrix chains = new VertexListMatrix();
     int num2 = -1;
     Label_0112:
     foreach (IVertex vertex2 in vertices)
     {
         if (dictionary.get_Item(vertex2) == 0)
         {
             num2 = chains.AddRow();
             IVertex vertex3 = vertex2;
             while (true)
             {
                 chains[num2].Add(vertex3);
                 dictionary.set_Item(vertex3, 1);
                 ArrayList list2 = this.TopoSortAdjVertices(vertex3, this.cg, dictionary2);
                 vertex3 = this.FirstNotInChain(list2, dictionary);
                 if (vertex3 == null)
                 {
                     goto Label_0112;
                 }
             }
         }
     }
     VertexIntDictionary dictionary3 = new VertexIntDictionary();
     VertexIntDictionary dictionary4 = new VertexIntDictionary();
     this.SetChainPositions(chains, dictionary3, dictionary4);
     VertexListMatrix matrix2 = new VertexListMatrix();
     matrix2.CreateObjectMatrix(this.cg.get_VerticesCount(), chains.RowCount, 0x7fffffff);
     if (vertices.Count > 0)
     {
         for (int j = vertices.Count - 1; j > -1; j--)
         {
             IVertex v = (IVertex) vertices[j];
             foreach (IVertex vertex5 in this.TopoSortAdjVertices(v, this.cg, dictionary2))
             {
                 if (dictionary2.get_Item(vertex5) < ((int) matrix2[v.get_ID()][dictionary3.get_Item(vertex5)]))
                 {
                     this.LeftUnion(matrix2[v.get_ID()], matrix2[vertex5.get_ID()]);
                     matrix2[v.get_ID()][dictionary3.get_Item(vertex5)] = dictionary2.get_Item(vertex5);
                 }
             }
         }
     }
     ArrayList list3 = new ArrayList();
     IEdgeEnumerator enumerator = this.cg.get_Edges().GetEnumerator();
     while (enumerator.MoveNext())
     {
         IEdge edge = enumerator.get_Current();
         list3.Add(edge);
     }
     foreach (IEdge edge2 in list3)
     {
         this.cg.RemoveEdge(edge2);
     }
     IVertexEnumerator enumerator5 = this.cg.get_Vertices().GetEnumerator();
     while (enumerator5.MoveNext())
     {
         IVertex vertex6 = enumerator5.get_Current();
         int num4 = vertex6.get_ID();
         for (int k = 0; k < chains.RowCount; k++)
         {
             int num6 = (int) matrix2[num4][k];
             if (num6 < 0x7fffffff)
             {
                 IVertex vertex7 = (IVertex) vertices[num6];
                 for (int m = dictionary4.get_Item(vertex7); m < chains[k].Count; m++)
                 {
                     this.cg.AddEdge(vertex6, (IVertex) chains[k][m]);
                 }
             }
         }
     }
     this.graphTransitiveClosures = new VertexVertexDictionary();
     IVertexEnumerator enumerator6 = this.visitedGraph.get_Vertices().GetEnumerator();
     while (enumerator6.MoveNext())
     {
         IVertex vertex8 = enumerator6.get_Current();
         if (!this.graphTransitiveClosures.Contains(vertex8))
         {
             IVertex vertex9 = tc.AddVertex();
             this.OnInitTransitiveClosureVertex(new TransitiveClosureVertexEventArgs(vertex8, vertex9));
             this.graphTransitiveClosures.Add(vertex8, vertex9);
         }
     }
     IVertexCollection vertexs = null;
     IVertexEnumerator enumerator7 = this.cg.get_Vertices().GetEnumerator();
     while (enumerator7.MoveNext())
     {
         IVertex vertex10 = enumerator7.get_Current();
         vertexs = (IVertexCollection) algorithm.SCCVerticesMap[vertex10.get_ID()];
         if (vertexs.Count > 1)
         {
             IVertexEnumerator enumerator8 = vertexs.GetEnumerator();
             while (enumerator8.MoveNext())
             {
                 IVertex vertex11 = enumerator8.get_Current();
                 IVertexEnumerator enumerator9 = vertexs.GetEnumerator();
                 while (enumerator9.MoveNext())
                 {
                     IVertex vertex12 = enumerator9.get_Current();
                     this.OnExamineEdge(tc.AddEdge(this.graphTransitiveClosures.get_Item(vertex11), this.graphTransitiveClosures.get_Item(vertex12)));
                 }
             }
         }
         IEdgeEnumerator enumerator10 = this.cg.OutEdges(vertex10).GetEnumerator();
         while (enumerator10.MoveNext())
         {
             IVertex vertex13 = enumerator10.get_Current().get_Target();
             IVertexEnumerator enumerator11 = ((IVertexCollection) algorithm.SCCVerticesMap[vertex10.get_ID()]).GetEnumerator();
             while (enumerator11.MoveNext())
             {
                 IVertex vertex14 = enumerator11.get_Current();
                 IVertexEnumerator enumerator12 = ((IVertexCollection) algorithm.SCCVerticesMap[vertex13.get_ID()]).GetEnumerator();
                 while (enumerator12.MoveNext())
                 {
                     IVertex vertex15 = enumerator12.get_Current();
                     this.OnExamineEdge(tc.AddEdge(this.graphTransitiveClosures.get_Item(vertex14), this.graphTransitiveClosures.get_Item(vertex15)));
                 }
             }
         }
     }
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        /// <param name="assg"></param>
        public void Transform(IBidirectionalGraph g, IMutableVertexAndEdgeListGraph assg)
        {
            VertexCollection avs = new VertexCollection();
            // adding vertices
            foreach(IEdge e in g.Edges)
            {
                // xi_-(L) = g(xi_-(0), xi_+(L))
                CharacteristicVertex avm = (CharacteristicVertex)assg.AddVertex();
                avm.IncomingEdge = e;
                avm.Vertex = e.Target;
                avs.Add(avm);

                // xi_+(0) = g(xi_-(0), xi_+(L))
                CharacteristicVertex avp = (CharacteristicVertex)assg.AddVertex();
                avp.IncomingEdge = e;
                avp.Vertex = e.Source;
                avs.Add(avp);
            }

            // adding out edges
            foreach(CharacteristicVertex av in avs)
            {
                foreach(IEdge e in g.OutEdges(av.Vertex))
                {
                    // find target vertex:
                    CharacteristicVertex avtarget = FindTargetVertex(e);
                    // add xi_-
                    CharacteristicEdge aem = (CharacteristicEdge)assg.AddEdge(av,avtarget);
                    aem.Positive = false;
                    aem.Edge = e;
                }
                foreach(IEdge e in g.InEdges(av.Vertex))
                {
                    // find target vertex:
                    CharacteristicVertex avtarget = FindTargetVertex(e);
                    // add xi_-
                    CharacteristicEdge aem = (CharacteristicEdge)assg.AddEdge(av,avtarget);
                    aem.Positive = true;
                    aem.Edge = e;
                }
            }
        }
        public static void RegularLattice(int rows, int columns, IMutableVertexAndEdgeListGraph<string, Edge<string>> g)
        {
            string[,] latice = new string[rows, columns];
            // adding vertices
            for (int i = 0; i < rows; ++i)
            {
                for (int j = 0; j < columns; ++j)
                {
                    latice[i, j] = String.Format("{0},{1}", i.ToString(), j.ToString());
                    g.AddVertex(latice[i, j]);
                }
            }

            // adding edges
            for (int i = 0; i < rows - 1; ++i)
            {
                for (int j = 0; j < columns - 1; ++j)
                {
                    g.AddEdge(new Edge<string>(latice[i, j], latice[i, j + 1]));
                    g.AddEdge(new Edge<string>(latice[i, j + 1], latice[i, j]));

                    g.AddEdge(new Edge<string>(latice[i, j], latice[i + 1, j]));
                    g.AddEdge(new Edge<string>(latice[i + 1, j], latice[i, j]));
                }
            }

            for (int j = 0; j < columns - 1; ++j)
            {
                g.AddEdge(new Edge<string>(latice[rows - 1, j], latice[rows - 1, j + 1]));
                g.AddEdge(new Edge<string>(latice[rows - 1, j + 1], latice[rows - 1, j]));
            }

            for (int i = 0; i < rows - 1; ++i)
            {
                g.AddEdge(new Edge<string>(latice[i, columns - 1], latice[i + 1, columns - 1]));
                g.AddEdge(new Edge<string>(latice[i + 1, columns - 1], latice[i, columns - 1]));
            }
        }
        public static void Fsm(IMutableVertexAndEdgeListGraph<string,NamedEdge<string>> g)
        {
            string s0 = "S0"; g.AddVertex(s0);
            string s1 = "S1"; g.AddVertex(s1);
            string s2 = "S2"; g.AddVertex(s2);
            string s3 = "S3"; g.AddVertex(s3);
            string s4 = "S4"; g.AddVertex(s4);
            string s5 = "S5"; g.AddVertex(s5);

            g.AddEdge(new NamedEdge<string>(s0, s1,"StartCalc"));

            g.AddEdge(new NamedEdge<string>(s1, s0,"StopCalc"));
            g.AddEdge(new NamedEdge<string>(s1, s1,"SelectStandard"));
            g.AddEdge(new NamedEdge<string>(s1, s1,"ClearDisplay"));
            g.AddEdge(new NamedEdge<string>(s1, s2,"SelectScientific"));
            g.AddEdge(new NamedEdge<string>(s1, s3,"EnterDecNumber"));

            g.AddEdge(new NamedEdge<string>(s2, s1,"SelectStandard"));
            g.AddEdge(new NamedEdge<string>(s2, s2,"SelectScientific"));
            g.AddEdge(new NamedEdge<string>(s2, s2,"ClearDisplay"));
            g.AddEdge(new NamedEdge<string>(s2, s4,"EnterDecNumber"));
            g.AddEdge(new NamedEdge<string>(s2, s5,"StopCalc"));

            g.AddEdge(new NamedEdge<string>(s3, s0,"StopCalc"));
            g.AddEdge(new NamedEdge<string>(s3, s1,"ClearDisplay"));
            g.AddEdge(new NamedEdge<string>(s3, s3,"SelectStandard"));
            g.AddEdge(new NamedEdge<string>(s3, s3,"EnterDecNumber"));
            g.AddEdge(new NamedEdge<string>(s3, s4,"SelectScientific"));

            g.AddEdge(new NamedEdge<string>(s4, s2,"ClearDisplay"));
            g.AddEdge(new NamedEdge<string>(s4, s3,"SelectStandard"));
            g.AddEdge(new NamedEdge<string>(s4, s4,"SelectScientific"));
            g.AddEdge(new NamedEdge<string>(s4, s4,"EnterDecNumber"));
            g.AddEdge(new NamedEdge<string>(s4, s5,"StopCalc"));

            g.AddEdge(new NamedEdge<string>(s5, s2, "StartCalc"));
        }
        /// <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]));
                    }
                }
            }
        }
		/// <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;			
		}