// there is path from start to end in the residual network. private bool HasAugmentingPath(FlowWeightedGraph <V> graph, V startVertex, V endVertex) { Queue <V> queue = new Queue <V>(); queue.Enqueue(startVertex); marked[startVertex.GetHashCode()] = true; while (queue.Count != 0) { var first = queue.Dequeue(); foreach (var edge in graph.Adjacency(first)) { var other = edge.Other(first); if (edge.ResidualCapacityToVertex(other) > 0 && !marked[other.GetHashCode()]) { edgeTo[other.GetHashCode()] = edge; marked[other.GetHashCode()] = true; queue.Enqueue(other); } } } return(marked[endVertex.GetHashCode()]); }
public void FordFulkerson(FlowWeightedGraph <V> graph, V startVertex, V endVertex) { value = 0.0; // visit the graph and find a path from s to t, fill edgeto and marked arrays // this terminates when there is no augmenting path ( all full forward edges and empty backward edges) while (HasAugmentingPath(graph, startVertex, endVertex)) { double bottle = Double.PositiveInfinity; V begin = endVertex; for (; begin.CompareTo(startVertex) != 0; begin = edgeTo[begin.GetHashCode()].Other(begin)) { // minimum of the unused capacity in forward edge or available flow in backward edge bottle = Math.Min(bottle, edgeTo[begin.GetHashCode()].ResidualCapacityToVertex(begin)); } // now go thru the edge and add the residual capacity to augment the flow begin = endVertex; for (; begin.CompareTo(startVertex) != 0; begin = edgeTo[begin.GetHashCode()].Other(begin)) { edgeTo[begin.GetHashCode()].AddResidualFlowToVertex(begin, bottle); } value += bottle; } }