26 using System.Collections.Generic;
34 public interface IFlow<TCapacity>
40 Func<Arc, TCapacity> Capacity {
get; }
46 TCapacity FlowSize {
get; }
49 IEnumerable<KeyValuePair<Arc, TCapacity>> NonzeroArcs {
get; }
53 TCapacity Flow(
Arc arc);
61 public sealed
class Preflow : IFlow<double>
64 public Func<Arc, double>
Capacity {
get;
private set; }
69 private Dictionary<Arc, double> flow;
74 public double Error {
get;
private set; }
83 flow =
new Dictionary<Arc, double>();
87 dijkstra.AddSource(
Source);
88 dijkstra.RunUntilFixed(
Target);
89 double bottleneckCapacity = -dijkstra.GetDistance(
Target);
91 if (
double.IsPositiveInfinity(bottleneckCapacity))
98 Arc arc = dijkstra.GetParentArc(n);
99 flow[arc] =
double.PositiveInfinity;
100 n2 =
Graph.Other(arc, n);
106 if (
double.IsNegativeInfinity(bottleneckCapacity))
107 bottleneckCapacity = 0;
116 if (USource > U)
break;
118 U = Math.Min(U, USource);
124 if (UTarget > U)
break;
126 U = Math.Min(U, UTarget);
132 CapacityMultiplier = Utils.LargestPowerOfTwo(
long.MaxValue / U);
133 if (CapacityMultiplier == 0) CapacityMultiplier = 1;
136 FlowSize = p.FlowSize / CapacityMultiplier;
138 foreach (var kv
in p.NonzeroArcs) flow[kv.Key] = kv.Value / CapacityMultiplier;
142 private Arc artificialArc;
143 private double U, CapacityMultiplier;
144 private long IntegralCapacity(
Arc arc)
146 return (
long)( CapacityMultiplier * (arc == artificialArc ? U : Math.Min(U,
Capacity(arc))) );
149 public IEnumerable<KeyValuePair<Arc, double>>
NonzeroArcs
153 return flow.Where(kv => kv.Value != 0.0);
160 flow.TryGetValue(arc, out result);
171 public Func<Arc, long>
Capacity {
get;
private set; }
177 private readonly Dictionary<Arc, long> flow;
178 private readonly Dictionary<Node, long> excess;
179 private readonly Dictionary<Node, long> label;
180 private readonly PriorityQueue<Node, long> active;
189 flow =
new Dictionary<Arc, long>();
190 excess =
new Dictionary<Node, long>();
191 label =
new Dictionary<Node, long>();
192 active =
new PriorityQueue<Node, long>();
212 if (other ==
Source)
continue;
215 if (initialFlow == 0)
continue;
216 flow[arc] = initialFlow;
217 initialFlow = Math.Abs(initialFlow);
218 checked { outgoing += initialFlow; }
219 excess[other] += initialFlow;
220 if (other !=
Target) active[other] = 0;
222 excess[
Source] = -outgoing;
224 while (active.Count > 0)
227 Node z = active.Peek(out label_z);
230 long newlabel_z =
long.MinValue;
235 if (u == v)
continue;
236 Node other = (z == u ? v : u);
240 flow.TryGetValue(arc, out f);
242 long lowerBound = (isEdge ? -
Capacity(arc) : 0);
246 if (f == c)
continue;
248 long label_other = label[other];
249 if (label_other <= label_z)
250 newlabel_z = Math.Max(newlabel_z, label_other - 1);
253 long amount = (long)Math.Min((ulong)e, (ulong)(c - f));
254 flow[arc] = f + amount;
263 if (f == lowerBound)
continue;
265 long label_other = label[other];
266 if (label_other <= label_z)
267 newlabel_z = Math.Max(newlabel_z, label_other - 1);
270 long amount = (long)Math.Min((ulong)e, (ulong)(f - lowerBound));
271 flow[arc] = f - amount;
283 if (newlabel_z ==
long.MinValue)
throw new InvalidOperationException(
"Internal error.");
284 active[z] = label[z] = label_z = newlabel_z;
292 if (u == v)
continue;
294 if (!flow.TryGetValue(arc, out f))
continue;
299 public IEnumerable<KeyValuePair<Arc, long>>
NonzeroArcs
303 return flow.Where(kv => kv.Value != 0);
310 flow.TryGetValue(arc, out result);