OR-Tools  8.0
min_cost_flow.cc
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 
15 
16 #include <algorithm>
17 #include <cmath>
18 #include <limits>
19 
20 #include "absl/strings/str_format.h"
22 #include "ortools/base/mathutil.h"
23 #include "ortools/graph/graph.h"
24 #include "ortools/graph/graphs.h"
25 #include "ortools/graph/max_flow.h"
26 
27 // TODO(user): Remove these flags and expose the parameters in the API.
28 // New clients, please do not use these flags!
29 DEFINE_int64(min_cost_flow_alpha, 5,
30  "Divide factor for epsilon at each refine step.");
31 DEFINE_bool(min_cost_flow_check_feasibility, true,
32  "Check that the graph has enough capacity to send all supplies "
33  "and serve all demands. Also check that the sum of supplies "
34  "is equal to the sum of demands.");
35 DEFINE_bool(min_cost_flow_check_balance, true,
36  "Check that the sum of supplies is equal to the sum of demands.");
37 DEFINE_bool(min_cost_flow_check_costs, true,
38  "Check that the magnitude of the costs will not exceed the "
39  "precision of the machine when scaled (multiplied) by the number "
40  "of nodes");
41 DEFINE_bool(min_cost_flow_check_result, true,
42  "Check that the result is valid.");
43 
44 namespace operations_research {
45 
46 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
48  const Graph* graph)
49  : graph_(graph),
50  node_excess_(),
51  node_potential_(),
52  residual_arc_capacity_(),
53  first_admissible_arc_(),
54  active_nodes_(),
55  epsilon_(0),
56  alpha_(FLAGS_min_cost_flow_alpha),
57  cost_scaling_factor_(1),
58  scaled_arc_unit_cost_(),
59  total_flow_cost_(0),
60  status_(NOT_SOLVED),
61  initial_node_excess_(),
62  feasible_node_excess_(),
63  stats_("MinCostFlow"),
64  feasibility_checked_(false),
65  use_price_update_(false),
66  check_feasibility_(FLAGS_min_cost_flow_check_feasibility) {
67  const NodeIndex max_num_nodes = Graphs<Graph>::NodeReservation(*graph_);
68  if (max_num_nodes > 0) {
69  node_excess_.Reserve(0, max_num_nodes - 1);
70  node_excess_.SetAll(0);
71  node_potential_.Reserve(0, max_num_nodes - 1);
72  node_potential_.SetAll(0);
73  first_admissible_arc_.Reserve(0, max_num_nodes - 1);
74  first_admissible_arc_.SetAll(Graph::kNilArc);
75  initial_node_excess_.Reserve(0, max_num_nodes - 1);
76  initial_node_excess_.SetAll(0);
77  feasible_node_excess_.Reserve(0, max_num_nodes - 1);
78  feasible_node_excess_.SetAll(0);
79  }
80  const ArcIndex max_num_arcs = Graphs<Graph>::ArcReservation(*graph_);
81  if (max_num_arcs > 0) {
82  residual_arc_capacity_.Reserve(-max_num_arcs, max_num_arcs - 1);
83  residual_arc_capacity_.SetAll(0);
84  scaled_arc_unit_cost_.Reserve(-max_num_arcs, max_num_arcs - 1);
85  scaled_arc_unit_cost_.SetAll(0);
86  }
87 }
88 
89 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
91  NodeIndex node, FlowQuantity supply) {
92  DCHECK(graph_->IsNodeValid(node));
93  node_excess_.Set(node, supply);
94  initial_node_excess_.Set(node, supply);
95  status_ = NOT_SOLVED;
96  feasibility_checked_ = false;
97 }
98 
99 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
101  ArcIndex arc, ArcScaledCostType unit_cost) {
102  DCHECK(IsArcDirect(arc));
103  scaled_arc_unit_cost_.Set(arc, unit_cost);
104  scaled_arc_unit_cost_.Set(Opposite(arc), -scaled_arc_unit_cost_[arc]);
105  status_ = NOT_SOLVED;
106  feasibility_checked_ = false;
107 }
108 
109 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
111  ArcIndex arc, ArcFlowType new_capacity) {
112  DCHECK_LE(0, new_capacity);
113  DCHECK(IsArcDirect(arc));
114  const FlowQuantity free_capacity = residual_arc_capacity_[arc];
115  const FlowQuantity capacity_delta = new_capacity - Capacity(arc);
116  if (capacity_delta == 0) {
117  return; // Nothing to do.
118  }
119  status_ = NOT_SOLVED;
120  feasibility_checked_ = false;
121  const FlowQuantity new_availability = free_capacity + capacity_delta;
122  if (new_availability >= 0) {
123  // The above condition is true when one of two following holds:
124  // 1/ (capacity_delta > 0), meaning we are increasing the capacity
125  // 2/ (capacity_delta < 0 && free_capacity + capacity_delta >= 0)
126  // meaning we are reducing the capacity, but that the capacity
127  // reduction is not larger than the free capacity.
128  DCHECK((capacity_delta > 0) ||
129  (capacity_delta < 0 && new_availability >= 0));
130  residual_arc_capacity_.Set(arc, new_availability);
131  DCHECK_LE(0, residual_arc_capacity_[arc]);
132  } else {
133  // We have to reduce the flow on the arc, and update the excesses
134  // accordingly.
135  const FlowQuantity flow = residual_arc_capacity_[Opposite(arc)];
136  const FlowQuantity flow_excess = flow - new_capacity;
137  residual_arc_capacity_.Set(arc, 0);
138  residual_arc_capacity_.Set(Opposite(arc), new_capacity);
139  const NodeIndex tail = Tail(arc);
140  node_excess_.Set(tail, node_excess_[tail] + flow_excess);
141  const NodeIndex head = Head(arc);
142  node_excess_.Set(head, node_excess_[head] - flow_excess);
143  DCHECK_LE(0, residual_arc_capacity_[arc]);
144  DCHECK_LE(0, residual_arc_capacity_[Opposite(arc)]);
145  }
146 }
147 
148 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
150  ArcIndex arc, ArcFlowType new_flow) {
151  DCHECK(IsArcValid(arc));
152  const FlowQuantity capacity = Capacity(arc);
153  DCHECK_GE(capacity, new_flow);
154  residual_arc_capacity_.Set(Opposite(arc), new_flow);
155  residual_arc_capacity_.Set(arc, capacity - new_flow);
156  status_ = NOT_SOLVED;
157  feasibility_checked_ = false;
158 }
159 
160 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
161 bool GenericMinCostFlow<Graph, ArcFlowType,
162  ArcScaledCostType>::CheckInputConsistency() const {
163  FlowQuantity total_supply = 0;
164  uint64 max_capacity = 0; // uint64 because it is positive and will be used
165  // to check against FlowQuantity overflows.
166  for (ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
167  const uint64 capacity = static_cast<uint64>(residual_arc_capacity_[arc]);
168  max_capacity = std::max(capacity, max_capacity);
169  }
170  uint64 total_flow = 0; // uint64 for the same reason as max_capacity.
171  for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
172  const FlowQuantity excess = node_excess_[node];
173  total_supply += excess;
174  if (excess > 0) {
175  total_flow += excess;
177  max_capacity + total_flow) {
178  LOG(DFATAL) << "Input consistency error: max capacity + flow exceed "
179  << "precision";
180  return false;
181  }
182  }
183  }
184  if (total_supply != 0) {
185  LOG(DFATAL) << "Input consistency error: unbalanced problem";
186  return false;
187  }
188  return true;
189 }
190 
191 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
192 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::CheckResult()
193  const {
194  for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
195  if (node_excess_[node] != 0) {
196  LOG(DFATAL) << "node_excess_[" << node << "] != 0";
197  return false;
198  }
199  for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
200  it.Next()) {
201  const ArcIndex arc = it.Index();
202  bool ok = true;
203  if (residual_arc_capacity_[arc] < 0) {
204  LOG(DFATAL) << "residual_arc_capacity_[" << arc << "] < 0";
205  ok = false;
206  }
207  if (residual_arc_capacity_[arc] > 0 && ReducedCost(arc) < -epsilon_) {
208  LOG(DFATAL) << "residual_arc_capacity_[" << arc
209  << "] > 0 && ReducedCost(" << arc << ") < " << -epsilon_
210  << ". (epsilon_ = " << epsilon_ << ").";
211  ok = false;
212  }
213  if (!ok) {
214  LOG(DFATAL) << DebugString("CheckResult ", arc);
215  return false;
216  }
217  }
218  }
219  return true;
220 }
221 
222 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
223 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::CheckCostRange()
224  const {
225  CostValue min_cost_magnitude = std::numeric_limits<CostValue>::max();
226  CostValue max_cost_magnitude = 0;
227  // Traverse the initial arcs of the graph:
228  for (ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
229  const CostValue cost_magnitude = MathUtil::Abs(scaled_arc_unit_cost_[arc]);
230  max_cost_magnitude = std::max(max_cost_magnitude, cost_magnitude);
231  if (cost_magnitude != 0.0) {
232  min_cost_magnitude = std::min(min_cost_magnitude, cost_magnitude);
233  }
234  }
235  VLOG(3) << "Min cost magnitude = " << min_cost_magnitude
236  << ", Max cost magnitude = " << max_cost_magnitude;
237 #if !defined(_MSC_VER)
239  log(max_cost_magnitude + 1) + log(graph_->num_nodes() + 1)) {
240  LOG(DFATAL) << "Maximum cost magnitude " << max_cost_magnitude << " is too "
241  << "high for the number of nodes. Try changing the data.";
242  return false;
243  }
244 #endif
245  return true;
246 }
247 
248 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
249 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
250  CheckRelabelPrecondition(NodeIndex node) const {
251  // Note that the classical Relabel precondition assumes IsActive(node), i.e.,
252  // the node_excess_[node] > 0. However, to implement the Push Look-Ahead
253  // heuristic, we can relax this condition as explained in the section 4.3 of
254  // the article "An Efficient Implementation of a Scaling Minimum-Cost Flow
255  // Algorithm", A.V. Goldberg, Journal of Algorithms 22(1), January 1997, pp.
256  // 1-29.
257  DCHECK_GE(node_excess_[node], 0);
258  for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
259  it.Next()) {
260  const ArcIndex arc = it.Index();
261  DCHECK(!IsAdmissible(arc)) << DebugString("CheckRelabelPrecondition:", arc);
262  }
263  return true;
264 }
265 
266 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
267 std::string
268 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::DebugString(
269  const std::string& context, ArcIndex arc) const {
270  const NodeIndex tail = Tail(arc);
271  const NodeIndex head = Head(arc);
272  // Reduced cost is computed directly without calling ReducedCost to avoid
273  // recursive calls between ReducedCost and DebugString in case a DCHECK in
274  // ReducedCost fails.
275  const CostValue reduced_cost = scaled_arc_unit_cost_[arc] +
276  node_potential_[tail] - node_potential_[head];
277  return absl::StrFormat(
278  "%s Arc %d, from %d to %d, "
279  "Capacity = %d, Residual capacity = %d, "
280  "Flow = residual capacity for reverse arc = %d, "
281  "Height(tail) = %d, Height(head) = %d, "
282  "Excess(tail) = %d, Excess(head) = %d, "
283  "Cost = %d, Reduced cost = %d, ",
284  context, arc, tail, head, Capacity(arc),
285  static_cast<FlowQuantity>(residual_arc_capacity_[arc]), Flow(arc),
286  node_potential_[tail], node_potential_[head], node_excess_[tail],
287  node_excess_[head], static_cast<CostValue>(scaled_arc_unit_cost_[arc]),
288  reduced_cost);
289 }
290 
291 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
293  CheckFeasibility(std::vector<NodeIndex>* const infeasible_supply_node,
294  std::vector<NodeIndex>* const infeasible_demand_node) {
295  SCOPED_TIME_STAT(&stats_);
296  // Create a new graph, which is a copy of graph_, with the following
297  // modifications:
298  // Two nodes are added: a source and a sink.
299  // The source is linked to each supply node (whose supply > 0) by an arc whose
300  // capacity is equal to the supply at the supply node.
301  // The sink is linked to each demand node (whose supply < 0) by an arc whose
302  // capacity is the demand (-supply) at the demand node.
303  // There are no supplies or demands or costs in the graph, as we will run
304  // max-flow.
305  // TODO(user): make it possible to share a graph by MaxFlow and MinCostFlow.
306  // For this it is necessary to make StarGraph resizable.
307  feasibility_checked_ = false;
308  ArcIndex num_extra_arcs = 0;
309  for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
310  if (initial_node_excess_[node] != 0) {
311  ++num_extra_arcs;
312  }
313  }
314  const NodeIndex num_nodes_in_max_flow = graph_->num_nodes() + 2;
315  const ArcIndex num_arcs_in_max_flow = graph_->num_arcs() + num_extra_arcs;
316  const NodeIndex source = num_nodes_in_max_flow - 2;
317  const NodeIndex sink = num_nodes_in_max_flow - 1;
318  StarGraph checker_graph(num_nodes_in_max_flow, num_arcs_in_max_flow);
319  MaxFlow checker(&checker_graph, source, sink);
320  checker.SetCheckInput(false);
321  checker.SetCheckResult(false);
322  // Copy graph_ to checker_graph.
323  for (ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
324  const ArcIndex new_arc =
325  checker_graph.AddArc(graph_->Tail(arc), graph_->Head(arc));
326  DCHECK_EQ(arc, new_arc);
327  checker.SetArcCapacity(new_arc, Capacity(arc));
328  }
329  FlowQuantity total_demand = 0;
330  FlowQuantity total_supply = 0;
331  // Create the source-to-supply node arcs and the demand-node-to-sink arcs.
332  for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
333  const FlowQuantity supply = initial_node_excess_[node];
334  if (supply > 0) {
335  const ArcIndex new_arc = checker_graph.AddArc(source, node);
336  checker.SetArcCapacity(new_arc, supply);
337  total_supply += supply;
338  } else if (supply < 0) {
339  const ArcIndex new_arc = checker_graph.AddArc(node, sink);
340  checker.SetArcCapacity(new_arc, -supply);
341  total_demand -= supply;
342  }
343  }
344  if (total_supply != total_demand) {
345  LOG(DFATAL) << "total_supply(" << total_supply << ") != total_demand("
346  << total_demand << ").";
347  return false;
348  }
349  if (!checker.Solve()) {
350  LOG(DFATAL) << "Max flow could not be computed.";
351  return false;
352  }
353  const FlowQuantity optimal_max_flow = checker.GetOptimalFlow();
354  feasible_node_excess_.SetAll(0);
355  for (StarGraph::OutgoingArcIterator it(checker_graph, source); it.Ok();
356  it.Next()) {
357  const ArcIndex arc = it.Index();
358  const NodeIndex node = checker_graph.Head(arc);
359  const FlowQuantity flow = checker.Flow(arc);
360  feasible_node_excess_.Set(node, flow);
361  if (infeasible_supply_node != nullptr) {
362  infeasible_supply_node->push_back(node);
363  }
364  }
365  for (StarGraph::IncomingArcIterator it(checker_graph, sink); it.Ok();
366  it.Next()) {
367  const ArcIndex arc = it.Index();
368  const NodeIndex node = checker_graph.Tail(arc);
369  const FlowQuantity flow = checker.Flow(arc);
370  feasible_node_excess_.Set(node, -flow);
371  if (infeasible_demand_node != nullptr) {
372  infeasible_demand_node->push_back(node);
373  }
374  }
375  feasibility_checked_ = true;
376  return optimal_max_flow == total_supply;
377 }
378 
379 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
381  if (!feasibility_checked_) {
382  return false;
383  }
384  for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
385  const FlowQuantity excess = feasible_node_excess_[node];
386  node_excess_.Set(node, excess);
387  initial_node_excess_.Set(node, excess);
388  }
389  return true;
390 }
391 
392 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
394  ArcIndex arc) const {
395  if (IsArcDirect(arc)) {
396  return residual_arc_capacity_[Opposite(arc)];
397  } else {
398  return -residual_arc_capacity_[arc];
399  }
400 }
401 
402 // We use the equations given in the comment of residual_arc_capacity_.
403 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
406  ArcIndex arc) const {
407  if (IsArcDirect(arc)) {
408  return residual_arc_capacity_[arc] + residual_arc_capacity_[Opposite(arc)];
409  } else {
410  return 0;
411  }
412 }
413 
414 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
416  ArcIndex arc) const {
417  DCHECK(IsArcValid(arc));
418  DCHECK_EQ(uint64{1}, cost_scaling_factor_);
419  return scaled_arc_unit_cost_[arc];
420 }
421 
422 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
424  NodeIndex node) const {
425  DCHECK(graph_->IsNodeValid(node));
426  return node_excess_[node];
427 }
428 
429 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
432  NodeIndex node) const {
433  return initial_node_excess_[node];
434 }
435 
436 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
439  NodeIndex node) const {
440  return feasible_node_excess_[node];
441 }
442 
443 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
445  ArcIndex arc) const {
446  return FastIsAdmissible(arc, node_potential_[Tail(arc)]);
447 }
448 
449 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
450 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
451  FastIsAdmissible(ArcIndex arc, CostValue tail_potential) const {
452  DCHECK_EQ(node_potential_[Tail(arc)], tail_potential);
453  return residual_arc_capacity_[arc] > 0 &&
454  FastReducedCost(arc, tail_potential) < 0;
455 }
456 
457 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
458 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsActive(
459  NodeIndex node) const {
460  return node_excess_[node] > 0;
461 }
462 
463 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
464 CostValue
465 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ReducedCost(
466  ArcIndex arc) const {
467  return FastReducedCost(arc, node_potential_[Tail(arc)]);
468 }
469 
470 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
471 CostValue
472 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastReducedCost(
473  ArcIndex arc, CostValue tail_potential) const {
474  DCHECK_EQ(node_potential_[Tail(arc)], tail_potential);
475  DCHECK(graph_->IsNodeValid(Tail(arc)));
476  DCHECK(graph_->IsNodeValid(Head(arc)));
477  DCHECK_LE(node_potential_[Tail(arc)], 0) << DebugString("ReducedCost:", arc);
478  DCHECK_LE(node_potential_[Head(arc)], 0) << DebugString("ReducedCost:", arc);
479  return scaled_arc_unit_cost_[arc] + tail_potential -
480  node_potential_[Head(arc)];
481 }
482 
483 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
485 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
486  GetFirstOutgoingOrOppositeIncomingArc(NodeIndex node) const {
487  OutgoingOrOppositeIncomingArcIterator arc_it(*graph_, node);
488  return arc_it.Index();
489 }
490 
491 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
493  status_ = NOT_SOLVED;
494  if (FLAGS_min_cost_flow_check_balance && !CheckInputConsistency()) {
495  status_ = UNBALANCED;
496  return false;
497  }
498  if (FLAGS_min_cost_flow_check_costs && !CheckCostRange()) {
499  status_ = BAD_COST_RANGE;
500  return false;
501  }
502  if (check_feasibility_ && !CheckFeasibility(nullptr, nullptr)) {
503  status_ = INFEASIBLE;
504  return false;
505  }
506  node_potential_.SetAll(0);
507  ResetFirstAdmissibleArcs();
508  ScaleCosts();
509  Optimize();
510  if (FLAGS_min_cost_flow_check_result && !CheckResult()) {
511  status_ = BAD_RESULT;
512  UnscaleCosts();
513  return false;
514  }
515  UnscaleCosts();
516  if (status_ != OPTIMAL) {
517  LOG(DFATAL) << "Status != OPTIMAL";
518  total_flow_cost_ = 0;
519  return false;
520  }
521  total_flow_cost_ = 0;
522  for (ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
523  const FlowQuantity flow_on_arc = residual_arc_capacity_[Opposite(arc)];
524  total_flow_cost_ += scaled_arc_unit_cost_[arc] * flow_on_arc;
525  }
526  status_ = OPTIMAL;
527  IF_STATS_ENABLED(VLOG(1) << stats_.StatString());
528  return true;
529 }
530 
531 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
532 void GenericMinCostFlow<Graph, ArcFlowType,
533  ArcScaledCostType>::ResetFirstAdmissibleArcs() {
534  for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
535  first_admissible_arc_.Set(node,
536  GetFirstOutgoingOrOppositeIncomingArc(node));
537  }
538 }
539 
540 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
541 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ScaleCosts() {
542  SCOPED_TIME_STAT(&stats_);
543  cost_scaling_factor_ = graph_->num_nodes() + 1;
544  epsilon_ = 1LL;
545  VLOG(3) << "Number of nodes in the graph = " << graph_->num_nodes();
546  VLOG(3) << "Number of arcs in the graph = " << graph_->num_arcs();
547  for (ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
548  const CostValue cost = scaled_arc_unit_cost_[arc] * cost_scaling_factor_;
549  scaled_arc_unit_cost_.Set(arc, cost);
550  scaled_arc_unit_cost_.Set(Opposite(arc), -cost);
551  epsilon_ = std::max(epsilon_, MathUtil::Abs(cost));
552  }
553  VLOG(3) << "Initial epsilon = " << epsilon_;
554  VLOG(3) << "Cost scaling factor = " << cost_scaling_factor_;
555 }
556 
557 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
558 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UnscaleCosts() {
559  SCOPED_TIME_STAT(&stats_);
560  for (ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
561  const CostValue cost = scaled_arc_unit_cost_[arc] / cost_scaling_factor_;
562  scaled_arc_unit_cost_.Set(arc, cost);
563  scaled_arc_unit_cost_.Set(Opposite(arc), -cost);
564  }
565  cost_scaling_factor_ = 1;
566 }
567 
568 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
569 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Optimize() {
570  const CostValue kEpsilonMin = 1LL;
571  num_relabels_since_last_price_update_ = 0;
572  do {
573  // Avoid epsilon_ == 0.
574  epsilon_ = std::max(epsilon_ / alpha_, kEpsilonMin);
575  VLOG(3) << "Epsilon changed to: " << epsilon_;
576  Refine();
577  } while (epsilon_ != 1LL && status_ != INFEASIBLE);
578  if (status_ == NOT_SOLVED) {
579  status_ = OPTIMAL;
580  }
581 }
582 
583 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
584 void GenericMinCostFlow<Graph, ArcFlowType,
585  ArcScaledCostType>::SaturateAdmissibleArcs() {
586  SCOPED_TIME_STAT(&stats_);
587  for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
588  const CostValue tail_potential = node_potential_[node];
589  for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
590  first_admissible_arc_[node]);
591  it.Ok(); it.Next()) {
592  const ArcIndex arc = it.Index();
593  if (FastIsAdmissible(arc, tail_potential)) {
594  FastPushFlow(residual_arc_capacity_[arc], arc, node);
595  }
596  }
597 
598  // We just saturated all the admissible arcs, so there are no arcs with a
599  // positive residual capacity that are incident to the current node.
600  // Moreover, during the course of the algorithm, if the residual capacity of
601  // such an arc becomes positive again, then the arc is still not admissible
602  // until we relabel the node (because the reverse arc was admissible for
603  // this to happen). In conclusion, the optimization below is correct.
604  first_admissible_arc_[node] = Graph::kNilArc;
605  }
606 }
607 
608 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
609 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::PushFlow(
610  FlowQuantity flow, ArcIndex arc) {
611  SCOPED_TIME_STAT(&stats_);
612  FastPushFlow(flow, arc, Tail(arc));
613 }
614 
615 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
616 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastPushFlow(
617  FlowQuantity flow, ArcIndex arc, NodeIndex tail) {
618  SCOPED_TIME_STAT(&stats_);
619  DCHECK_EQ(Tail(arc), tail);
620  DCHECK_GT(residual_arc_capacity_[arc], 0);
621  DCHECK_LE(flow, residual_arc_capacity_[arc]);
622  // Reduce the residual capacity on the arc by flow.
623  residual_arc_capacity_.Set(arc, residual_arc_capacity_[arc] - flow);
624  // Increase the residual capacity on the opposite arc by flow.
625  const ArcIndex opposite = Opposite(arc);
626  residual_arc_capacity_.Set(opposite, residual_arc_capacity_[opposite] + flow);
627  // Update the excesses at the tail and head of the arc.
628  node_excess_.Set(tail, node_excess_[tail] - flow);
629  const NodeIndex head = Head(arc);
630  node_excess_.Set(head, node_excess_[head] + flow);
631 }
632 
633 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
634 void GenericMinCostFlow<Graph, ArcFlowType,
635  ArcScaledCostType>::InitializeActiveNodeStack() {
636  SCOPED_TIME_STAT(&stats_);
637  DCHECK(active_nodes_.empty());
638  for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
639  if (IsActive(node)) {
640  active_nodes_.push(node);
641  }
642  }
643 }
644 
645 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
646 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UpdatePrices() {
647  SCOPED_TIME_STAT(&stats_);
648 
649  // The algorithm works as follows. Start with a set of nodes S containing all
650  // the nodes with negative excess. Expand the set along reverse admissible
651  // arcs. If at the end, the complement of S contains at least one node with
652  // positive excess, relabel all the nodes in the complement of S by
653  // subtracting epsilon from their current potential. See the paper cited in
654  // the .h file.
655  //
656  // After this relabeling is done, the heuristic is reapplied by extending S as
657  // much as possible, relabeling the complement of S, and so on until there is
658  // no node with positive excess that is not in S. Note that this is not
659  // described in the paper.
660  //
661  // Note(user): The triggering mechanism of this UpdatePrices() is really
662  // important; if it is not done properly it may degrade performance!
663 
664  // This represents the set S.
665  const NodeIndex num_nodes = graph_->num_nodes();
666  std::vector<NodeIndex> bfs_queue;
667  std::vector<bool> node_in_queue(num_nodes, false);
668 
669  // This is used to update the potential of the nodes not in S.
670  const CostValue kMinCostValue = std::numeric_limits<CostValue>::min();
671  std::vector<CostValue> min_non_admissible_potential(num_nodes, kMinCostValue);
672  std::vector<NodeIndex> nodes_to_process;
673 
674  // Sum of the positive excesses out of S, used for early exit.
675  FlowQuantity remaining_excess = 0;
676 
677  // First consider the nodes which have a negative excess.
678  for (NodeIndex node = 0; node < num_nodes; ++node) {
679  if (node_excess_[node] < 0) {
680  bfs_queue.push_back(node);
681  node_in_queue[node] = true;
682 
683  // This uses the fact that the sum of excesses is always 0.
684  remaining_excess -= node_excess_[node];
685  }
686  }
687 
688  // All the nodes not yet in the bfs_queue will have their potential changed by
689  // +potential_delta (which becomes more and more negative at each pass). This
690  // update is applied when a node is pushed into the queue and at the end of
691  // the function for the nodes that are still unprocessed.
692  CostValue potential_delta = 0;
693 
694  int queue_index = 0;
695  while (remaining_excess > 0) {
696  // Reverse BFS that expands S as much as possible in the reverse admissible
697  // graph. Once S cannot be expanded anymore, perform a relabeling on the
698  // nodes not in S but that can reach it in one arc and try to expand S
699  // again.
700  for (; queue_index < bfs_queue.size(); ++queue_index) {
701  DCHECK_GE(num_nodes, bfs_queue.size());
702  const NodeIndex node = bfs_queue[queue_index];
703  for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
704  it.Next()) {
705  const NodeIndex head = Head(it.Index());
706  if (node_in_queue[head]) continue;
707  const ArcIndex opposite_arc = Opposite(it.Index());
708  if (residual_arc_capacity_[opposite_arc] > 0) {
709  node_potential_[head] += potential_delta;
710  if (ReducedCost(opposite_arc) < 0) {
711  DCHECK(IsAdmissible(opposite_arc));
712 
713  // TODO(user): Try to steal flow if node_excess_[head] > 0.
714  // An initial experiment didn't show a big speedup though.
715 
716  remaining_excess -= node_excess_[head];
717  if (remaining_excess == 0) {
718  node_potential_[head] -= potential_delta;
719  break;
720  }
721  bfs_queue.push_back(head);
722  node_in_queue[head] = true;
723  if (potential_delta < 0) {
724  first_admissible_arc_[head] =
725  GetFirstOutgoingOrOppositeIncomingArc(head);
726  }
727  } else {
728  // The opposite_arc is not admissible but is in the residual graph;
729  // this updates its min_non_admissible_potential.
730  node_potential_[head] -= potential_delta;
731  if (min_non_admissible_potential[head] == kMinCostValue) {
732  nodes_to_process.push_back(head);
733  }
734  min_non_admissible_potential[head] = std::max(
735  min_non_admissible_potential[head],
736  node_potential_[node] - scaled_arc_unit_cost_[opposite_arc]);
737  }
738  }
739  }
740  if (remaining_excess == 0) break;
741  }
742  if (remaining_excess == 0) break;
743 
744  // Decrease by as much as possible instead of decreasing by epsilon.
745  // TODO(user): Is it worth the extra loop?
746  CostValue max_potential_diff = kMinCostValue;
747  for (int i = 0; i < nodes_to_process.size(); ++i) {
748  const NodeIndex node = nodes_to_process[i];
749  if (node_in_queue[node]) continue;
750  max_potential_diff =
751  std::max(max_potential_diff,
752  min_non_admissible_potential[node] - node_potential_[node]);
753  if (max_potential_diff == potential_delta) break;
754  }
755  DCHECK_LE(max_potential_diff, potential_delta);
756  potential_delta = max_potential_diff - epsilon_;
757 
758  // Loop over nodes_to_process_ and for each node, apply the first of the
759  // rules below that match or leave it in the queue for later iteration:
760  // - Remove it if it is already in the queue.
761  // - If the node is connected to S by an admissible arc after it is
762  // relabeled by +potential_delta, add it to bfs_queue_ and remove it from
763  // nodes_to_process.
764  int index = 0;
765  for (int i = 0; i < nodes_to_process.size(); ++i) {
766  const NodeIndex node = nodes_to_process[i];
767  if (node_in_queue[node]) continue;
768  if (node_potential_[node] + potential_delta <
769  min_non_admissible_potential[node]) {
770  node_potential_[node] += potential_delta;
771  first_admissible_arc_[node] =
772  GetFirstOutgoingOrOppositeIncomingArc(node);
773  bfs_queue.push_back(node);
774  node_in_queue[node] = true;
775  remaining_excess -= node_excess_[node];
776  continue;
777  }
778 
779  // Keep the node for later iteration.
780  nodes_to_process[index] = node;
781  ++index;
782  }
783  nodes_to_process.resize(index);
784  }
785 
786  // Update the potentials of the nodes not yet processed.
787  if (potential_delta == 0) return;
788  for (NodeIndex node = 0; node < num_nodes; ++node) {
789  if (!node_in_queue[node]) {
790  node_potential_[node] += potential_delta;
791  first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
792  }
793  }
794 }
795 
796 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
797 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Refine() {
798  SCOPED_TIME_STAT(&stats_);
799  SaturateAdmissibleArcs();
800  InitializeActiveNodeStack();
801 
802  const NodeIndex num_nodes = graph_->num_nodes();
803  while (status_ != INFEASIBLE && !active_nodes_.empty()) {
804  // TODO(user): Experiment with different factors in front of num_nodes.
805  if (num_relabels_since_last_price_update_ >= num_nodes) {
806  num_relabels_since_last_price_update_ = 0;
807  if (use_price_update_) {
808  UpdatePrices();
809  }
810  }
811  const NodeIndex node = active_nodes_.top();
812  active_nodes_.pop();
813  DCHECK(IsActive(node));
814  Discharge(node);
815  }
816 }
817 
818 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
819 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Discharge(
820  NodeIndex node) {
821  SCOPED_TIME_STAT(&stats_);
822  do {
823  // The node is initially active, and we exit as soon as it becomes
824  // inactive.
825  DCHECK(IsActive(node));
826  const CostValue tail_potential = node_potential_[node];
827  for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
828  first_admissible_arc_[node]);
829  it.Ok(); it.Next()) {
830  const ArcIndex arc = it.Index();
831  if (FastIsAdmissible(arc, tail_potential)) {
832  const NodeIndex head = Head(arc);
833  if (!LookAhead(arc, tail_potential, head)) continue;
834  const bool head_active_before_push = IsActive(head);
835  const FlowQuantity delta =
836  std::min(node_excess_[node],
837  static_cast<FlowQuantity>(residual_arc_capacity_[arc]));
838  FastPushFlow(delta, arc, node);
839  if (IsActive(head) && !head_active_before_push) {
840  active_nodes_.push(head);
841  }
842  if (node_excess_[node] == 0) {
843  // arc may still be admissible.
844  first_admissible_arc_.Set(node, arc);
845  return;
846  }
847  }
848  }
849  Relabel(node);
850  } while (status_ != INFEASIBLE);
851 }
852 
853 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
854 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::LookAhead(
855  ArcIndex in_arc, CostValue in_tail_potential, NodeIndex node) {
856  SCOPED_TIME_STAT(&stats_);
857  DCHECK_EQ(Head(in_arc), node);
858  DCHECK_EQ(node_potential_[Tail(in_arc)], in_tail_potential);
859  if (node_excess_[node] < 0) return true;
860  const CostValue tail_potential = node_potential_[node];
861  for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
862  first_admissible_arc_[node]);
863  it.Ok(); it.Next()) {
864  const ArcIndex arc = it.Index();
865  if (FastIsAdmissible(arc, tail_potential)) {
866  first_admissible_arc_.Set(node, arc);
867  return true;
868  }
869  }
870 
871  // The node we looked ahead has no admissible arc at its current potential.
872  // We relabel it and return true if the original arc is still admissible.
873  Relabel(node);
874  return FastIsAdmissible(in_arc, in_tail_potential);
875 }
876 
877 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
878 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Relabel(
879  NodeIndex node) {
880  SCOPED_TIME_STAT(&stats_);
881  DCHECK(CheckRelabelPrecondition(node));
882  ++num_relabels_since_last_price_update_;
883 
884  // By setting node_potential_[node] to the guaranteed_new_potential we are
885  // sure to keep epsilon-optimality of the pseudo-flow. Note that we could
886  // return right away with this value, but we prefer to check that this value
887  // will lead to at least one admissible arc, and if not, to decrease the
888  // potential as much as possible.
889  const CostValue guaranteed_new_potential = node_potential_[node] - epsilon_;
890 
891  // This will be updated to contain the minimum node potential for which
892  // the node has no admissible arc. We know that:
893  // - min_non_admissible_potential <= node_potential_[node]
894  // - We can set the new node potential to min_non_admissible_potential -
895  // epsilon_ and still keep the epsilon-optimality of the pseudo flow.
896  const CostValue kMinCostValue = std::numeric_limits<CostValue>::min();
897  CostValue min_non_admissible_potential = kMinCostValue;
898 
899  // The following variables help setting the first_admissible_arc_[node] to a
900  // value different from GetFirstOutgoingOrOppositeIncomingArc(node) which
901  // avoids looking again at some arcs.
902  CostValue previous_min_non_admissible_potential = kMinCostValue;
903  ArcIndex first_arc = Graph::kNilArc;
904 
905  for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
906  it.Next()) {
907  const ArcIndex arc = it.Index();
908  if (residual_arc_capacity_[arc] > 0) {
909  const CostValue min_non_admissible_potential_for_arc =
910  node_potential_[Head(arc)] - scaled_arc_unit_cost_[arc];
911  if (min_non_admissible_potential_for_arc > min_non_admissible_potential) {
912  if (min_non_admissible_potential_for_arc > guaranteed_new_potential) {
913  // We found an admissible arc for the guaranteed_new_potential. We
914  // stop right now instead of trying to compute the minimum possible
915  // new potential that keeps the epsilon-optimality of the pseudo flow.
916  node_potential_.Set(node, guaranteed_new_potential);
917  first_admissible_arc_.Set(node, arc);
918  return;
919  }
920  previous_min_non_admissible_potential = min_non_admissible_potential;
921  min_non_admissible_potential = min_non_admissible_potential_for_arc;
922  first_arc = arc;
923  }
924  }
925  }
926 
927  // No admissible arc leaves this node!
928  if (min_non_admissible_potential == kMinCostValue) {
929  if (node_excess_[node] != 0) {
930  // Note that this infeasibility detection is incomplete.
931  // Only max flow can detect that a min-cost flow problem is infeasible.
932  status_ = INFEASIBLE;
933  LOG(ERROR) << "Infeasible problem.";
934  } else {
935  // This source saturates all its arcs, we can actually decrease the
936  // potential by as much as we want.
937  // TODO(user): Set it to a minimum value, but be careful of overflow.
938  node_potential_.Set(node, guaranteed_new_potential);
939  first_admissible_arc_.Set(node,
940  GetFirstOutgoingOrOppositeIncomingArc(node));
941  }
942  return;
943  }
944 
945  // We decrease the potential as much as possible, but we do not know the first
946  // admissible arc (most of the time). Keeping the
947  // previous_min_non_admissible_potential makes it faster by a few percent.
948  const CostValue new_potential = min_non_admissible_potential - epsilon_;
949  node_potential_.Set(node, new_potential);
950  if (previous_min_non_admissible_potential <= new_potential) {
951  first_admissible_arc_.Set(node, first_arc);
952  } else {
953  // We have no indication of what may be the first admissible arc.
954  first_admissible_arc_.Set(node,
955  GetFirstOutgoingOrOppositeIncomingArc(node));
956  }
957 }
958 
959 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
960 typename Graph::ArcIndex
961 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Opposite(
962  ArcIndex arc) const {
963  return Graphs<Graph>::OppositeArc(*graph_, arc);
964 }
965 
966 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
967 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcValid(
968  ArcIndex arc) const {
969  return Graphs<Graph>::IsArcValid(*graph_, arc);
970 }
971 
972 template <typename Graph, typename ArcFlowType, typename ArcScaledCostType>
973 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcDirect(
974  ArcIndex arc) const {
975  DCHECK(IsArcValid(arc));
976  return arc >= 0;
977 }
978 
979 // Explicit instantiations that can be used by a client.
980 //
981 // TODO(user): Move this code out of a .cc file and include it at the end of
982 // the header so it can work with any graph implementation?
983 template class GenericMinCostFlow<StarGraph>;
984 template class GenericMinCostFlow<::util::ReverseArcListGraph<>>;
985 template class GenericMinCostFlow<::util::ReverseArcStaticGraph<>>;
986 template class GenericMinCostFlow<::util::ReverseArcMixedGraph<>>;
987 template class GenericMinCostFlow<::util::ReverseArcStaticGraph<uint16, int32>>;
988 
989 // A more memory-efficient version for large graphs.
990 template class GenericMinCostFlow<::util::ReverseArcStaticGraph<uint16, int32>,
991  /*ArcFlowType=*/int16,
992  /*ArcScaledCostType=*/int32>;
993 
995  ArcIndex reserve_num_arcs) {
996  if (reserve_num_nodes > 0) {
997  node_supply_.reserve(reserve_num_nodes);
998  }
999  if (reserve_num_arcs > 0) {
1000  arc_tail_.reserve(reserve_num_arcs);
1001  arc_head_.reserve(reserve_num_arcs);
1002  arc_capacity_.reserve(reserve_num_arcs);
1003  arc_cost_.reserve(reserve_num_arcs);
1004  arc_permutation_.reserve(reserve_num_arcs);
1005  arc_flow_.reserve(reserve_num_arcs);
1006  }
1007 }
1008 
1010  ResizeNodeVectors(node);
1011  node_supply_[node] = supply;
1012 }
1013 
1015  NodeIndex head,
1017  CostValue unit_cost) {
1018  ResizeNodeVectors(std::max(tail, head));
1019  const ArcIndex arc = arc_tail_.size();
1020  arc_tail_.push_back(tail);
1021  arc_head_.push_back(head);
1022  arc_capacity_.push_back(capacity);
1023  arc_cost_.push_back(unit_cost);
1024  return arc;
1025 }
1026 
1027 ArcIndex SimpleMinCostFlow::PermutedArc(ArcIndex arc) {
1028  return arc < arc_permutation_.size() ? arc_permutation_[arc] : arc;
1029 }
1030 
1031 SimpleMinCostFlow::Status SimpleMinCostFlow::SolveWithPossibleAdjustment(
1032  SupplyAdjustment adjustment) {
1033  optimal_cost_ = 0;
1034  maximum_flow_ = 0;
1035  arc_flow_.clear();
1036  const NodeIndex num_nodes = node_supply_.size();
1037  const ArcIndex num_arcs = arc_capacity_.size();
1038  if (num_nodes == 0) return OPTIMAL;
1039 
1040  int supply_node_count = 0, demand_node_count = 0;
1041  FlowQuantity total_supply = 0, total_demand = 0;
1042  for (NodeIndex node = 0; node < num_nodes; ++node) {
1043  if (node_supply_[node] > 0) {
1044  ++supply_node_count;
1045  total_supply += node_supply_[node];
1046  } else if (node_supply_[node] < 0) {
1047  ++demand_node_count;
1048  total_demand -= node_supply_[node];
1049  }
1050  }
1051  if (adjustment == DONT_ADJUST && total_supply != total_demand) {
1052  return UNBALANCED;
1053  }
1054 
1055  // Feasibility checking, and possible supply/demand adjustment, is done by:
1056  // 1. Creating a new source and sink node.
1057  // 2. Taking all nodes that have a non-zero supply or demand and
1058  // connecting them to the source or sink respectively. The arc thus
1059  // added has a capacity of the supply or demand.
1060  // 3. Computing the max flow between the new source and sink.
1061  // 4. If adjustment isn't being done, checking that the max flow is equal
1062  // to the total supply/demand (and returning INFEASIBLE if it isn't).
1063  // 5. Running min-cost max-flow on this augmented graph, using the max
1064  // flow computed in step 3 as the supply of the source and demand of
1065  // the sink.
1066  const ArcIndex augmented_num_arcs =
1067  num_arcs + supply_node_count + demand_node_count;
1068  const NodeIndex source = num_nodes;
1069  const NodeIndex sink = num_nodes + 1;
1070  const NodeIndex augmented_num_nodes = num_nodes + 2;
1071 
1072  Graph graph(augmented_num_nodes, augmented_num_arcs);
1073  for (ArcIndex arc = 0; arc < num_arcs; ++arc) {
1074  graph.AddArc(arc_tail_[arc], arc_head_[arc]);
1075  }
1076 
1077  for (NodeIndex node = 0; node < num_nodes; ++node) {
1078  if (node_supply_[node] > 0) {
1079  graph.AddArc(source, node);
1080  } else if (node_supply_[node] < 0) {
1081  graph.AddArc(node, sink);
1082  }
1083  }
1084 
1085  graph.Build(&arc_permutation_);
1086 
1087  {
1088  GenericMaxFlow<Graph> max_flow(&graph, source, sink);
1089  ArcIndex arc;
1090  for (arc = 0; arc < num_arcs; ++arc) {
1091  max_flow.SetArcCapacity(PermutedArc(arc), arc_capacity_[arc]);
1092  }
1093  for (NodeIndex node = 0; node < num_nodes; ++node) {
1094  if (node_supply_[node] != 0) {
1095  max_flow.SetArcCapacity(PermutedArc(arc), std::abs(node_supply_[node]));
1096  ++arc;
1097  }
1098  }
1099  CHECK_EQ(arc, augmented_num_arcs);
1100  if (!max_flow.Solve()) {
1101  LOG(ERROR) << "Max flow could not be computed.";
1102  switch (max_flow.status()) {
1104  return NOT_SOLVED;
1106  LOG(ERROR)
1107  << "Max flow failed but claimed to have an optimal solution";
1108  ABSL_FALLTHROUGH_INTENDED;
1109  default:
1110  return BAD_RESULT;
1111  }
1112  }
1113  maximum_flow_ = max_flow.GetOptimalFlow();
1114  }
1115 
1116  if (adjustment == DONT_ADJUST && maximum_flow_ != total_supply) {
1117  return INFEASIBLE;
1118  }
1119 
1120  GenericMinCostFlow<Graph> min_cost_flow(&graph);
1121  ArcIndex arc;
1122  for (arc = 0; arc < num_arcs; ++arc) {
1123  ArcIndex permuted_arc = PermutedArc(arc);
1124  min_cost_flow.SetArcUnitCost(permuted_arc, arc_cost_[arc]);
1125  min_cost_flow.SetArcCapacity(permuted_arc, arc_capacity_[arc]);
1126  }
1127  for (NodeIndex node = 0; node < num_nodes; ++node) {
1128  if (node_supply_[node] != 0) {
1129  ArcIndex permuted_arc = PermutedArc(arc);
1130  min_cost_flow.SetArcCapacity(permuted_arc, std::abs(node_supply_[node]));
1131  min_cost_flow.SetArcUnitCost(permuted_arc, 0);
1132  ++arc;
1133  }
1134  }
1135  min_cost_flow.SetNodeSupply(source, maximum_flow_);
1136  min_cost_flow.SetNodeSupply(sink, -maximum_flow_);
1137  min_cost_flow.SetCheckFeasibility(false);
1138 
1139  arc_flow_.resize(num_arcs);
1140  if (min_cost_flow.Solve()) {
1141  optimal_cost_ = min_cost_flow.GetOptimalCost();
1142  for (arc = 0; arc < num_arcs; ++arc) {
1143  arc_flow_[arc] = min_cost_flow.Flow(PermutedArc(arc));
1144  }
1145  }
1146  return min_cost_flow.status();
1147 }
1148 
1149 CostValue SimpleMinCostFlow::OptimalCost() const { return optimal_cost_; }
1150 
1151 FlowQuantity SimpleMinCostFlow::MaximumFlow() const { return maximum_flow_; }
1152 
1154  return arc_flow_[arc];
1155 }
1156 
1157 NodeIndex SimpleMinCostFlow::NumNodes() const { return node_supply_.size(); }
1158 
1159 ArcIndex SimpleMinCostFlow::NumArcs() const { return arc_tail_.size(); }
1160 
1161 ArcIndex SimpleMinCostFlow::Tail(ArcIndex arc) const { return arc_tail_[arc]; }
1162 
1163 ArcIndex SimpleMinCostFlow::Head(ArcIndex arc) const { return arc_head_[arc]; }
1164 
1166  return arc_capacity_[arc];
1167 }
1168 
1170  return arc_cost_[arc];
1171 }
1172 
1174  return node_supply_[node];
1175 }
1176 
1177 void SimpleMinCostFlow::ResizeNodeVectors(NodeIndex node) {
1178  if (node < node_supply_.size()) return;
1179  node_supply_.resize(node + 1);
1180 }
1181 
1182 } // namespace operations_research
operations_research::SimpleMinCostFlow::Tail
NodeIndex Tail(ArcIndex arc) const
Definition: min_cost_flow.cc:1161
tail
int64 tail
Definition: routing_flow.cc:127
operations_research::GenericMinCostFlow::Flow
FlowQuantity Flow(ArcIndex arc) const
Definition: min_cost_flow.cc:393
min
int64 min
Definition: alldiff_cst.cc:138
operations_research::GenericMaxFlow::Flow
FlowQuantity Flow(ArcIndex arc) const
Definition: max_flow.h:365
operations_research::GenericMinCostFlow::InitialSupply
FlowQuantity InitialSupply(NodeIndex node) const
Definition: min_cost_flow.cc:431
max
int64 max
Definition: alldiff_cst.cc:139
IF_STATS_ENABLED
#define IF_STATS_ENABLED(instructions)
Definition: stats.h:430
operations_research::ZVector::Reserve
bool Reserve(int64 new_min_index, int64 new_max_index)
Definition: zvector.h:98
operations_research::EbertGraph::Tail
NodeIndexType Tail(const ArcIndexType arc) const
Definition: ebert_graph.h:1376
operations_research::NodeIndex
int32 NodeIndex
Definition: ebert_graph.h:192
operations_research::SimpleMinCostFlow::NumArcs
ArcIndex NumArcs() const
Definition: min_cost_flow.cc:1159
operations_research::SimpleMinCostFlow::NumNodes
NodeIndex NumNodes() const
Definition: min_cost_flow.cc:1157
DEFINE_int64
DEFINE_int64(min_cost_flow_alpha, 5, "Divide factor for epsilon at each refine step.")
util::Graph
ListGraph Graph
Definition: graph.h:2354
operations_research::SimpleMinCostFlow::SimpleMinCostFlow
SimpleMinCostFlow(NodeIndex reserve_num_nodes=0, ArcIndex reserve_num_arcs=0)
Definition: min_cost_flow.cc:994
operations_research::SimpleMinCostFlow::MaximumFlow
FlowQuantity MaximumFlow() const
Definition: min_cost_flow.cc:1151
DEFINE_bool
DEFINE_bool(min_cost_flow_check_feasibility, true, "Check that the graph has enough capacity to send all supplies " "and serve all demands. Also check that the sum of supplies " "is equal to the sum of demands.")
operations_research::GenericMinCostFlow::MakeFeasible
bool MakeFeasible()
Definition: min_cost_flow.cc:380
operations_research::GenericMinCostFlow::UnitCost
CostValue UnitCost(ArcIndex arc) const
Definition: min_cost_flow.cc:415
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::GenericMaxFlow::Solve
bool Solve()
Definition: max_flow.cc:334
operations_research::GenericMinCostFlow::ArcIndex
Graph::ArcIndex ArcIndex
Definition: min_cost_flow.h:329
operations_research::GenericMinCostFlow::SetArcCapacity
void SetArcCapacity(ArcIndex arc, ArcFlowType new_capacity)
Definition: min_cost_flow.cc:110
operations_research::GenericMinCostFlow::NodeIndex
Graph::NodeIndex NodeIndex
Definition: min_cost_flow.h:328
operations_research::SimpleMinCostFlow::UnitCost
CostValue UnitCost(ArcIndex arc) const
Definition: min_cost_flow.cc:1169
operations_research::GenericMinCostFlow::GenericMinCostFlow
GenericMinCostFlow(const Graph *graph)
Definition: min_cost_flow.cc:47
operations_research::MinCostFlowBase::OPTIMAL
@ OPTIMAL
Definition: min_cost_flow.h:196
index
int index
Definition: pack.cc:508
int32
int int32
Definition: integral_types.h:33
context
GurobiMPCallbackContext * context
Definition: gurobi_interface.cc:439
operations_research::Graphs::ArcReservation
static ArcIndex ArcReservation(const Graph &graph)
Definition: graphs.h:39
SCOPED_TIME_STAT
#define SCOPED_TIME_STAT(stats)
Definition: stats.h:431
cost
int64 cost
Definition: routing_flow.cc:130
min_cost_flow.h
operations_research::sat::INFEASIBLE
@ INFEASIBLE
Definition: cp_model.pb.h:231
operations_research::GenericMaxFlow::SetCheckResult
void SetCheckResult(bool value)
Definition: max_flow.h:420
operations_research::GenericMinCostFlow::SetArcUnitCost
void SetArcUnitCost(ArcIndex arc, ArcScaledCostType unit_cost)
Definition: min_cost_flow.cc:100
operations_research::MinCostFlowBase::BAD_RESULT
@ BAD_RESULT
Definition: min_cost_flow.h:200
operations_research::MaxFlowStatusClass::NOT_SOLVED
@ NOT_SOLVED
Definition: max_flow.h:303
operations_research::FlowQuantity
int64 FlowQuantity
Definition: ebert_graph.h:202
operations_research::CostValue
int64 CostValue
Definition: ebert_graph.h:203
operations_research::EbertGraph
Definition: ebert_graph.h:188
mathutil.h
operations_research::GenericMinCostFlow::FeasibleSupply
FlowQuantity FeasibleSupply(NodeIndex node) const
Definition: min_cost_flow.cc:438
operations_research::GenericMinCostFlow::Solve
bool Solve()
Definition: min_cost_flow.cc:492
operations_research::SimpleMinCostFlow::Flow
FlowQuantity Flow(ArcIndex arc) const
Definition: min_cost_flow.cc:1153
operations_research::MaxFlow
Definition: max_flow.h:652
operations_research::SimpleMinCostFlow::Capacity
FlowQuantity Capacity(ArcIndex arc) const
Definition: min_cost_flow.cc:1165
operations_research::sat::OPTIMAL
@ OPTIMAL
Definition: cp_model.pb.h:232
operations_research::GenericMinCostFlow::SetArcFlow
void SetArcFlow(ArcIndex arc, ArcFlowType new_flow)
Definition: min_cost_flow.cc:149
uint64
uint64_t uint64
Definition: integral_types.h:39
operations_research::ArcIndex
int32 ArcIndex
Definition: ebert_graph.h:201
int16
short int16
Definition: integral_types.h:32
max_flow.h
graph.h
operations_research::SimpleMinCostFlow::AddArcWithCapacityAndUnitCost
ArcIndex AddArcWithCapacityAndUnitCost(NodeIndex tail, NodeIndex head, FlowQuantity capacity, CostValue unit_cost)
Definition: min_cost_flow.cc:1014
operations_research::GenericMinCostFlow
Definition: min_cost_flow.h:188
operations_research::ZVector::SetAll
void SetAll(T value)
Definition: zvector.h:133
operations_research::SimpleMinCostFlow::OptimalCost
CostValue OptimalCost() const
Definition: min_cost_flow.cc:1149
operations_research::Graphs::NodeReservation
static NodeIndex NodeReservation(const Graph &graph)
Definition: graphs.h:36
operations_research::MathUtil::Abs
static T Abs(const T x)
Definition: mathutil.h:95
operations_research::MinCostFlowBase::NOT_SOLVED
@ NOT_SOLVED
Definition: min_cost_flow.h:195
delta
int64 delta
Definition: resource.cc:1684
operations_research::GenericMinCostFlow::Capacity
FlowQuantity Capacity(ArcIndex arc) const
Definition: min_cost_flow.cc:405
operations_research::SimpleMinCostFlow::Supply
FlowQuantity Supply(NodeIndex node) const
Definition: min_cost_flow.cc:1173
capacity
int64 capacity
Definition: routing_flow.cc:129
operations_research::MinCostFlowBase::INFEASIBLE
@ INFEASIBLE
Definition: min_cost_flow.h:198
operations_research::GenericMinCostFlow::SetNodeSupply
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
Definition: min_cost_flow.cc:90
operations_research::GenericMinCostFlow::Supply
FlowQuantity Supply(NodeIndex node) const
Definition: min_cost_flow.cc:423
operations_research::SimpleMinCostFlow::SetNodeSupply
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
Definition: min_cost_flow.cc:1009
operations_research::GenericMaxFlow::GetOptimalFlow
FlowQuantity GetOptimalFlow() const
Definition: max_flow.h:361
operations_research::MaxFlowStatusClass::OPTIMAL
@ OPTIMAL
Definition: max_flow.h:304
head
int64 head
Definition: routing_flow.cc:128
operations_research::Graphs::IsArcValid
static bool IsArcValid(const Graph &graph, ArcIndex arc)
Definition: graphs.h:33
operations_research::SimpleMinCostFlow::Head
NodeIndex Head(ArcIndex arc) const
Definition: min_cost_flow.cc:1163
operations_research::MinCostFlowBase::UNBALANCED
@ UNBALANCED
Definition: min_cost_flow.h:199
operations_research::GenericMaxFlow::SetArcCapacity
void SetArcCapacity(ArcIndex arc, FlowQuantity new_capacity)
Definition: max_flow.cc:175
operations_research::Graphs::OppositeArc
static ArcIndex OppositeArc(const Graph &graph, ArcIndex arc)
Definition: graphs.h:30
commandlineflags.h
operations_research::GenericMinCostFlow::CheckFeasibility
bool CheckFeasibility(std::vector< NodeIndex > *const infeasible_supply_node, std::vector< NodeIndex > *const infeasible_demand_node)
Definition: min_cost_flow.cc:293
operations_research::GenericMaxFlow::SetCheckInput
void SetCheckInput(bool value)
Definition: max_flow.h:419
operations_research::MinCostFlowBase::Status
Status
Definition: min_cost_flow.h:194
graphs.h