C++ Reference

C++ Reference: Graph

min_cost_flow.h
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 // An implementation of a cost-scaling push-relabel algorithm for
15 // the min-cost flow problem.
16 //
17 // In the following, we consider a graph G = (V,E) where V denotes the set
18 // of nodes (vertices) in the graph, E denotes the set of arcs (edges).
19 // n = |V| denotes the number of nodes in the graph, and m = |E| denotes the
20 // number of arcs in the graph.
21 //
22 // With each arc (v,w) is associated a nonnegative capacity u(v,w)
23 // (where 'u' stands for "upper bound") and a unit cost c(v,w). With
24 // each node v is associated a quantity named supply(v), which
25 // represents a supply of fluid (if >0) or a demand (if <0).
26 // Furthermore, no fluid is created in the graph so
27 // sum_{v in V} supply(v) = 0.
28 //
29 // A flow is a function from E to R such that:
30 // a) f(v,w) <= u(v,w) for all (v,w) in E (capacity constraint).
31 // b) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint).
32 // c) sum on v f(v,w) + supply(w) = 0 (flow conservation).
33 //
34 // The cost of a flow is sum on (v,w) in E ( f(v,w) * c(v,w) ) [Note:
35 // It can be confusing to beginners that the cost is actually double
36 // the amount that it might seem at first because of flow
37 // antisymmetry.]
38 //
39 // The problem to solve: find a flow of minimum cost such that all the
40 // fluid flows from the supply nodes to the demand nodes.
41 //
42 // The principles behind this algorithm are the following:
43 // 1/ handle pseudo-flows instead of flows and refine pseudo-flows until an
44 // epsilon-optimal minimum-cost flow is obtained,
45 // 2/ deal with epsilon-optimal pseudo-flows.
46 //
47 // 1/ A pseudo-flow is like a flow, except that a node's outflow minus
48 // its inflow can be different from its supply. If it is the case at a
49 // given node v, it is said that there is an excess (or deficit) at
50 // node v. A deficit is denoted by a negative excess and inflow =
51 // outflow + excess.
52 // (Look at ortools/graph/max_flow.h to see that the definition
53 // of preflow is more restrictive than the one for pseudo-flow in that a preflow
54 // only allows non-negative excesses, i.e., no deficit.)
55 // More formally, a pseudo-flow is a function f such that:
56 // a) f(v,w) <= u(v,w) for all (v,w) in E (capacity constraint).
57 // b) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint).
58 //
59 // For each v in E, we also define the excess at node v, the algebraic sum of
60 // all the incoming preflows at this node, added together with the supply at v.
61 // excess(v) = sum on u f(u,v) + supply(v)
62 //
63 // The goal of the algorithm is to obtain excess(v) = 0 for all v in V, while
64 // consuming capacity on some arcs, at the lowest possible cost.
65 //
66 // 2/ Internally to the algorithm and its analysis (but invisibly to
67 // the client), each node has an associated "price" (or potential), in
68 // addition to its excess. It is formally a function from E to R (the
69 // set of real numbers.). For a given price function p, the reduced
70 // cost of an arc (v,w) is:
71 // c_p(v,w) = c(v,w) + p(v) - p(w)
72 // (c(v,w) is the cost of arc (v,w).) For those familiar with linear
73 // programming, the price function can be viewed as a set of dual
74 // variables.
75 //
76 // For a constant epsilon >= 0, a pseudo-flow f is said to be epsilon-optimal
77 // with respect to a price function p if for every residual arc (v,w) in E,
78 // c_p(v,w) >= -epsilon.
79 //
80 // A flow f is optimal if and only if there exists a price function p such that
81 // no arc is admissible with respect to f and p.
82 //
83 // If the arc costs are integers, and epsilon < 1/n, any epsilon-optimal flow
84 // is optimal. The integer cost case is handled by multiplying all the arc costs
85 // and the initial value of epsilon by (n+1). When epsilon reaches 1, and
86 // the solution is epsilon-optimal, it means: for all residual arc (v,w) in E,
87 // (n+1) * c_p(v,w) >= -1, thus c_p(v,w) >= -1/(n+1) >= 1/n, and the
88 // solution is optimal.
89 //
90 // A node v is said to be *active* if excess(v) > 0.
91 // In this case the following operations can be applied to it:
92 // - if there are *admissible* incident arcs, i.e. arcs which are not saturated,
93 // and whose reduced costs are negative, a PushFlow operation can
94 // be applied. It consists in sending as much flow as both the excess at the
95 // node and the capacity of the arc permit.
96 // - if there are no admissible arcs, the active node considered is relabeled,
97 // This is implemented in Discharge, which itself calls PushFlow and Relabel.
98 //
99 // Discharge itself is called by Refine. Refine first saturates all the
100 // admissible arcs, then builds a stack of active nodes. It then applies
101 // Discharge for each active node, possibly adding new ones in the process,
102 // until no nodes are active. In that case an epsilon-optimal flow is obtained.
103 //
104 // Optimize iteratively calls Refine, while epsilon > 1, and divides epsilon by
105 // alpha (set by default to 5) before each iteration.
106 //
107 // The algorithm starts with epsilon = C, where C is the maximum absolute value
108 // of the arc costs. In the integer case which we are dealing with, since all
109 // costs are multiplied by (n+1), the initial value of epsilon is (n+1)*C.
110 // The algorithm terminates when epsilon = 1, and Refine() has been called.
111 // In this case, a minimum-cost flow is obtained.
112 //
113 // The complexity of the algorithm is O(n^2*m*log(n*C)) where C is the value of
114 // the largest arc cost in the graph.
115 //
116 // IMPORTANT:
117 // The algorithm is not able to detect the infeasibility of a problem (i.e.,
118 // when a bottleneck in the network prohibits sending all the supplies.)
119 // Worse, it could in some cases loop forever. This is why feasibility checking
120 // is enabled by default (FLAGS_min_cost_flow_check_feasibility=true.)
121 // Feasibility checking is implemented using a max-flow, which has a much lower
122 // complexity. The impact on performance is negligible, while the risk of being
123 // caught in an endless loop is removed. Note that using the feasibility checker
124 // roughly doubles the memory consumption.
125 //
126 // The starting reference for this class of algorithms is:
127 // A.V. Goldberg and R.E. Tarjan, "Finding Minimum-Cost Circulations by
128 // Successive Approximation." Mathematics of Operations Research, Vol. 15,
129 // 1990:430-466.
130 // http://portal.acm.org/citation.cfm?id=92225
131 //
132 // Implementation issues are tackled in:
133 // A.V. Goldberg, "An Efficient Implementation of a Scaling Minimum-Cost Flow
134 // Algorithm," Journal of Algorithms, (1997) 22:1-29
135 // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.258
136 //
137 // A.V. Goldberg and M. Kharitonov, "On Implementing Scaling Push-Relabel
138 // Algorithms for the Minimum-Cost Flow Problem", Network flows and matching:
139 // First DIMACS implementation challenge, DIMACS Series in Discrete Mathematics
140 // and Theoretical Computer Science, (1993) 12:157-198.
141 // ftp://dimacs.rutgers.edu/pub/netflow/submit/papers/Goldberg-mincost/scalmin.ps
142 // and in:
143 // U. Bunnagel, B. Korte, and J. Vygen. “Efficient implementation of the
144 // Goldberg-Tarjan minimum-cost flow algorithm.” Optimization Methods and
145 // Software (1998) vol. 10, no. 2:157-174.
146 // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.84.9897
147 //
148 // We have tried as much as possible in this implementation to keep the
149 // notations and namings of the papers cited above, except for 'demand' or
150 // 'balance' which have been replaced by 'supply', with the according sign
151 // changes to better accommodate with the API of the rest of our tools. A demand
152 // is denoted by a negative supply.
153 //
154 // TODO(user): See whether the following can bring any improvements on real-life
155 // problems.
156 // R.K. Ahuja, A.V. Goldberg, J.B. Orlin, and R.E. Tarjan, "Finding minimum-cost
157 // flows by double scaling," Mathematical Programming, (1992) 53:243-266.
158 // http://www.springerlink.com/index/gu7404218u6kt166.pdf
159 //
160 // An interesting general reference on network flows is:
161 // R. K. Ahuja, T. L. Magnanti, J. B. Orlin, "Network Flows: Theory, Algorithms,
162 // and Applications," Prentice Hall, 1993, ISBN: 978-0136175490,
163 // http://www.amazon.com/dp/013617549X
164 //
165 // Keywords: Push-relabel, min-cost flow, network, graph, Goldberg, Tarjan,
166 // Dinic, Dinitz.
167 
168 #ifndef OR_TOOLS_GRAPH_MIN_COST_FLOW_H_
169 #define OR_TOOLS_GRAPH_MIN_COST_FLOW_H_
170 
171 #include <algorithm>
172 #include <stack>
173 #include <string>
174 #include <vector>
175 
176 #include "ortools/base/integral_types.h"
177 #include "ortools/base/logging.h"
178 #include "ortools/base/macros.h"
180 #include "ortools/graph/graph.h"
181 #include "ortools/util/stats.h"
182 #include "ortools/util/zvector.h"
183 
184 namespace operations_research {
185 
186 // Forward declaration.
187 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
189 
190 // Different statuses for a solved problem.
191 // We use a base class to share it between our different interfaces.
193  public:
194  enum Status {
202  };
203 };
204 
205 // A simple and efficient min-cost flow interface. This is as fast as
206 // GenericMinCostFlow<ReverseArcStaticGraph>, which is the fastest, but is uses
207 // more memory in order to hide the somewhat involved construction of the
208 // static graph.
209 //
210 // TODO(user): If the need arises, extend this interface to support warm start
211 // and incrementality between solves. Note that this is already supported by the
212 // GenericMinCostFlow<> interface.
214  public:
215  // The constructor takes no size. New node indices will be created lazily by
216  // AddArcWithCapacityAndUnitCost() or SetNodeSupply() such that the set of
217  // valid nodes will always be [0, NumNodes()).
219 
220  // Adds a directed arc from tail to head to the underlying graph with
221  // a given capacity and cost per unit of flow.
222  // * Node indices and the capacity must be non-negative (>= 0).
223  // * The unit cost can take any integer value (even negative).
224  // * Self-looping and duplicate arcs are supported.
225  // * After the method finishes, NumArcs() == the returned ArcIndex + 1.
227  FlowQuantity capacity,
228  CostValue unit_cost);
229 
230  // Sets the supply of the given node. The node index must be non-negative (>=
231  // 0). Nodes implicitly created will have a default supply set to 0. A demand
232  // is modeled as a negative supply.
233  void SetNodeSupply(NodeIndex node, FlowQuantity supply);
234 
235  // Solves the problem, and returns the problem status. This function
236  // requires that the sum of all node supply minus node demand is zero and
237  // that the graph has enough capacity to send all supplies and serve all
238  // demands. Otherwise, it will return INFEASIBLE.
240  return SolveWithPossibleAdjustment(SupplyAdjustment::DONT_ADJUST);
241  }
242 
243  // Same as Solve(), but does not have the restriction that the supply
244  // must match the demand or that the graph has enough capacity to serve
245  // all the demand or use all the supply. This will compute a maximum-flow
246  // with minimum cost. The value of the maximum-flow will be given by
247  // MaximumFlow().
249  return SolveWithPossibleAdjustment(SupplyAdjustment::ADJUST);
250  }
251 
252  // Returns the cost of the minimum-cost flow found by the algorithm when
253  // the returned Status is OPTIMAL.
254  CostValue OptimalCost() const;
255 
256  // Returns the total flow of the minimum-cost flow found by the algorithm
257  // when the returned Status is OPTIMAL.
258  FlowQuantity MaximumFlow() const;
259 
260  // Returns the flow on arc, this only make sense for a successful Solve().
261  //
262  // Note: It is possible that there is more than one optimal solution. The
263  // algorithm is deterministic so it will always return the same solution for
264  // a given problem. However, there is no guarantee of this from one code
265  // version to the next (but the code does not change often).
266  FlowQuantity Flow(ArcIndex arc) const;
267 
268  // Accessors for the user given data. The implementation will crash if "arc"
269  // is not in [0, NumArcs()) or "node" is not in [0, NumNodes()).
270  NodeIndex NumNodes() const;
271  ArcIndex NumArcs() const;
272  NodeIndex Tail(ArcIndex arc) const;
273  NodeIndex Head(ArcIndex arc) const;
274  FlowQuantity Capacity(ArcIndex arc) const;
275  FlowQuantity Supply(NodeIndex node) const;
276  CostValue UnitCost(ArcIndex arc) const;
277 
278  private:
279  typedef ::util::ReverseArcStaticGraph<NodeIndex, ArcIndex> Graph;
280  enum SupplyAdjustment { ADJUST, DONT_ADJUST };
281 
282  // Applies the permutation in arc_permutation_ to the given arc index.
283  ArcIndex PermutedArc(ArcIndex arc);
284  // Solves the problem, potentially applying supply and demand adjustment,
285  // and returns the problem status.
286  Status SolveWithPossibleAdjustment(SupplyAdjustment adjustment);
287  void ResizeNodeVectors(NodeIndex node);
288 
289  std::vector<NodeIndex> arc_tail_;
290  std::vector<NodeIndex> arc_head_;
291  std::vector<FlowQuantity> arc_capacity_;
292  std::vector<FlowQuantity> node_supply_;
293  std::vector<CostValue> arc_cost_;
294  std::vector<ArcIndex> arc_permutation_;
295  std::vector<FlowQuantity> arc_flow_;
296  CostValue optimal_cost_;
297  FlowQuantity maximum_flow_;
298 
299  DISALLOW_COPY_AND_ASSIGN(SimpleMinCostFlow);
300 };
301 
302 // Generic MinCostFlow that works with StarGraph and all the graphs handling
303 // reverse arcs from graph.h, see the end of min_cost_flow.cc for the exact
304 // types this class is compiled for.
305 //
306 // One can greatly decrease memory usage by using appropriately small integer
307 // types:
308 // - For the Graph<> types, i.e. NodeIndexType and ArcIndexType, see graph.h.
309 // - ArcFlowType is used for the *per-arc* flow quantity. It must be signed, and
310 // large enough to hold the maximum arc capacity and its negation.
311 // - ArcScaledCostType is used for a per-arc scaled cost. It must be signed
312 // and large enough to hold the maximum unit cost of an arc times
313 // (num_nodes + 1).
314 //
315 // Note that the latter two are different than FlowQuantity and CostValue, which
316 // are used for global, aggregated values and may need to be larger.
317 //
318 // TODO(user): Avoid using the globally defined type CostValue and FlowQuantity.
319 // Also uses the Arc*Type where there is no risk of overflow in more places.
320 template <typename Graph, typename ArcFlowType = FlowQuantity,
321  typename ArcScaledCostType = CostValue>
322 class GenericMinCostFlow : public MinCostFlowBase {
323  public:
324  typedef typename Graph::NodeIndex NodeIndex;
325  typedef typename Graph::ArcIndex ArcIndex;
326  typedef typename Graph::OutgoingArcIterator OutgoingArcIterator;
327  typedef typename Graph::OutgoingOrOppositeIncomingArcIterator
329  typedef ZVector<ArcIndex> ArcIndexArray;
330 
331  // Initialize a MinCostFlow instance on the given graph. The graph does not
332  // need to be fully built yet, but its capacity reservation is used to
333  // initialize the memory of this class.
334  explicit GenericMinCostFlow(const Graph* graph);
335 
336  // Returns the graph associated to the current object.
337  const Graph* graph() const { return graph_; }
338 
339  // Returns the status of last call to Solve(). NOT_SOLVED is returned if
340  // Solve() has never been called or if the problem has been modified in such a
341  // way that the previous solution becomes invalid.
342  Status status() const { return status_; }
343 
344  // Sets the supply corresponding to node. A demand is modeled as a negative
345  // supply.
346  void SetNodeSupply(NodeIndex node, FlowQuantity supply);
347 
348  // Sets the unit cost for the given arc.
349  void SetArcUnitCost(ArcIndex arc, ArcScaledCostType unit_cost);
350 
351  // Sets the capacity for the given arc.
352  void SetArcCapacity(ArcIndex arc, ArcFlowType new_capacity);
353 
354  // Sets the flow for the given arc. Note that new_flow must be smaller than
355  // the capacity of the arc.
356  void SetArcFlow(ArcIndex arc, ArcFlowType new_flow);
357 
358  // Solves the problem, returning true if a min-cost flow could be found.
359  bool Solve();
360 
361  // Checks for feasibility, i.e., that all the supplies and demands can be
362  // matched without exceeding bottlenecks in the network.
363  // If infeasible_supply_node (resp. infeasible_demand_node) are not NULL,
364  // they are populated with the indices of the nodes where the initial supplies
365  // (resp. demands) are too large. Feasible values for the supplies and
366  // demands are accessible through FeasibleSupply.
367  // Note that CheckFeasibility is called by Solve() when the flag
368  // min_cost_flow_check_feasibility is set to true (which is the default.)
369  bool CheckFeasibility(std::vector<NodeIndex>* const infeasible_supply_node,
370  std::vector<NodeIndex>* const infeasible_demand_node);
371 
372  // Makes the min-cost flow problem solvable by truncating supplies and
373  // demands to a level acceptable by the network. There may be several ways to
374  // do it. In our case, the levels are computed from the result of the max-flow
375  // algorithm run in CheckFeasibility().
376  // MakeFeasible returns false if CheckFeasibility() was not called before.
377  bool MakeFeasible();
378 
379  // Returns the cost of the minimum-cost flow found by the algorithm.
380  CostValue GetOptimalCost() const { return total_flow_cost_; }
381 
382  // Returns the flow on the given arc using the equations given in the
383  // comment on residual_arc_capacity_.
384  FlowQuantity Flow(ArcIndex arc) const;
385 
386  // Returns the capacity of the given arc.
387  FlowQuantity Capacity(ArcIndex arc) const;
388 
389  // Returns the unscaled cost for the given arc.
390  CostValue UnitCost(ArcIndex arc) const;
391 
392  // Returns the supply at a given node. Demands are modelled as negative
393  // supplies.
394  FlowQuantity Supply(NodeIndex node) const;
395 
396  // Returns the initial supply at a given node.
398 
399  // Returns the largest supply (if > 0) or largest demand in absolute value
400  // (if < 0) admissible at node. If the problem is not feasible, some of these
401  // values will be smaller (in absolute value) than the initial supplies
402  // and demand given as input.
404 
405  // Whether to use the UpdatePrices() heuristic.
406  void SetUseUpdatePrices(bool value) { use_price_update_ = value; }
407 
408  // Whether to check the feasibility of the problem with a max-flow, prior to
409  // solving it. This uses about twice as much memory, but detects infeasible
410  // problems (where the flow can't be satisfied) and makes Solve() return
411  // INFEASIBLE. If you disable this check, you will spare memory but you must
412  // make sure that your problem is feasible, otherwise the code can loop
413  // forever.
414  void SetCheckFeasibility(bool value) { check_feasibility_ = value; }
415 
416  private:
417  // Returns true if the given arc is admissible i.e. if its residual capacity
418  // is strictly positive, and its reduced cost strictly negative, i.e., pushing
419  // more flow into it will result in a reduction of the total cost.
420  bool IsAdmissible(ArcIndex arc) const;
421  bool FastIsAdmissible(ArcIndex arc, CostValue tail_potential) const;
422 
423  // Returns true if node is active, i.e., if its supply is positive.
424  bool IsActive(NodeIndex node) const;
425 
426  // Returns the reduced cost for a given arc.
427  CostValue ReducedCost(ArcIndex arc) const;
428  CostValue FastReducedCost(ArcIndex arc, CostValue tail_potential) const;
429 
430  // Returns the first incident arc of a given node.
431  ArcIndex GetFirstOutgoingOrOppositeIncomingArc(NodeIndex node) const;
432 
433  // Checks the consistency of the input, i.e., whether the sum of the supplies
434  // for all nodes is equal to zero. To be used in a DCHECK.
435  bool CheckInputConsistency() const;
436 
437  // Checks whether the result is valid, i.e. whether for each arc,
438  // residual_arc_capacity_[arc] == 0 || ReducedCost(arc) >= -epsilon_.
439  // (A solution is epsilon-optimal if ReducedCost(arc) >= -epsilon.)
440  // To be used in a DCHECK.
441  bool CheckResult() const;
442 
443  // Checks that the cost range fits in the range of int64's.
444  // To be used in a DCHECK.
445  bool CheckCostRange() const;
446 
447  // Checks the relabel precondition (to be used in a DCHECK):
448  // - The node must be active, or have a 0 excess (relaxation for the Push
449  // Look-Ahead heuristic).
450  // - The node must have no admissible arcs.
451  bool CheckRelabelPrecondition(NodeIndex node) const;
452 
453  // Returns context concatenated with information about a given arc
454  // in a human-friendly way.
455  std::string DebugString(const std::string& context, ArcIndex arc) const;
456 
457  // Resets the first_admissible_arc_ array to the first incident arc of each
458  // node.
459  void ResetFirstAdmissibleArcs();
460 
461  // Scales the costs, by multiplying them by (graph_->num_nodes() + 1).
462  void ScaleCosts();
463 
464  // Unscales the costs, by dividing them by (graph_->num_nodes() + 1).
465  void UnscaleCosts();
466 
467  // Optimizes the cost by dividing epsilon_ by alpha_ and calling Refine().
468  void Optimize();
469 
470  // Saturates the admissible arcs, i.e., push as much flow as possible.
471  void SaturateAdmissibleArcs();
472 
473  // Pushes flow on a given arc, i.e., consumes flow on
474  // residual_arc_capacity_[arc], and consumes -flow on
475  // residual_arc_capacity_[Opposite(arc)]. Updates node_excess_ at the tail
476  // and head of the arc accordingly.
477  void PushFlow(FlowQuantity flow, ArcIndex arc);
478  void FastPushFlow(FlowQuantity flow, ArcIndex arc, NodeIndex tail);
479 
480  // Initializes the stack active_nodes_.
481  void InitializeActiveNodeStack();
482 
483  // Price update heuristics as described in A.V. Goldberg, "An Efficient
484  // Implementation of a Scaling Minimum-Cost Flow Algorithm," Journal of
485  // Algorithms, (1997) 22:1-29
486  // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.258
487  void UpdatePrices();
488 
489  // Performs an epsilon-optimization step by saturating admissible arcs
490  // and discharging the active nodes.
491  void Refine();
492 
493  // Discharges an active node by saturating its admissible adjacent arcs,
494  // if any, and by relabelling it when it becomes inactive.
495  void Discharge(NodeIndex node);
496 
497  // Part of the Push LookAhead heuristic. When we are about to push on the
498  // in_arc, we check that the head (i.e node here) can accept the flow and
499  // return true if this is the case:
500  // - Returns true if the node excess is < 0.
501  // - Returns true if node is an admissible arc at its current potential.
502  // - If the two conditions above are false, the node can be relabeled. We
503  // do that and return true if the in_arc is still admissible.
504  bool LookAhead(ArcIndex in_arc, CostValue in_tail_potential, NodeIndex node);
505 
506  // Relabels node, i.e., decreases its potential while keeping the
507  // epsilon-optimality of the pseudo flow. See CheckRelabelPrecondition() for
508  // details on the preconditions.
509  void Relabel(NodeIndex node);
510 
511  // Handy member functions to make the code more compact.
512  NodeIndex Head(ArcIndex arc) const { return graph_->Head(arc); }
513  NodeIndex Tail(ArcIndex arc) const { return graph_->Tail(arc); }
514  ArcIndex Opposite(ArcIndex arc) const;
515  bool IsArcDirect(ArcIndex arc) const;
516  bool IsArcValid(ArcIndex arc) const;
517 
518  // Pointer to the graph passed as argument.
519  const Graph* graph_;
520 
521  // An array representing the supply (if > 0) or the demand (if < 0)
522  // for each node in graph_.
523  QuantityArray node_excess_;
524 
525  // An array representing the potential (or price function) for
526  // each node in graph_.
527  CostArray node_potential_;
528 
529  // An array representing the residual_capacity for each arc in graph_.
530  // Residual capacities enable one to represent the capacity and flow for all
531  // arcs in the graph in the following manner.
532  // For all arcs, residual_arc_capacity_[arc] = capacity[arc] - flow[arc]
533  // Moreover, for reverse arcs, capacity[arc] = 0 by definition.
534  // Also flow[Opposite(arc)] = -flow[arc] by definition.
535  // Therefore:
536  // - for a direct arc:
537  // flow[arc] = 0 - flow[Opposite(arc)]
538  // = capacity[Opposite(arc)] - flow[Opposite(arc)]
539  // = residual_arc_capacity_[Opposite(arc)]
540  // - for a reverse arc:
541  // flow[arc] = -residual_arc_capacity_[arc]
542  // Using these facts enables one to only maintain residual_arc_capacity_,
543  // instead of both capacity and flow, for each direct and indirect arc. This
544  // reduces the amount of memory for this information by a factor 2.
545  // Note that the sum of the largest capacity of an arc in the graph and of
546  // the total flow in the graph mustn't exceed the largest 64 bit integer
547  // to avoid errors. CheckInputConsistency() verifies this constraint.
548  ZVector<ArcFlowType> residual_arc_capacity_;
549 
550  // An array representing the first admissible arc for each node in graph_.
551  ArcIndexArray first_admissible_arc_;
552 
553  // A stack used for managing active nodes in the algorithm.
554  // Note that the papers cited above recommend the use of a queue, but
555  // benchmarking so far has not proved it is better.
556  std::stack<NodeIndex> active_nodes_;
557 
558  // epsilon_ is the tolerance for optimality.
559  CostValue epsilon_;
560 
561  // alpha_ is the factor by which epsilon_ is divided at each iteration of
562  // Refine().
563  const int64 alpha_;
564 
565  // cost_scaling_factor_ is the scaling factor for cost.
566  CostValue cost_scaling_factor_;
567 
568  // An array representing the scaled unit cost for each arc in graph_.
569  ZVector<ArcScaledCostType> scaled_arc_unit_cost_;
570 
571  // The total cost of the flow.
572  CostValue total_flow_cost_;
573 
574  // The status of the problem.
575  Status status_;
576 
577  // An array containing the initial excesses (i.e. the supplies) for each
578  // node. This is used to create the max-flow-based feasibility checker.
579  QuantityArray initial_node_excess_;
580 
581  // An array containing the best acceptable excesses for each of the
582  // nodes. These excesses are imposed by the result of the max-flow-based
583  // feasibility checker for the nodes with an initial supply != 0. For the
584  // other nodes, the excess is simply 0.
585  QuantityArray feasible_node_excess_;
586 
587  // Statistics about this class.
588  StatsGroup stats_;
589 
590  // Number of Relabel() since last UpdatePrices().
591  int num_relabels_since_last_price_update_;
592 
593  // A Boolean which is true when feasibility has been checked.
594  bool feasibility_checked_;
595 
596  // Whether to use the UpdatePrices() heuristic.
597  bool use_price_update_;
598 
599  // Whether to check the problem feasibility with a max-flow.
600  bool check_feasibility_;
601 
602  DISALLOW_COPY_AND_ASSIGN(GenericMinCostFlow);
603 };
604 
605 #if !SWIG
606 
607 // Default MinCostFlow instance that uses StarGraph.
608 // New clients should use SimpleMinCostFlow if they can.
609 class MinCostFlow : public GenericMinCostFlow<StarGraph> {
610  public:
612 };
613 
614 #endif // SWIG
615 
616 } // namespace operations_research
617 #endif // OR_TOOLS_GRAPH_MIN_COST_FLOW_H_
Graph::OutgoingArcIterator OutgoingArcIterator
FlowQuantity Flow(ArcIndex arc) const
FlowQuantity InitialSupply(NodeIndex node) const
int64 CostValue
Definition: ebert_graph.h:203
ArcIndex NumArcs() const
NodeIndex Head(ArcIndex arc) const
NodeIndex NumNodes() const
ListGraph Graph
Definition: graph.h:2356
FlowQuantity MaximumFlow() const
bool MakeFeasible()
CostValue UnitCost(ArcIndex arc) const
Definition: christofides.h:33
Graph::ArcIndex ArcIndex
void SetArcCapacity(ArcIndex arc, ArcFlowType new_capacity)
@ BAD_COST_RANGE
ZVector< FlowQuantity > QuantityArray
Definition: ebert_graph.h:209
Graph::NodeIndex NodeIndex
CostValue UnitCost(ArcIndex arc) const
GenericMinCostFlow(const Graph *graph)
@ OPTIMAL
Graph::OutgoingOrOppositeIncomingArcIterator OutgoingOrOppositeIncomingArcIterator
ZVector< CostValue > CostArray
Definition: ebert_graph.h:210
void SetArcUnitCost(ArcIndex arc, ArcScaledCostType unit_cost)
Status status() const
@ BAD_RESULT
CostValue GetOptimalCost() const
int64 FlowQuantity
Definition: ebert_graph.h:202
Definition: ebert_graph.h:188
SimpleMinCostFlow()
FlowQuantity FeasibleSupply(NodeIndex node) const
Status SolveMaxFlowWithMinCost()
bool Solve()
FlowQuantity Flow(ArcIndex arc) const
Status Solve()
FlowQuantity Capacity(ArcIndex arc) const
ZVector< ArcIndex > ArcIndexArray
void SetArcFlow(ArcIndex arc, ArcFlowType new_flow)
int32 ArcIndex
Definition: ebert_graph.h:201
void SetCheckFeasibility(bool value)
NodeIndex Tail(ArcIndex arc) const
ArcIndex AddArcWithCapacityAndUnitCost(NodeIndex tail, NodeIndex head, FlowQuantity capacity, CostValue unit_cost)
int32 NodeIndex
Definition: ebert_graph.h:192
MinCostFlow(const StarGraph *graph)
const Graph * graph() const
CostValue OptimalCost() const
void SetUseUpdatePrices(bool value)
@ NOT_SOLVED
FlowQuantity Capacity(ArcIndex arc) const
FlowQuantity Supply(NodeIndex node) const
@ INFEASIBLE
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
FlowQuantity Supply(NodeIndex node) const
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
@ UNBALANCED
bool CheckFeasibility(std::vector< NodeIndex > *const infeasible_supply_node, std::vector< NodeIndex > *const infeasible_demand_node)
Status
@ FEASIBLE