public static FlowGraph <T> FordFulkerson <T>(this FlowGraph <T> graph) { if (graph.Edges.Where(e => !e.Capacity.HasValue).Any()) { throw new ArgumentException("In dem Graphen muss für jede Kante eine Kapazität definiert sein."); } // Sicherstellen, dass der Fluss bei allen Kanten initialisiert ist. foreach (Edge <T> e in graph.Edges.Where(e => !e.Flow.HasValue)) { e.Flow = 0; } // Eine Kopie des Graphens erstellen. FlowGraph <T> maxFlowGraph = graph.Copy(); // Den Residualgraph erstellen FlowGraph <T> residualGraph = maxFlowGraph.GetResidualGraph(); while (residualGraph.DepthFirstSearch(residualGraph.Source, residualGraph.Target, out List <Edge <T> > path)) { int minAugmentingFlow = path.Select(e => Math.Abs(e.Flow.Value)).Min(); foreach (Edge <T> edge in path) { //Edge<T> edgeToModify = maxFlowGraph.Edges.Where(e => e.From.Equals(edge.From) && e.To.Equals(edge.To)).Single(); Edge <T> edgeToModify = maxFlowGraph.GetEdge(edge.From, edge.To); if (edge.Flow.Value > 0) { edgeToModify.Flow += minAugmentingFlow; } else { edgeToModify.Flow -= minAugmentingFlow; } // edgeToModify.Flow += edge.Flow; } residualGraph = maxFlowGraph.GetResidualGraph(); } return(maxFlowGraph); }
public void Copy_must_work() { Vertex<string> source = new Vertex<string>("s"); Vertex<string> target = new Vertex<string>("t"); FlowGraph<string> flowGraph = new FlowGraph<string>(source, target, new List<Vertex<string>>() { source, target }); flowGraph.AddVertex("a"); flowGraph.AddVertex("b"); flowGraph.AddEdge("s", "a", 5, 2); flowGraph.AddEdge("s", "b", 8, 4); flowGraph.AddEdge("a", "b", 3, 0); flowGraph.AddEdge("a", "t", 4, 2); flowGraph.AddEdge("b", "t", 6, 4); FlowGraph<string> flowGraphCopy = flowGraph.Copy(); Assert.IsFalse(ReferenceEquals(flowGraph.Vertices, flowGraphCopy.Vertices)); Assert.IsFalse(ReferenceEquals(flowGraph.Edges, flowGraphCopy.Edges)); Assert.IsFalse(ReferenceEquals(flowGraph.Vertices[0], flowGraphCopy.Vertices[0])); Assert.IsFalse(ReferenceEquals(flowGraph.Edges[0], flowGraphCopy.Edges[0])); }
public static FlowGraph InstantiateFlow(this FlowGraph flowGraph) { return(flowGraph.Copy() as FlowGraph); }