public Preflow(IGraph graph, Func <Arc, double> capacity, Node source, Node target) { Graph = graph; Capacity = capacity; Source = source; Target = target; flow = new Dictionary <Arc, double>(); // calculate bottleneck capacity to get an upper bound for the flow value Dijkstra dijkstra = new Dijkstra(Graph, a => - Capacity(a), DijkstraMode.Maximum); dijkstra.AddSource(Source); dijkstra.RunUntilFixed(Target); double bottleneckCapacity = -dijkstra.GetDistance(Target); if (double.IsPositiveInfinity(bottleneckCapacity)) { // flow value is infinity FlowSize = double.PositiveInfinity; Error = 0; for (Node n = Target, n2 = Node.Invalid; n != Source; n = n2) { Arc arc = dijkstra.GetParentArc(n); flow[arc] = double.PositiveInfinity; n2 = Graph.Other(arc, n); } } else { // flow value is finite if (double.IsNegativeInfinity(bottleneckCapacity)) { bottleneckCapacity = 0; // Target is not accessible } U = Graph.ArcCount() * bottleneckCapacity; // calculate other upper bounds for the flow double USource = 0; foreach (var arc in Graph.Arcs(Source, ArcFilter.Forward)) { if (Graph.Other(arc, Source) != Source) { USource += Capacity(arc); if (USource > U) { break; } } } U = Math.Min(U, USource); double UTarget = 0; foreach (var arc in Graph.Arcs(Target, ArcFilter.Backward)) { if (Graph.Other(arc, Target) != Target) { UTarget += Capacity(arc); if (UTarget > U) { break; } } } U = Math.Min(U, UTarget); Supergraph sg = new Supergraph(Graph); Node newSource = sg.AddNode(); artificialArc = sg.AddArc(newSource, Source, Directedness.Directed); CapacityMultiplier = Utils.LargestPowerOfTwo(long.MaxValue / U); if (CapacityMultiplier == 0) { CapacityMultiplier = 1; } var p = new IntegerPreflow(sg, IntegralCapacity, newSource, Target); FlowSize = p.FlowSize / CapacityMultiplier; Error = Graph.ArcCount() / CapacityMultiplier; foreach (var kv in p.NonzeroArcs) { flow[kv.Key] = kv.Value / CapacityMultiplier; } } }
public Preflow(IGraph graph, Func <Arc, double> capacity, Node source, Node target) { Graph = graph; Capacity = capacity; Source = source; Target = target; flow = new Dictionary <Arc, double>(); Dijkstra dijkstra = new Dijkstra(Graph, (Arc a) => 0.0 - Capacity(a), DijkstraMode.Maximum); dijkstra.AddSource(Source); dijkstra.RunUntilFixed(Target); double num = 0.0 - dijkstra.GetDistance(Target); if (double.IsPositiveInfinity(num)) { FlowSize = double.PositiveInfinity; Error = 0.0; Node node = Target; Node invalid = Node.Invalid; while (node != Source) { Arc parentArc = dijkstra.GetParentArc(node); flow[parentArc] = double.PositiveInfinity; invalid = Graph.Other(parentArc, node); node = invalid; } } else { if (double.IsNegativeInfinity(num)) { num = 0.0; } U = (double)Graph.ArcCount(ArcFilter.All) * num; double num2 = 0.0; foreach (Arc item in Graph.Arcs(Source, ArcFilter.Forward)) { if (Graph.Other(item, Source) != Source) { num2 += Capacity(item); if (num2 > U) { break; } } } U = Math.Min(U, num2); double num3 = 0.0; foreach (Arc item2 in Graph.Arcs(Target, ArcFilter.Backward)) { if (Graph.Other(item2, Target) != Target) { num3 += Capacity(item2); if (num3 > U) { break; } } } U = Math.Min(U, num3); Supergraph supergraph = new Supergraph(Graph); Node node2 = supergraph.AddNode(); artificialArc = supergraph.AddArc(node2, Source, Directedness.Directed); CapacityMultiplier = Utils.LargestPowerOfTwo(9.2233720368547758E+18 / U); if (CapacityMultiplier == 0.0) { CapacityMultiplier = 1.0; } IntegerPreflow integerPreflow = new IntegerPreflow(supergraph, IntegralCapacity, node2, Target); FlowSize = (double)integerPreflow.FlowSize / CapacityMultiplier; Error = (double)Graph.ArcCount(ArcFilter.All) / CapacityMultiplier; foreach (KeyValuePair <Arc, long> nonzeroArc in integerPreflow.NonzeroArcs) { flow[nonzeroArc.Key] = (double)nonzeroArc.Value / CapacityMultiplier; } } }