public override double Compute(IVertex src, IVertex sink)
 {
     if (src == null)
     {
         throw new ArgumentNullException("src");
     }
     if (sink == null)
     {
         throw new ArgumentNullException("sink");
     }
     IVertexEnumerator enumerator = base.VisitedGraph.get_Vertices().GetEnumerator();
     while (enumerator.MoveNext())
     {
         IVertex vertex = enumerator.get_Current();
         IEdgeEnumerator enumerator2 = base.VisitedGraph.OutEdges(vertex).GetEnumerator();
         while (enumerator2.MoveNext())
         {
             IEdge edge = enumerator2.get_Current();
             base.ResidualCapacities.set_Item(edge, base.Capacities.get_Item(edge));
         }
     }
     base.Colors.set_Item(sink, 2);
     while (base.Colors.get_Item(sink) != null)
     {
         PredecessorRecorderVisitor vis = new PredecessorRecorderVisitor(base.Predecessors);
         VertexBuffer q = new VertexBuffer();
         BreadthFirstSearchAlgorithm algorithm = new BreadthFirstSearchAlgorithm(this.ResidualGraph, q, base.Colors);
         algorithm.RegisterPredecessorRecorderHandlers(vis);
         algorithm.Compute(src);
         if (base.Colors.get_Item(sink) != null)
         {
             this.Augment(src, sink);
         }
     }
     double num = 0.0;
     IEdgeEnumerator enumerator3 = base.VisitedGraph.OutEdges(src).GetEnumerator();
     while (enumerator3.MoveNext())
     {
         IEdge edge2 = enumerator3.get_Current();
         num += base.Capacities.get_Item(edge2) - base.ResidualCapacities.get_Item(edge2);
     }
     return num;
 }
        /// <summary>
        /// Computes the maximum flow between <paramref name="src"/> and
        /// <paramref name="sink"/>
        /// </summary>
        /// <param name="src"></param>
        /// <param name="sink"></param>
        /// <returns></returns>
        public override double Compute(IVertex src, IVertex sink)
        {
            if (src==null)
                throw new ArgumentNullException("src");
            if (sink==null)
                throw new ArgumentNullException("sink");

            foreach(IVertex u in VisitedGraph.Vertices)
            {
                foreach(IEdge e in VisitedGraph.OutEdges(u))
                {
                    ResidualCapacities[e] = Capacities[e];
                }
            }

            Colors[sink] = GraphColor.Gray;
            while (Colors[sink] != GraphColor.White)
            {
                PredecessorRecorderVisitor vis = new PredecessorRecorderVisitor(
                    Predecessors
                    );
                VertexBuffer Q = new VertexBuffer();
                BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm(
                    ResidualGraph,
                    Q,
                    Colors
                    );
                bfs.RegisterPredecessorRecorderHandlers(vis);
                bfs.Compute(src);

                if (Colors[sink] != GraphColor.White)
                    Augment(src, sink);
            } // while

            double flow=0;
            foreach(IEdge e in VisitedGraph.OutEdges(src))
                flow += (Capacities[e] - ResidualCapacities[e]);

            return flow;
        }
Esempio n. 3
0
		/// <summary>
		/// Computes a set of eulerian trail, starting at <paramref name="s"/>
		/// that spans the entire graph.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This method computes a set of eulerian trail starting at <paramref name="s"/>
		/// that spans the entire graph.The algorithm outline is as follows:
		/// </para>
		/// <para>
		/// The algorithms iterates throught the Eulerian circuit of the augmented
		/// graph (the augmented graph is the graph with additional edges to make
		/// the number of odd vertices even).
		/// </para>
		/// <para>
		/// If the current edge is not temporary, it is added to the current trail.
		/// </para>
		/// <para>
		/// If the current edge is temporary, the current trail is finished and
		/// added to the trail collection. The shortest path between the 
		/// start vertex <paramref name="s"/> and the target vertex of the
		/// temporary edge is then used to start the new trail. This shortest
		/// path is computed using the <see cref="BreadthFirstSearchAlgorithm"/>.
		/// </para>
		/// </remarks>
		/// <param name="s">start vertex</param>
		/// <returns>eulerian trail set, all starting at s</returns>
		/// <exception cref="ArgumentNullException">s is a null reference.</exception>
		/// <exception cref="Exception">Eulerian trail not computed yet.</exception>
		public EdgeCollectionCollection Trails(IVertex s)
		{
			if (s==null)
				throw new ArgumentNullException("s");
			if (this.Circuit.Count==0)
				throw new Exception("Circuit is empty");

			// find the first edge in the circuit.
			int i=0;
			for(i=0;i<this.Circuit.Count;++i)
			{
				IEdge e = this.Circuit[i];
				if (TemporaryEdges.Contains(e))
					continue;
				if (e.Source == s)
					break;
			}
			if (i==this.Circuit.Count)
				throw new Exception("Did not find vertex in eulerian trail?");

			// create collections
			EdgeCollectionCollection trails = new EdgeCollectionCollection();
			EdgeCollection trail = new EdgeCollection();
			BreadthFirstSearchAlgorithm bfs =
				new BreadthFirstSearchAlgorithm(VisitedGraph);
			PredecessorRecorderVisitor vis = new PredecessorRecorderVisitor();
			bfs.RegisterPredecessorRecorderHandlers(vis);
			bfs.Compute(s);

			// go throught the edges and build the predecessor table.
			int start = i;
			for (;i<this.Circuit.Count;++i)
			{
				IEdge e = this.Circuit[i];
				if (TemporaryEdges.Contains(e))
				{
					// store previous trail and start new one.
					if(trail.Count != 0)
						trails.Add(trail);
					// start new trail
					// take the shortest path from the start vertex to
					// the target vertex
					trail = vis.Path(e.Target);
				}
				else
					trail.Add(e);
			}

			// starting again on the circuit
			for (i=0;i<start;++i)
			{
				IEdge e = this.Circuit[i];
				if (TemporaryEdges.Contains(e))
				{
					// store previous trail and start new one.
					if(trail.Count != 0)
						trails.Add(trail);
					// start new trail
					// take the shortest path from the start vertex to
					// the target vertex
					trail = vis.Path(e.Target);
				}
				else
					trail.Add(e);
			}

			// adding the last element
			if (trail.Count!=0)
				trails.Add(trail);
		
			return trails;
		}
 public EdgeCollectionCollection Trails(IVertex s)
 {
     if (s == null)
     {
         throw new ArgumentNullException("s");
     }
     if (this.Circuit.Count == 0)
     {
         throw new Exception("Circuit is empty");
     }
     int num = 0;
     num = 0;
     while (num < this.Circuit.Count)
     {
         IEdge edge = this.Circuit.get_Item(num);
         if (!this.TemporaryEdges.Contains(edge) && (edge.get_Source() == s))
         {
             break;
         }
         num++;
     }
     if (num == this.Circuit.Count)
     {
         throw new Exception("Did not find vertex in eulerian trail?");
     }
     EdgeCollectionCollection collections = new EdgeCollectionCollection();
     EdgeCollection edges = new EdgeCollection();
     BreadthFirstSearchAlgorithm algorithm = new BreadthFirstSearchAlgorithm(this.VisitedGraph);
     PredecessorRecorderVisitor vis = new PredecessorRecorderVisitor();
     algorithm.RegisterPredecessorRecorderHandlers(vis);
     algorithm.Compute(s);
     int num2 = num;
     while (num < this.Circuit.Count)
     {
         IEdge edge2 = this.Circuit.get_Item(num);
         if (this.TemporaryEdges.Contains(edge2))
         {
             if (edges.Count != 0)
             {
                 collections.Add(edges);
             }
             edges = vis.Path(edge2.get_Target());
         }
         else
         {
             edges.Add(edge2);
         }
         num++;
     }
     for (num = 0; num < num2; num++)
     {
         IEdge edge3 = this.Circuit.get_Item(num);
         if (this.TemporaryEdges.Contains(edge3))
         {
             if (edges.Count != 0)
             {
                 collections.Add(edges);
             }
             edges = vis.Path(edge3.get_Target());
         }
         else
         {
             edges.Add(edge3);
         }
     }
     if (edges.Count != 0)
     {
         collections.Add(edges);
     }
     return collections;
 }