/// <summary> /// Augmentation of the flows /// </summary> /// <param name="path">The augmentation path found</param> private void Augment(FlowPath path) { foreach (FlowArc arc in path.Arcs) { this.Flows[arc] += path.AdditionalCapacity; } }
/// <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) { this.Augment(path); // search new path path = this.PathFinder(this.Source, this.Target, new List <FlowNode>()); } }
/// <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; FlowPath path = null; // 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]; } // 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]; } // if an ongoing path has been found then if (null != path) { // updating arcs and capacitiy path.Arcs.Add(arc); path.AdditionalCapacity = Math.Min(delta, path.AdditionalCapacity); return(path); } } // if no ongoing path found then return null return(null); }