Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
min_cost_flow.h
Go to the documentation of this file.
1// Copyright 2010-2024 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 <cstdint>
172#include <stack>
173#include <string>
174#include <vector>
175
176#include "absl/strings/string_view.h"
178#include "ortools/graph/graph.h"
179#include "ortools/util/stats.h"
180#include "ortools/util/zvector.h"
181
182namespace operations_research {
183
184// Forward declaration.
185template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
186class GenericMinCostFlow;
187
188// Different statuses for a solved problem.
189// We use a base class to share it between our different interfaces.
191 public:
192 enum Status {
199
200 // This is returned when an integer overflow occurred during the algorithm
201 // execution.
202 //
203 // Some details on how to deal with this:
204 // - The sum of all incoming/outgoing capacity at each node should not
205 // overflow. TODO(user): this is not always properly checked and probably
206 // deserve a different return status.
207 // - Since we scale cost, each arc unit cost times (num_nodes + 1) should
208 // not overflow. We detect that at the beginning of the Solve().
209 // - This is however not sufficient as the node potential depends on the
210 // minimum cost of sending 1 unit of flow through the residual graph. If
211 // the maximum arc unit cost is smaller than kint64max / (2 * n ^ 2) then
212 // one shouldn't run into any overflow. But in pratice this bound is quite
213 // loose. So it is possible to try with higher cost, and the algorithm
214 // will detect if an overflow actually happen and return BAD_COST_RANGE,
215 // so we can retry with smaller cost.
216 //
217 // And two remarks:
218 // - Note that the complexity of the algorithm depends on the maximum cost,
219 // so it is usually a good idea to use unit cost that are as small as
220 // possible.
221 // - Even if there is no overflow, note that the total cost can easily not
222 // fit on an int64_t since it is the product of the unit cost times the
223 // actual amount of flow sent. This is easy to detect since the final
224 // optimal cost will be set to kint64max. It is also relatively easy to
225 // deal with since we will still have the proper flow on each arc. It is
226 // thus possible to recompute the total cost in double or using
227 // absl::int128 if the need arise.
229 };
230};
231
232// A simple and efficient min-cost flow interface. This is as fast as
233// GenericMinCostFlow<ReverseArcStaticGraph>, which is the fastest, but is uses
234// more memory in order to hide the somewhat involved construction of the
235// static graph.
236//
237// TODO(user): If the need arises, extend this interface to support warm start
238// and incrementality between solves. Note that this is already supported by the
239// GenericMinCostFlow<> interface.
241 public:
242 // By default, the constructor takes no size. New node indices are created
243 // lazily by AddArcWithCapacityAndUnitCost() or SetNodeSupply() such that the
244 // set of valid nodes will always be [0, NumNodes()).
245 //
246 // You may pre-reserve the internal data structures with a given expected
247 // number of nodes and arcs, to potentially gain performance.
248 explicit SimpleMinCostFlow(NodeIndex reserve_num_nodes = 0,
249 ArcIndex reserve_num_arcs = 0);
250
251#ifndef SWIG
252 // This type is neither copyable nor movable.
255#endif
256
257 // Adds a directed arc from tail to head to the underlying graph with
258 // a given capacity and cost per unit of flow.
259 // * Node indices and the capacity must be non-negative (>= 0).
260 // * The unit cost can take any integer value (even negative).
261 // * Self-looping and duplicate arcs are supported.
262 // * After the method finishes, NumArcs() == the returned ArcIndex + 1.
264 FlowQuantity capacity,
265 CostValue unit_cost);
266
267 // Sets the supply of the given node. The node index must be non-negative (>=
268 // 0). Nodes implicitly created will have a default supply set to 0. A demand
269 // is modeled as a negative supply.
270 void SetNodeSupply(NodeIndex node, FlowQuantity supply);
271
272 // Solves the problem, and returns the problem status. This function
273 // requires that the sum of all node supply minus node demand is zero and
274 // that the graph has enough capacity to send all supplies and serve all
275 // demands. Otherwise, it will return INFEASIBLE.
277 return SolveWithPossibleAdjustment(SupplyAdjustment::DONT_ADJUST);
278 }
279
280 // Same as Solve(), but does not have the restriction that the supply
281 // must match the demand or that the graph has enough capacity to serve
282 // all the demand or use all the supply. This will compute a maximum-flow
283 // with minimum cost. The value of the maximum-flow will be given by
284 // MaximumFlow().
286 return SolveWithPossibleAdjustment(SupplyAdjustment::ADJUST);
287 }
288
289 // Returns the cost of the minimum-cost flow found by the algorithm when
290 // the returned Status is OPTIMAL.
291 CostValue OptimalCost() const;
292
293 // Returns the total flow of the minimum-cost flow found by the algorithm
294 // when the returned Status is OPTIMAL.
296
297 // Returns the flow on arc, this only make sense for a successful Solve().
298 //
299 // Note: It is possible that there is more than one optimal solution. The
300 // algorithm is deterministic so it will always return the same solution for
301 // a given problem. However, there is no guarantee of this from one code
302 // version to the next (but the code does not change often).
304
305 // Accessors for the user given data. The implementation will crash if "arc"
306 // is not in [0, NumArcs()) or "node" is not in [0, NumNodes()).
307 NodeIndex NumNodes() const;
308 ArcIndex NumArcs() const;
309 NodeIndex Tail(ArcIndex arc) const;
310 NodeIndex Head(ArcIndex arc) const;
312 FlowQuantity Supply(NodeIndex node) const;
314
315 // Advanced usage. The default is true.
316 //
317 // Without cost scaling, the algorithm will return a 1-optimal solution to the
318 // given problem. The solution will be an optimal solution to a perturbed
319 // problem where some of the arc unit costs are changed by at most 1.
320 //
321 // If the cost are initially integer and we scale them by (num_nodes + 1),
322 // then we can show that such 1-optimal solution is actually optimal. This
323 // is what happen by default or when SetPriceScaling(true) is called.
324 //
325 // However, if your cost were originally double, you don't really care to
326 // solve optimally a problem where the weights are approximated in the first
327 // place. It is better to multiply your double by a scaling_factor (prefer a
328 // power of 2) so that the maximum rounded arc unit cost is under kint64max /
329 // (num_nodes + 1) to prevent any overflow. You can then solve without any
330 // cost scaling. The final result will be the optimal to a problem were the
331 // unit cost of some arc as been changed by at most 1 / scaling_factor.
332 void SetPriceScaling(bool value) { scale_prices_ = value; }
333
334 private:
335 typedef ::util::ReverseArcStaticGraph<NodeIndex, ArcIndex> Graph;
336 enum SupplyAdjustment { ADJUST, DONT_ADJUST };
337
338 // Applies the permutation in arc_permutation_ to the given arc index.
339 ArcIndex PermutedArc(ArcIndex arc);
340 // Solves the problem, potentially applying supply and demand adjustment,
341 // and returns the problem status.
342 Status SolveWithPossibleAdjustment(SupplyAdjustment adjustment);
343 void ResizeNodeVectors(NodeIndex node);
344
345 std::vector<NodeIndex> arc_tail_;
346 std::vector<NodeIndex> arc_head_;
347 std::vector<FlowQuantity> arc_capacity_;
348 std::vector<FlowQuantity> node_supply_;
349 std::vector<CostValue> arc_cost_;
350 std::vector<ArcIndex> arc_permutation_;
351 std::vector<FlowQuantity> arc_flow_;
352 CostValue optimal_cost_;
353 FlowQuantity maximum_flow_;
354
355 bool scale_prices_ = true;
356};
357
358// Generic MinCostFlow that works with StarGraph and all the graphs handling
359// reverse arcs from graph.h, see the end of min_cost_flow.cc for the exact
360// types this class is compiled for.
361//
362// One can greatly decrease memory usage by using appropriately small integer
363// types:
364// - For the Graph<> types, i.e. NodeIndexType and ArcIndexType, see graph.h.
365// - ArcFlowType is used for the *per-arc* flow quantity. It must be signed, and
366// large enough to hold the maximum arc capacity and its negation.
367// - ArcScaledCostType is used for a per-arc scaled cost. It must be signed
368// and large enough to hold the maximum unit cost of an arc times
369// (num_nodes + 1).
370//
371// Note that the latter two are different than FlowQuantity and CostValue, which
372// are used for global, aggregated values and may need to be larger.
373//
374// TODO(user): Avoid using the globally defined type CostValue and FlowQuantity.
375// Also uses the Arc*Type where there is no risk of overflow in more places.
376template <typename Graph, typename ArcFlowType = FlowQuantity,
377 typename ArcScaledCostType = CostValue>
379 public:
380 typedef typename Graph::NodeIndex NodeIndex;
381 typedef typename Graph::ArcIndex ArcIndex;
386
387 // Initialize a MinCostFlow instance on the given graph. The graph does not
388 // need to be fully built yet, but its capacity reservation is used to
389 // initialize the memory of this class.
390 explicit GenericMinCostFlow(const Graph* graph);
391
392#ifndef SWIG
393 // This type is neither copyable nor movable.
396#endif
397
398 // Returns the graph associated to the current object.
399 const Graph* graph() const { return graph_; }
400
401 // Returns the status of last call to Solve(). NOT_SOLVED is returned if
402 // Solve() has never been called or if the problem has been modified in such a
403 // way that the previous solution becomes invalid.
404 Status status() const { return status_; }
405
406 // Sets the supply corresponding to node. A demand is modeled as a negative
407 // supply.
408 void SetNodeSupply(NodeIndex node, FlowQuantity supply);
409
410 // Sets the unit cost for the given arc.
411 void SetArcUnitCost(ArcIndex arc, ArcScaledCostType unit_cost);
412
413 // Sets the capacity for the given arc.
414 void SetArcCapacity(ArcIndex arc, ArcFlowType new_capacity);
415
416 // Sets the flow for the given arc. Note that new_flow must be smaller than
417 // the capacity of the arc.
418 void SetArcFlow(ArcIndex arc, ArcFlowType new_flow);
419
420 // Solves the problem, returning true if a min-cost flow could be found.
421 bool Solve();
422
423 // Checks for feasibility, i.e., that all the supplies and demands can be
424 // matched without exceeding bottlenecks in the network.
425 // If infeasible_supply_node (resp. infeasible_demand_node) are not NULL,
426 // they are populated with the indices of the nodes where the initial supplies
427 // (resp. demands) are too large. Feasible values for the supplies and
428 // demands are accessible through FeasibleSupply.
429 // Note that CheckFeasibility is called by Solve() when the flag
430 // min_cost_flow_check_feasibility is set to true (which is the default.)
431 bool CheckFeasibility(std::vector<NodeIndex>* infeasible_supply_node,
432 std::vector<NodeIndex>* infeasible_demand_node);
433
434 // Makes the min-cost flow problem solvable by truncating supplies and
435 // demands to a level acceptable by the network. There may be several ways to
436 // do it. In our case, the levels are computed from the result of the max-flow
437 // algorithm run in CheckFeasibility().
438 // MakeFeasible returns false if CheckFeasibility() was not called before.
439 bool MakeFeasible();
440
441 // Returns the cost of the minimum-cost flow found by the algorithm. This
442 // works in O(num_arcs). This will only work if the last Solve() call was
443 // successful and returned true, otherwise it will return 0. Note that the
444 // computation might overflow, in which case we will cap the cost at
445 // std::numeric_limits<CostValue>::max().
447
448 // Returns the flow on the given arc using the equations given in the
449 // comment on residual_arc_capacity_.
451
452 // Returns the capacity of the given arc.
454
455 // Returns the unscaled cost for the given arc.
457
458 // Returns the supply at a given node. Demands are modelled as negative
459 // supplies.
460 FlowQuantity Supply(NodeIndex node) const;
461
462 // Returns the initial supply at a given node.
464
465 // Returns the largest supply (if > 0) or largest demand in absolute value
466 // (if < 0) admissible at node. If the problem is not feasible, some of these
467 // values will be smaller (in absolute value) than the initial supplies
468 // and demand given as input.
470
471 // Whether to check the feasibility of the problem with a max-flow, prior to
472 // solving it. This uses about twice as much memory, but detects infeasible
473 // problems (where the flow can't be satisfied) and makes Solve() return
474 // INFEASIBLE. If you disable this check, you will spare memory but you must
475 // make sure that your problem is feasible, otherwise the code can loop
476 // forever.
477 void SetCheckFeasibility(bool value) { check_feasibility_ = value; }
478
479 // Algorithm options.
480 void SetUseUpdatePrices(bool value) { use_price_update_ = value; }
481 void SetPriceScaling(bool value) { scale_prices_ = value; }
482
483 private:
484 // Returns true if the given arc is admissible i.e. if its residual capacity
485 // is strictly positive, and its reduced cost strictly negative, i.e., pushing
486 // more flow into it will result in a reduction of the total cost.
487 bool IsAdmissible(ArcIndex arc) const;
488 bool FastIsAdmissible(ArcIndex arc, CostValue tail_potential) const;
489
490 // Returns true if node is active, i.e., if its supply is positive.
491 bool IsActive(NodeIndex node) const;
492
493 // Returns the reduced cost for a given arc.
494 CostValue ReducedCost(ArcIndex arc) const;
495 CostValue FastReducedCost(ArcIndex arc, CostValue tail_potential) const;
496
497 // Returns the first incident arc of a given node.
498 ArcIndex GetFirstOutgoingOrOppositeIncomingArc(NodeIndex node) const;
499
500 // Checks the consistency of the input, i.e., whether the sum of the supplies
501 // for all nodes is equal to zero. To be used in a DCHECK.
502 bool CheckInputConsistency();
503
504 // Checks whether the result is valid, i.e. whether for each arc,
505 // residual_arc_capacity_[arc] == 0 || ReducedCost(arc) >= -epsilon_.
506 // (A solution is epsilon-optimal if ReducedCost(arc) >= -epsilon.)
507 // To be used in a DCHECK.
508 bool CheckResult() const;
509
510 // Checks the relabel precondition (to be used in a DCHECK):
511 // - The node must be active, or have a 0 excess (relaxation for the Push
512 // Look-Ahead heuristic).
513 // - The node must have no admissible arcs.
514 bool CheckRelabelPrecondition(NodeIndex node) const;
515
516 // Returns context concatenated with information about a given arc
517 // in a human-friendly way.
518 std::string DebugString(absl::string_view context, ArcIndex arc) const;
519
520 // Resets the first_admissible_arc_ array to the first incident arc of each
521 // node.
522 void ResetFirstAdmissibleArcs();
523
524 // Scales the costs, by multiplying them by (graph_->num_nodes() + 1).
525 // Returns false on integer overflow.
526 bool ScaleCosts();
527
528 // Unscales the costs, by dividing them by (graph_->num_nodes() + 1).
529 void UnscaleCosts();
530
531 // Optimizes the cost by dividing epsilon_ by alpha_ and calling Refine().
532 // Returns false on integer overflow.
533 bool Optimize();
534
535 // Saturates the admissible arcs, i.e., push as much flow as possible.
536 void SaturateAdmissibleArcs();
537
538 // Pushes flow on a given arc, i.e., consumes flow on
539 // residual_arc_capacity_[arc], and consumes -flow on
540 // residual_arc_capacity_[Opposite(arc)]. Updates node_excess_ at the tail
541 // and head of the arc accordingly.
542 void PushFlow(FlowQuantity flow, ArcIndex arc);
543 void FastPushFlow(FlowQuantity flow, ArcIndex arc, NodeIndex tail);
544
545 // Initializes the stack active_nodes_.
546 void InitializeActiveNodeStack();
547
548 // Price update heuristics as described in A.V. Goldberg, "An Efficient
549 // Implementation of a Scaling Minimum-Cost Flow Algorithm," Journal of
550 // Algorithms, (1997) 22:1-29
551 // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.258
552 // Returns false on overflow or infeasibility.
553 bool UpdatePrices();
554
555 // Performs an epsilon-optimization step by saturating admissible arcs
556 // and discharging the active nodes.
557 // Returns false on overflow or infeasibility.
558 bool Refine();
559
560 // Discharges an active node by saturating its admissible adjacent arcs,
561 // if any, and by relabelling it when it becomes inactive.
562 // Returns false on overflow or infeasibility.
563 bool Discharge(NodeIndex node);
564
565 // Part of the Push LookAhead heuristic.
566 // Returns true iff the node has admissible arc.
567 bool NodeHasAdmissibleArc(NodeIndex node);
568
569 // Relabels node, i.e., decreases its potential while keeping the
570 // epsilon-optimality of the pseudo flow. See CheckRelabelPrecondition() for
571 // details on the preconditions.
572 // Returns false on overflow or infeasibility.
573 bool Relabel(NodeIndex node);
574
575 // Handy member functions to make the code more compact.
576 NodeIndex Head(ArcIndex arc) const { return graph_->Head(arc); }
577 NodeIndex Tail(ArcIndex arc) const { return graph_->Tail(arc); }
578 ArcIndex Opposite(ArcIndex arc) const;
579 bool IsArcDirect(ArcIndex arc) const;
580 bool IsArcValid(ArcIndex arc) const;
581
582 // Pointer to the graph passed as argument.
583 const Graph* graph_;
584
585 // An array representing the supply (if > 0) or the demand (if < 0)
586 // for each node in graph_.
587 std::vector<FlowQuantity> node_excess_;
588
589 // An array representing the potential (or price function) for
590 // each node in graph_.
591 std::vector<CostValue> node_potential_;
592
593 // An array representing the residual_capacity for each arc in graph_.
594 // Residual capacities enable one to represent the capacity and flow for all
595 // arcs in the graph in the following manner.
596 // For all arcs, residual_arc_capacity_[arc] = capacity[arc] - flow[arc]
597 // Moreover, for reverse arcs, capacity[arc] = 0 by definition.
598 // Also flow[Opposite(arc)] = -flow[arc] by definition.
599 // Therefore:
600 // - for a direct arc:
601 // flow[arc] = 0 - flow[Opposite(arc)]
602 // = capacity[Opposite(arc)] - flow[Opposite(arc)]
603 // = residual_arc_capacity_[Opposite(arc)]
604 // - for a reverse arc:
605 // flow[arc] = -residual_arc_capacity_[arc]
606 // Using these facts enables one to only maintain residual_arc_capacity_,
607 // instead of both capacity and flow, for each direct and indirect arc. This
608 // reduces the amount of memory for this information by a factor 2.
609 // Note that the sum of the largest capacity of an arc in the graph and of
610 // the total flow in the graph mustn't exceed the largest 64 bit integer
611 // to avoid errors. CheckInputConsistency() verifies this constraint.
612 ZVector<ArcFlowType> residual_arc_capacity_;
613
614 // An array representing the first admissible arc for each node in graph_.
615 std::vector<ArcIndex> first_admissible_arc_;
616
617 // A stack used for managing active nodes in the algorithm.
618 // Note that the papers cited above recommend the use of a queue, but
619 // benchmarking so far has not proved it is better.
620 std::stack<NodeIndex> active_nodes_;
621
622 // epsilon_ is the tolerance for optimality.
623 CostValue epsilon_ = 0;
624
625 // alpha_ is the factor by which epsilon_ is divided at each iteration of
626 // Refine().
627 const int64_t alpha_;
628
629 // cost_scaling_factor_ is the scaling factor for cost.
630 CostValue cost_scaling_factor_ = 1;
631
632 // Our node potentials should be >= this at all time.
633 // The first time a potential cross this, BAD_COST_RANGE status is returned.
634 CostValue overflow_threshold_;
635
636 // An array representing the scaled unit cost for each arc in graph_.
637 ZVector<ArcScaledCostType> scaled_arc_unit_cost_;
638
639 // The status of the problem.
640 Status status_ = NOT_SOLVED;
641
642 // An array containing the initial excesses (i.e. the supplies) for each
643 // node. This is used to create the max-flow-based feasibility checker.
644 std::vector<FlowQuantity> initial_node_excess_;
645
646 // An array containing the best acceptable excesses for each of the
647 // nodes. These excesses are imposed by the result of the max-flow-based
648 // feasibility checker for the nodes with an initial supply != 0. For the
649 // other nodes, the excess is simply 0.
650 std::vector<FlowQuantity> feasible_node_excess_;
651
652 // Statistics about this class.
653 StatsGroup stats_;
654
655 // Number of Relabel() since last UpdatePrices().
656 int num_relabels_since_last_price_update_ = 0;
657
658 // A Boolean which is true when feasibility has been checked.
659 bool feasibility_checked_ = false;
660
661 // Whether to use the UpdatePrices() heuristic.
662 bool use_price_update_ = false;
663
664 // Whether to check the problem feasibility with a max-flow.
665 bool check_feasibility_ = false;
666
667 // Whether to scale prices, see SimpleMinCostFlow::SetPriceScaling().
668 bool scale_prices_ = true;
669};
670
671#if !SWIG
672
673// Note: SWIG does not seem to understand explicit template specialization and
674// instantiation declarations.
675
676extern template class GenericMinCostFlow<StarGraph>;
677extern template class GenericMinCostFlow<::util::ReverseArcListGraph<>>;
678extern template class GenericMinCostFlow<::util::ReverseArcStaticGraph<>>;
679extern template class GenericMinCostFlow<::util::ReverseArcMixedGraph<>>;
680extern template class GenericMinCostFlow<
682extern template class GenericMinCostFlow<
684extern template class GenericMinCostFlow<
686 /*ArcFlowType=*/int16_t,
687 /*ArcScaledCostType=*/int32_t>;
688
689// Default MinCostFlow instance that uses StarGraph.
690// New clients should use SimpleMinCostFlow if they can.
691class MinCostFlow : public GenericMinCostFlow<StarGraph> {
692 public:
694};
695
696#endif // SWIG
697
698} // namespace operations_research
699#endif // OR_TOOLS_GRAPH_MIN_COST_FLOW_H_
void SetArcUnitCost(ArcIndex arc, ArcScaledCostType unit_cost)
Sets the unit cost for the given arc.
Graph::OutgoingOrOppositeIncomingArcIterator OutgoingOrOppositeIncomingArcIterator
GenericMinCostFlow & operator=(const GenericMinCostFlow &)=delete
FlowQuantity InitialSupply(NodeIndex node) const
Returns the initial supply at a given node.
bool Solve()
Solves the problem, returning true if a min-cost flow could be found.
Graph::OutgoingArcIterator OutgoingArcIterator
bool CheckFeasibility(std::vector< NodeIndex > *infeasible_supply_node, std::vector< NodeIndex > *infeasible_demand_node)
void SetArcCapacity(ArcIndex arc, ArcFlowType new_capacity)
Sets the capacity for the given arc.
FlowQuantity Capacity(ArcIndex arc) const
Returns the capacity of the given arc.
GenericMinCostFlow(const GenericMinCostFlow &)=delete
This type is neither copyable nor movable.
void SetArcFlow(ArcIndex arc, ArcFlowType new_flow)
FlowQuantity Supply(NodeIndex node) const
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
void SetUseUpdatePrices(bool value)
Algorithm options.
const Graph * graph() const
Returns the graph associated to the current object.
FlowQuantity Flow(ArcIndex arc) const
CostValue UnitCost(ArcIndex arc) const
Returns the unscaled cost for the given arc.
FlowQuantity FeasibleSupply(NodeIndex node) const
MinCostFlow(const StarGraph *graph)
FlowQuantity Supply(NodeIndex node) const
ArcIndex AddArcWithCapacityAndUnitCost(NodeIndex tail, NodeIndex head, FlowQuantity capacity, CostValue unit_cost)
FlowQuantity Capacity(ArcIndex arc) const
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
CostValue UnitCost(ArcIndex arc) const
NodeIndex Tail(ArcIndex arc) const
FlowQuantity Flow(ArcIndex arc) const
SimpleMinCostFlow(const SimpleMinCostFlow &)=delete
This type is neither copyable nor movable.
SimpleMinCostFlow(NodeIndex reserve_num_nodes=0, ArcIndex reserve_num_arcs=0)
SimpleMinCostFlow & operator=(const SimpleMinCostFlow &)=delete
NodeIndex Head(ArcIndex arc) const
NodeIndexType Tail(ArcIndexType arc) const
Definition graph.h:1771
NodeIndexType Head(ArcIndexType arc) const
Definition graph.h:1763
int64_t value
GurobiMPCallbackContext * context
int arc
In SWIG mode, we don't want anything besides these top-level includes.
util::ReverseArcStaticGraph Graph
Type of graph to use.
int head
int tail