/// <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>
 /// 
 /// </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>
		/// 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 DagShortestPathAlgorithm(IVertexListGraph g, EdgeDoubleDictionary weights)
 {
     if (g == null)
     {
         throw new ArgumentNullException("g");
     }
     if (weights == null)
     {
         throw new ArgumentNullException("Weights");
     }
     this.m_VisitedGraph = g;
     this.m_Colors = new VertexColorDictionary();
     this.m_Distances = new VertexDoubleDictionary();
     this.m_Predecessors = new VertexVertexDictionary();
     this.m_Weights = weights;
 }
示例#5
0
		/// <summary>
		/// Makes a copy of the source graph to the clone graph.
		/// </summary>
		/// <param name="source">source graph</param>
		/// <param name="target">clone graph</param>
		public void Clone(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.Source], vertexMap[e.Target]);
				// cone properties
				OnCloneEdge(e,ec);
			}
		}
示例#6
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);
		}
        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);
        }
        /// <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>
        /// 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 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)));
                 }
             }
         }
     }
 }
		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);
        }
 //[SetUp]
 public void Init()
 {
     m_Parents = new VertexVertexDictionary();
     m_DiscoverTimes = new VertexIntDictionary();
     m_FinishTimes = new VertexIntDictionary();
     m_Time = 0;
 }
		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);
                }
            }
        }
 private void ConvertPreflowToFlow()
 {
     IVertex vertex3;
     IVertex vertex4 = null;
     IVertex vertex5 = null;
     VertexVertexDictionary dictionary = new VertexVertexDictionary();
     VertexVertexDictionary dictionary2 = new VertexVertexDictionary();
     IVertexEnumerator enumerator3 = this.VisitedGraph.get_Vertices().GetEnumerator();
     while (enumerator3.MoveNext())
     {
         IVertex vertex6 = enumerator3.get_Current();
         IEdgeEnumerator enumerator4 = this.VisitedGraph.OutEdges(vertex6).GetEnumerator();
         while (enumerator4.MoveNext())
         {
             IEdge edge = enumerator4.get_Current();
             if (edge.get_Target() == vertex6)
             {
                 base.ResidualCapacities.set_Item(edge, base.Capacities.get_Item(edge));
             }
         }
         base.Colors.set_Item(vertex6, 0);
         dictionary.set_Item(vertex6, vertex6);
         this.current.set_Item(vertex6, 0);
     }
     IVertexEnumerator enumerator = this.VisitedGraph.get_Vertices().GetEnumerator();
     while (enumerator.MoveNext())
     {
         vertex3 = enumerator.get_Current();
         if (((base.Colors.get_Item(vertex3) != null) || (this.excessFlow.get_Item(vertex3) <= 0.0)) || ((vertex3 == this.src) || (vertex3 == this.sink)))
         {
             continue;
         }
         IVertex vertex = vertex3;
         base.Colors.set_Item(vertex, 2);
     Label_0392:
         do
         {
             while (this.current.get_Item(vertex3) < this.VisitedGraph.OutDegree(vertex3))
             {
                 VertexIntDictionary dictionary6;
                 IVertex vertex9;
                 IEdge a = this.VisitedGraph.OutEdges(vertex3).get_Item(this.current.get_Item(vertex3));
                 if ((base.Capacities.get_Item(a) == 0.0) && this.IsResidualEdge(a))
                 {
                     IVertex vertex7 = a.get_Target();
                     if (base.Colors.get_Item(vertex7) == null)
                     {
                         base.Colors.set_Item(vertex7, 2);
                         dictionary.set_Item(vertex7, vertex3);
                         vertex3 = vertex7;
                         break;
                     }
                     if (base.Colors.get_Item(vertex7) == 2)
                     {
                         double num = base.ResidualCapacities.get_Item(a);
                         while (true)
                         {
                             IEdge edge3 = this.VisitedGraph.OutEdges(vertex7).get_Item(this.current.get_Item(vertex7));
                             num = Math.Min(num, base.ResidualCapacities.get_Item(edge3));
                             if (vertex7 == vertex3)
                             {
                                 break;
                             }
                             vertex7 = edge3.get_Target();
                         }
                         vertex7 = vertex3;
                         do
                         {
                             EdgeDoubleDictionary dictionary3;
                             IEdge edge4;
                             EdgeDoubleDictionary dictionary4;
                             IEdge edge5;
                             a = this.VisitedGraph.OutEdges(vertex7).get_Item(this.current.get_Item(vertex7));
                             (dictionary3 = base.ResidualCapacities).set_Item(edge4 = a, dictionary3.get_Item(edge4) - num);
                             (dictionary4 = base.ResidualCapacities).set_Item(edge5 = base.ReversedEdges.get_Item(a), dictionary4.get_Item(edge5) + num);
                             vertex7 = a.get_Target();
                         }
                         while (vertex7 != vertex3);
                         IVertex vertex2 = vertex3;
                         for (vertex7 = this.VisitedGraph.OutEdges(vertex3).get_Item(this.current.get_Item(vertex3)).get_Target(); vertex7 != vertex3; vertex7 = a.get_Target())
                         {
                             a = this.VisitedGraph.OutEdges(vertex7).get_Item(this.current.get_Item(vertex7));
                             if ((base.Colors.get_Item(vertex7) == null) || this.IsSaturated(a))
                             {
                                 base.Colors.set_Item(this.VisitedGraph.OutEdges(vertex7).get_Item(this.current.get_Item(vertex7)).get_Target(), 0);
                                 if (base.Colors.get_Item(vertex7) != null)
                                 {
                                     vertex2 = vertex7;
                                 }
                             }
                         }
                         if (vertex2 != vertex3)
                         {
                             VertexIntDictionary dictionary5;
                             IVertex vertex8;
                             vertex3 = vertex2;
                             (dictionary5 = this.current).set_Item(vertex8 = vertex3, dictionary5.get_Item(vertex8) + 1);
                             break;
                         }
                     }
                 }
                 (dictionary6 = this.current).set_Item(vertex9 = vertex3, dictionary6.get_Item(vertex9) + 1);
             }
         }
         while (this.current.get_Item(vertex3) != this.VisitedGraph.OutDegree(vertex3));
         base.Colors.set_Item(vertex3, 1);
         if (vertex3 != this.src)
         {
             if (vertex4 == null)
             {
                 vertex4 = vertex3;
                 vertex5 = vertex3;
             }
             else
             {
                 dictionary2.set_Item(vertex3, vertex5);
                 vertex5 = vertex3;
             }
         }
         if (vertex3 != vertex)
         {
             VertexIntDictionary dictionary7;
             IVertex vertex10;
             vertex3 = dictionary.get_Item(vertex3);
             (dictionary7 = this.current).set_Item(vertex10 = vertex3, dictionary7.get_Item(vertex10) + 1);
             goto Label_0392;
         }
     }
     if (vertex4 != null)
     {
         IEdgeEnumerator enumerator2;
         for (vertex3 = vertex5; vertex3 != vertex4; vertex3 = dictionary2.get_Item(vertex3))
         {
             enumerator2 = this.VisitedGraph.OutEdges(vertex3).GetEnumerator();
             while ((this.excessFlow.get_Item(vertex3) > 0.0) && enumerator2.MoveNext())
             {
                 if ((base.Capacities.get_Item(enumerator2.get_Current()) == 0.0) && this.IsResidualEdge(enumerator2.get_Current()))
                 {
                     this.PushFlow(enumerator2.get_Current());
                 }
             }
         }
         vertex3 = vertex4;
         enumerator2 = this.VisitedGraph.OutEdges(vertex3).GetEnumerator();
         while ((this.excessFlow.get_Item(vertex3) > 0.0) && enumerator2.MoveNext())
         {
             if ((base.Capacities.get_Item(enumerator2.get_Current()) == 0.0) && this.IsResidualEdge(enumerator2.get_Current()))
             {
                 this.PushFlow(enumerator2.get_Current());
             }
         }
     }
 }