예제 #1
0
 /// <summary>
 /// Augmentation of the flows
 /// </summary>
 /// <param name="path">The augmentation path found</param>
 private void Augment(FlowPath path)
 {
     foreach (KeyValuePair <FlowArc, int> arcEntry in path.Arcs)
     {
         this.Flows[arcEntry.Key] += path.AdditionalCapacity * arcEntry.Value;
     }
 }
예제 #2
0
        /// <summary>
        /// Search of augmentating path
        /// </summary>
        /// <param name="source">Begining of the path</param>
        /// <param name="target">End of the path</param>
        /// <param name="visited">List of already visited nodes</param>
        /// <returns>An augmentating path OR null if none is found</returns>
        private FlowPath PathFinder(FlowNode source, FlowNode target, List <FlowNode> visited)
        {
            // adding source to list of visited nodes
            visited.Add(source);

            // trivial ending of recursion
            if (source == target)
            {
                FlowPath path = new FlowPath();
                path.AdditionalCapacity = float.MaxValue;
                return(path);
            }

            // searching for ongoing path
            foreach (FlowArc arc in this.Arcs)
            {
                double   delta = 0.0;
                FlowPath path  = null;
                int      sens  = 0;

                // is it a positive path ?
                if (arc.Start == source && this.Flows[arc] < arc.Capacity && !visited.Contains(arc.End))
                {
                    // recursive call on pathfinder
                    path  = this.PathFinder(arc.End, target, new List <FlowNode>(visited));
                    delta = arc.Capacity - this.Flows[arc];
                    sens  = 1;
                }
                // is it a negative path ?
                if (arc.End == source && this.Flows[arc] > 0 && !visited.Contains(arc.Start))
                {
                    // recursive call on pathfinder
                    path  = this.PathFinder(arc.Start, target, new List <FlowNode>(visited));
                    delta = this.Flows[arc];
                    sens  = -1;
                }

                // if an ongoing path has been found then
                if (null != path)
                {
                    // updating arcs and capacitiy
                    path.Arcs.Add(arc, sens);
                    path.AdditionalCapacity = Math.Min(delta, path.AdditionalCapacity);
                    return(path);
                }
            }
            // if no ongoing path found then return null
            return(null);
        }
예제 #3
0
        /// <summary>
        /// Implementation of the Ford-Fulkerson algorithm
        /// in order to calculate maximum flow
        /// </summary>
        private void CalculateMaximumFlow()
        {
            this.ResetCapacity();
            // search path
            FlowPath path = this.PathFinder(this.Source, this.Target, new List <FlowNode>());

            // if path exists then augmentation of flows
            while (null != path)
            {
                /* Only for debugging
                 * MessageBox.Show(path.ToString()); */
                this.Augment(path);
                // search new path
                path = this.PathFinder(this.Source, this.Target, new List <FlowNode>());
            }
        }