24#include "absl/base/attributes.h"
25#include "absl/flags/flag.h"
26#include "absl/log/check.h"
27#include "absl/strings/str_format.h"
28#include "absl/strings/string_view.h"
39 "Divide factor for epsilon at each refine step.");
40ABSL_FLAG(
bool, min_cost_flow_check_feasibility,
true,
41 "Check that the graph has enough capacity to send all supplies "
42 "and serve all demands. Also check that the sum of supplies "
43 "is equal to the sum of demands.");
45 "Check that the result is valid.");
49template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
53 alpha_(
absl::GetFlag(FLAGS_min_cost_flow_alpha)),
54 stats_(
"MinCostFlow"),
55 check_feasibility_(
absl::GetFlag(FLAGS_min_cost_flow_check_feasibility)) {
59 const NodeIndex max_num_nodes = graph_->node_capacity();
60 if (max_num_nodes > 0) {
62 node_potential_.assign(max_num_nodes, 0);
63 node_excess_.assign(max_num_nodes, 0);
64 initial_node_excess_.assign(max_num_nodes, 0);
66 const ArcIndex max_num_arcs = graph_->arc_capacity();
67 if (max_num_arcs > 0) {
68 residual_arc_capacity_.Reserve(-max_num_arcs, max_num_arcs - 1);
69 residual_arc_capacity_.SetAll(0);
70 scaled_arc_unit_cost_.Reserve(-max_num_arcs, max_num_arcs - 1);
71 scaled_arc_unit_cost_.SetAll(0);
75template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
78 DCHECK(graph_->IsNodeValid(node));
79 node_excess_[node] = supply;
80 initial_node_excess_[node] = supply;
82 feasibility_checked_ =
false;
85template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
87 ArcIndex arc, ArcScaledCostType unit_cost) {
88 DCHECK(IsArcDirect(arc));
89 scaled_arc_unit_cost_.Set(arc, unit_cost);
90 scaled_arc_unit_cost_.Set(Opposite(arc), -scaled_arc_unit_cost_[arc]);
92 feasibility_checked_ =
false;
95template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
97 ArcIndex arc, ArcFlowType new_capacity) {
98 DCHECK_LE(0, new_capacity);
99 DCHECK(IsArcDirect(arc));
100 const FlowQuantity free_capacity = residual_arc_capacity_[arc];
102 if (capacity_delta == 0) {
106 feasibility_checked_ =
false;
107 const FlowQuantity new_availability = free_capacity + capacity_delta;
108 if (new_availability >= 0) {
114 DCHECK((capacity_delta > 0) ||
115 (capacity_delta < 0 && new_availability >= 0));
116 residual_arc_capacity_.Set(arc, new_availability);
117 DCHECK_LE(0, residual_arc_capacity_[arc]);
121 const FlowQuantity flow = residual_arc_capacity_[Opposite(arc)];
123 residual_arc_capacity_.Set(arc, 0);
124 residual_arc_capacity_.Set(Opposite(arc), new_capacity);
125 node_excess_[Tail(arc)] += flow_excess;
126 node_excess_[Head(arc)] -= flow_excess;
127 DCHECK_LE(0, residual_arc_capacity_[arc]);
128 DCHECK_LE(0, residual_arc_capacity_[Opposite(arc)]);
132template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
134 ArcScaledCostType>::CheckInputConsistency() {
135 const FlowQuantity kMaxFlow = std::numeric_limits<FlowQuantity>::max();
141 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
144 sum_of_supplies =
CapAdd(sum_of_supplies, excess);
145 if (sum_of_supplies >= kMaxFlow) {
146 status_ = BAD_CAPACITY_RANGE;
147 LOG(ERROR) <<
"Input consistency error: sum of supplies overflow";
150 }
else if (excess < 0) {
151 sum_of_demands =
CapAdd(sum_of_demands, -excess);
152 if (sum_of_demands >= kMaxFlow) {
153 status_ = BAD_CAPACITY_RANGE;
154 LOG(ERROR) <<
"Input consistency error: sum of demands overflow";
159 if (sum_of_supplies != sum_of_demands) {
160 status_ = UNBALANCED;
161 LOG(ERROR) <<
"Input consistency error: unbalanced problem";
165 std::vector<FlowQuantity> max_node_excess = node_excess_;
166 std::vector<FlowQuantity> min_node_excess = node_excess_;
167 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
168 const FlowQuantity capacity = residual_arc_capacity_[arc];
169 CHECK_GE(capacity, 0);
170 if (capacity == 0)
continue;
171 const int tail = graph_->Tail(arc);
172 const int head = graph_->Head(arc);
173 min_node_excess[tail] =
CapSub(min_node_excess[tail], capacity);
174 max_node_excess[head] =
CapAdd(max_node_excess[head], capacity);
177 const int num_nodes = graph_->num_nodes();
178 for (
NodeIndex node = 0; node < num_nodes; ++node) {
179 if (max_node_excess[node] >= kMaxFlow ||
180 min_node_excess[node] <= -kMaxFlow) {
184 if (max_node_excess[node] < std::numeric_limits<ArcFlowType>::max()) {
186 const ArcFlowType upper_bound =
187 std::max<ArcFlowType>(0, max_node_excess[node]);
190 min_node_excess[node] = node_excess_[node];
191 for (OutgoingArcIterator it(*graph_, node); it.Ok(); it.Next()) {
192 const int arc = it.Index();
193 residual_arc_capacity_[arc] =
194 std::min(residual_arc_capacity_[arc], upper_bound);
195 min_node_excess[node] =
196 CapSub(min_node_excess[node], residual_arc_capacity_[arc]);
198 if (min_node_excess[node] > -kMaxFlow)
continue;
200 if (min_node_excess[node] > -std::numeric_limits<ArcFlowType>::max()) {
202 const ArcFlowType upper_bound =
203 std::max<ArcFlowType>(0, -min_node_excess[node]);
206 max_node_excess[node] = node_excess_[node];
207 for (IncomingArcIterator it(*graph_, node); it.Ok(); it.Next()) {
208 const int arc = it.Index();
209 residual_arc_capacity_[arc] =
210 std::min(residual_arc_capacity_[arc], upper_bound);
211 max_node_excess[node] =
212 CapAdd(max_node_excess[node], residual_arc_capacity_[arc]);
214 if (max_node_excess[node] < kMaxFlow)
continue;
217 status_ = BAD_CAPACITY_RANGE;
218 LOG(ERROR) <<
"Maximum in or out flow of node + excess " << node
219 <<
" overflow the FlowQuantity type (int64_t).";
226template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
227bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::CheckResult()
229 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
230 if (node_excess_[node] != 0) {
231 LOG(DFATAL) <<
"node_excess_[" << node <<
"] != 0";
234 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
238 if (residual_arc_capacity_[arc] < 0) {
239 LOG(DFATAL) <<
"residual_arc_capacity_[" << arc <<
"] < 0";
242 if (residual_arc_capacity_[arc] > 0 && ReducedCost(arc) < -epsilon_) {
243 LOG(DFATAL) <<
"residual_arc_capacity_[" << arc
244 <<
"] > 0 && ReducedCost(" << arc <<
") < " << -epsilon_
245 <<
". (epsilon_ = " << epsilon_ <<
").";
249 LOG(DFATAL) << DebugString(
"CheckResult ", arc);
257template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
266 DCHECK_GE(node_excess_[node], 0);
267 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
270 DCHECK(!IsAdmissible(arc)) << DebugString(
"CheckRelabelPrecondition:", arc);
275template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
277GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::DebugString(
278 absl::string_view context,
ArcIndex arc)
const {
284 const CostValue reduced_cost = scaled_arc_unit_cost_[arc] +
285 node_potential_[tail] - node_potential_[head];
286 return absl::StrFormat(
287 "%s Arc %d, from %d to %d, "
288 "Capacity = %d, Residual capacity = %d, "
289 "Flow = residual capacity for reverse arc = %d, "
290 "Height(tail) = %d, Height(head) = %d, "
291 "Excess(tail) = %d, Excess(head) = %d, "
292 "Cost = %d, Reduced cost = %d, ",
293 context, arc, tail, head, Capacity(arc),
294 static_cast<FlowQuantity>(residual_arc_capacity_[arc]), Flow(arc),
295 node_potential_[tail], node_potential_[head], node_excess_[tail],
296 node_excess_[head],
static_cast<CostValue>(scaled_arc_unit_cost_[arc]),
300template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
302 ArcScaledCostType>::CheckFeasibility() {
314 feasibility_checked_ =
false;
316 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
317 if (initial_node_excess_[node] != 0) {
321 const NodeIndex num_nodes_in_max_flow = graph_->num_nodes() + 2;
322 const ArcIndex num_arcs_in_max_flow = graph_->num_arcs() + num_extra_arcs;
323 const NodeIndex source = num_nodes_in_max_flow - 2;
324 const NodeIndex sink = num_nodes_in_max_flow - 1;
325 using CheckerGraph = ::util::ReverseArcListGraph<>;
326 CheckerGraph checker_graph(num_nodes_in_max_flow, num_arcs_in_max_flow);
329 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
331 checker_graph.AddArc(graph_->Tail(arc), graph_->Head(arc));
332 DCHECK_EQ(arc, new_arc);
333 checker.SetArcCapacity(new_arc, Capacity(arc));
338 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
341 const ArcIndex new_arc = checker_graph.AddArc(source, node);
342 checker.SetArcCapacity(new_arc, supply);
343 total_supply += supply;
344 }
else if (supply < 0) {
345 const ArcIndex new_arc = checker_graph.AddArc(node, sink);
346 checker.SetArcCapacity(new_arc, -supply);
347 total_demand -= supply;
350 if (total_supply != total_demand) {
351 LOG(DFATAL) <<
"total_supply(" << total_supply <<
") != total_demand("
352 << total_demand <<
").";
355 if (!checker.Solve()) {
356 LOG(DFATAL) <<
"Max flow could not be computed.";
359 const FlowQuantity optimal_max_flow = checker.GetOptimalFlow();
360 feasibility_checked_ =
true;
361 return optimal_max_flow == total_supply;
364template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
367 if (IsArcDirect(arc)) {
368 return residual_arc_capacity_[Opposite(arc)];
370 return -residual_arc_capacity_[arc];
375template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
378 if (IsArcDirect(arc)) {
379 return residual_arc_capacity_[arc] + residual_arc_capacity_[Opposite(arc)];
385template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
388 DCHECK(IsArcValid(arc));
389 DCHECK_EQ(uint64_t{1}, cost_scaling_factor_);
390 return scaled_arc_unit_cost_[arc];
393template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
396 DCHECK(graph_->IsNodeValid(node));
397 return node_excess_[node];
400template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
401bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsAdmissible(
403 return FastIsAdmissible(arc, node_potential_[Tail(arc)]);
406template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
407bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
409 DCHECK_EQ(node_potential_[Tail(arc)], tail_potential);
410 return residual_arc_capacity_[arc] > 0 &&
411 FastReducedCost(arc, tail_potential) < 0;
414template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
415bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsActive(
417 return node_excess_[node] > 0;
420template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
421auto GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ReducedCost(
423 return FastReducedCost(arc, node_potential_[Tail(arc)]);
426template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
427auto GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastReducedCost(
429 DCHECK_EQ(node_potential_[Tail(arc)], tail_potential);
430 DCHECK(graph_->IsNodeValid(Tail(arc)));
431 DCHECK(graph_->IsNodeValid(Head(arc)));
432 DCHECK_LE(node_potential_[Tail(arc)], 0) << DebugString(
"ReducedCost:", arc);
433 DCHECK_LE(node_potential_[Head(arc)], 0) << DebugString(
"ReducedCost:", arc);
437 return scaled_arc_unit_cost_[arc] + tail_potential -
438 node_potential_[Head(arc)];
441template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
444 OutgoingOrOppositeIncomingArcIterator arc_it(*graph_, node);
445 return arc_it.Index();
448template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
450 if (!CheckInputConsistency()) {
453 if (check_feasibility_ && !CheckFeasibility()) {
459 node_potential_.assign(node_potential_.size(), 0);
461 ResetFirstAdmissibleArcs();
462 if (!ScaleCosts())
return false;
463 if (!Optimize())
return false;
467 if (absl::GetFlag(FLAGS_min_cost_flow_check_result) && !CheckResult()) {
478template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
488 const CostValue kMaxCost = std::numeric_limits<CostValue>::max();
489 const CostValue kMinCost = std::numeric_limits<CostValue>::min();
490 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
491 const CostValue flow_on_arc = residual_arc_capacity_[Opposite(arc)];
493 CapProd(scaled_arc_unit_cost_[arc], flow_on_arc);
494 if (flow_cost == kMaxCost || flow_cost == kMinCost)
return kMaxCost;
495 total_flow_cost =
CapAdd(flow_cost, total_flow_cost);
496 if (total_flow_cost == kMaxCost || total_flow_cost == kMinCost) {
500 return total_flow_cost;
503template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
505 ArcScaledCostType>::ResetFirstAdmissibleArcs() {
506 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
507 first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
511template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
512bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ScaleCosts() {
514 cost_scaling_factor_ = scale_prices_ ? graph_->num_nodes() + 1 : 1;
516 VLOG(3) <<
"Number of nodes in the graph = " << graph_->num_nodes();
517 VLOG(3) <<
"Number of arcs in the graph = " << graph_->num_arcs();
519 std::numeric_limits<CostValue>::max() / (2 * cost_scaling_factor_);
520 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
521 if (scaled_arc_unit_cost_[arc] > threshold ||
522 scaled_arc_unit_cost_[arc] < -threshold) {
523 status_ = BAD_COST_RANGE;
526 const CostValue cost = scaled_arc_unit_cost_[arc] * cost_scaling_factor_;
527 scaled_arc_unit_cost_.Set(arc, cost);
528 scaled_arc_unit_cost_.Set(Opposite(arc), -cost);
535 overflow_threshold_ = std::numeric_limits<CostValue>::min() + epsilon_;
537 VLOG(3) <<
"Initial epsilon = " << epsilon_;
538 VLOG(3) <<
"Cost scaling factor = " << cost_scaling_factor_;
542template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
543void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UnscaleCosts() {
545 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
546 const CostValue cost = scaled_arc_unit_cost_[arc] / cost_scaling_factor_;
547 scaled_arc_unit_cost_.Set(arc, cost);
548 scaled_arc_unit_cost_.Set(Opposite(arc), -cost);
550 cost_scaling_factor_ = 1;
553template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
554bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Optimize() {
556 num_relabels_since_last_price_update_ = 0;
559 epsilon_ = std::max(epsilon_ / alpha_, kEpsilonMin);
560 VLOG(3) <<
"Epsilon changed to: " << epsilon_;
561 if (!Refine())
return false;
562 }
while (epsilon_ != 1LL);
566template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
568 ArcScaledCostType>::SaturateAdmissibleArcs() {
570 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
571 const CostValue tail_potential = node_potential_[node];
572 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
573 first_admissible_arc_[node]);
574 it.Ok(); it.Next()) {
576 if (FastIsAdmissible(arc, tail_potential)) {
577 FastPushFlow(residual_arc_capacity_[arc], arc, node);
591template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
592void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::PushFlow(
595 FastPushFlow(flow, arc, Tail(arc));
598template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
599void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastPushFlow(
602 DCHECK_EQ(Tail(arc), tail);
603 DCHECK_GT(residual_arc_capacity_[arc], 0);
604 DCHECK_LE(flow, residual_arc_capacity_[arc]);
606 residual_arc_capacity_.Set(arc, residual_arc_capacity_[arc] - flow);
608 const ArcIndex opposite = Opposite(arc);
609 residual_arc_capacity_.Set(opposite, residual_arc_capacity_[opposite] + flow);
611 node_excess_[tail] -= flow;
612 node_excess_[Head(arc)] += flow;
615template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
617 ArcScaledCostType>::InitializeActiveNodeStack() {
619 DCHECK(active_nodes_.empty());
620 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
621 if (IsActive(node)) {
622 active_nodes_.push(node);
627template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
628bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UpdatePrices() {
647 const NodeIndex num_nodes = graph_->num_nodes();
648 std::vector<NodeIndex> bfs_queue;
649 std::vector<bool> node_in_queue(num_nodes,
false);
652 const CostValue kMinCostValue = std::numeric_limits<CostValue>::min();
653 std::vector<CostValue> min_non_admissible_potential(num_nodes, kMinCostValue);
654 std::vector<NodeIndex> nodes_to_process;
660 for (
NodeIndex node = 0; node < num_nodes; ++node) {
661 if (node_excess_[node] < 0) {
662 bfs_queue.push_back(node);
663 node_in_queue[node] =
true;
666 remaining_excess -= node_excess_[node];
677 while (remaining_excess > 0) {
682 for (; queue_index < bfs_queue.size(); ++queue_index) {
683 DCHECK_GE(num_nodes, bfs_queue.size());
684 const NodeIndex node = bfs_queue[queue_index];
685 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
688 if (node_in_queue[head])
continue;
689 const ArcIndex opposite_arc = Opposite(it.Index());
690 if (residual_arc_capacity_[opposite_arc] > 0) {
691 node_potential_[head] += potential_delta;
692 if (node_potential_[head] < overflow_threshold_) {
693 status_ = BAD_COST_RANGE;
696 if (ReducedCost(opposite_arc) < 0) {
697 DCHECK(IsAdmissible(opposite_arc));
702 remaining_excess -= node_excess_[head];
703 if (remaining_excess == 0) {
704 node_potential_[head] -= potential_delta;
707 bfs_queue.push_back(head);
708 node_in_queue[head] =
true;
709 if (potential_delta < 0) {
710 first_admissible_arc_[head] =
711 GetFirstOutgoingOrOppositeIncomingArc(head);
716 node_potential_[head] -= potential_delta;
717 if (min_non_admissible_potential[head] == kMinCostValue) {
718 nodes_to_process.push_back(head);
720 min_non_admissible_potential[head] = std::max(
721 min_non_admissible_potential[head],
722 node_potential_[node] - scaled_arc_unit_cost_[opposite_arc]);
726 if (remaining_excess == 0)
break;
728 if (remaining_excess == 0)
break;
732 CostValue max_potential_diff = kMinCostValue;
733 for (
int i = 0;
i < nodes_to_process.size(); ++
i) {
735 if (node_in_queue[node])
continue;
737 std::max(max_potential_diff,
738 min_non_admissible_potential[node] - node_potential_[node]);
739 if (max_potential_diff == potential_delta)
break;
741 DCHECK_LE(max_potential_diff, potential_delta);
742 potential_delta = max_potential_diff - epsilon_;
751 for (
int i = 0;
i < nodes_to_process.size(); ++
i) {
753 if (node_in_queue[node])
continue;
754 if (node_potential_[node] + potential_delta <
755 min_non_admissible_potential[node]) {
756 node_potential_[node] += potential_delta;
757 if (node_potential_[node] < overflow_threshold_) {
758 status_ = BAD_COST_RANGE;
761 first_admissible_arc_[node] =
762 GetFirstOutgoingOrOppositeIncomingArc(node);
763 bfs_queue.push_back(node);
764 node_in_queue[node] =
true;
765 remaining_excess -= node_excess_[node];
770 nodes_to_process[index] = node;
773 nodes_to_process.resize(index);
777 if (potential_delta == 0)
return true;
778 for (
NodeIndex node = 0; node < num_nodes; ++node) {
779 if (!node_in_queue[node]) {
780 node_potential_[node] += potential_delta;
781 if (node_potential_[node] < overflow_threshold_) {
782 status_ = BAD_COST_RANGE;
785 first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
791template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
792bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Refine() {
794 SaturateAdmissibleArcs();
795 InitializeActiveNodeStack();
797 const NodeIndex num_nodes = graph_->num_nodes();
798 while (!active_nodes_.empty()) {
800 if (num_relabels_since_last_price_update_ >= num_nodes) {
801 num_relabels_since_last_price_update_ = 0;
802 if (use_price_update_) {
803 if (!UpdatePrices())
return false;
806 const NodeIndex node = active_nodes_.top();
808 DCHECK(IsActive(node));
809 if (!Discharge(node))
return false;
814template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
815bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Discharge(
821 DCHECK(IsActive(node));
822 const CostValue tail_potential = node_potential_[node];
823 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
824 first_admissible_arc_[node]);
825 it.Ok(); it.Next()) {
827 if (!FastIsAdmissible(arc, tail_potential))
continue;
833 if (node_excess_[head] >= 0 && !NodeHasAdmissibleArc(head)) {
835 if (!Relabel(head))
return false;
836 if (!FastIsAdmissible(arc, tail_potential))
continue;
840 std::min(node_excess_[node],
841 static_cast<FlowQuantity>(residual_arc_capacity_[arc]));
842 const bool head_active_before_push = IsActive(head);
843 FastPushFlow(delta, arc, node);
844 if (IsActive(head) && !head_active_before_push) {
845 active_nodes_.push(head);
848 if (node_excess_[node] == 0) {
850 first_admissible_arc_[node] = arc;
854 if (!Relabel(node))
return false;
858template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
862 const CostValue tail_potential = node_potential_[node];
863 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
864 first_admissible_arc_[node]);
865 it.Ok(); it.Next()) {
867 if (FastIsAdmissible(arc, tail_potential)) {
868 first_admissible_arc_[node] = arc;
876template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
877bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Relabel(
880 DCHECK(CheckRelabelPrecondition(node));
881 ++num_relabels_since_last_price_update_;
888 const CostValue guaranteed_new_potential = node_potential_[node] - epsilon_;
889 if (guaranteed_new_potential < overflow_threshold_) {
890 status_ = BAD_COST_RANGE;
899 const CostValue kMinCostValue = std::numeric_limits<CostValue>::min();
900 CostValue min_non_admissible_potential = kMinCostValue;
905 CostValue previous_min_non_admissible_potential = kMinCostValue;
908 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
911 if (residual_arc_capacity_[arc] > 0) {
912 const CostValue min_non_admissible_potential_for_arc =
913 node_potential_[Head(arc)] - scaled_arc_unit_cost_[arc];
917 if (min_non_admissible_potential_for_arc > guaranteed_new_potential) {
921 node_potential_[node] = guaranteed_new_potential;
922 first_admissible_arc_[node] = arc;
925 if (min_non_admissible_potential_for_arc > min_non_admissible_potential) {
926 previous_min_non_admissible_potential = min_non_admissible_potential;
927 min_non_admissible_potential = min_non_admissible_potential_for_arc;
937 if (min_non_admissible_potential == kMinCostValue) {
938 if (node_excess_[node] != 0) {
948 node_potential_[node] = guaranteed_new_potential;
957 if (min_non_admissible_potential < overflow_threshold_) {
958 status_ = BAD_COST_RANGE;
961 const CostValue new_potential = min_non_admissible_potential - epsilon_;
962 if (new_potential < overflow_threshold_) {
963 status_ = BAD_COST_RANGE;
966 node_potential_[node] = new_potential;
967 if (previous_min_non_admissible_potential <= new_potential) {
968 first_admissible_arc_[node] = first_arc;
971 first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
976template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
978GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Opposite(
980 return graph_->OppositeArc(arc);
983template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
984bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcValid(
986 return graph_->IsArcValid(arc);
989template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
990bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcDirect(
992 DCHECK(IsArcValid(arc));
1004 ::util::ReverseArcStaticGraph<uint16_t, int32_t>>;
1010 ::util::ReverseArcStaticGraph<uint16_t, int32_t>,
1016 if (reserve_num_nodes > 0) {
1017 node_supply_.reserve(reserve_num_nodes);
1019 if (reserve_num_arcs > 0) {
1020 arc_tail_.reserve(reserve_num_arcs);
1021 arc_head_.reserve(reserve_num_arcs);
1022 arc_capacity_.reserve(reserve_num_arcs);
1023 arc_cost_.reserve(reserve_num_arcs);
1024 arc_permutation_.reserve(reserve_num_arcs);
1025 arc_flow_.reserve(reserve_num_arcs);
1030 ResizeNodeVectors(node);
1031 node_supply_[node] = supply;
1037 ResizeNodeVectors(std::max(tail, head));
1038 const ArcIndex arc = arc_tail_.size();
1039 arc_tail_.push_back(tail);
1040 arc_head_.push_back(head);
1041 arc_capacity_.push_back(capacity);
1042 arc_cost_.push_back(unit_cost);
1047 arc_capacity_[arc] = capacity;
1051 return arc < arc_permutation_.size() ? arc_permutation_[arc] : arc;
1055 SupplyAdjustment adjustment) {
1059 const NodeIndex num_nodes = node_supply_.size();
1060 const ArcIndex num_arcs = arc_capacity_.size();
1061 if (num_nodes == 0)
return OPTIMAL;
1063 int supply_node_count = 0, demand_node_count = 0;
1065 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1066 if (node_supply_[node] > 0) {
1067 ++supply_node_count;
1068 total_supply += node_supply_[node];
1069 }
else if (node_supply_[node] < 0) {
1070 ++demand_node_count;
1071 total_demand -= node_supply_[node];
1074 if (adjustment == DONT_ADJUST && total_supply != total_demand) {
1089 const ArcIndex augmented_num_arcs =
1090 num_arcs + supply_node_count + demand_node_count;
1093 const NodeIndex augmented_num_nodes = num_nodes + 2;
1095 Graph graph(augmented_num_nodes, augmented_num_arcs);
1096 for (
ArcIndex arc = 0; arc < num_arcs; ++arc) {
1097 graph.AddArc(arc_tail_[arc], arc_head_[arc]);
1100 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1101 if (node_supply_[node] > 0) {
1102 graph.AddArc(source, node);
1103 }
else if (node_supply_[node] < 0) {
1104 graph.AddArc(node, sink);
1108 graph.Build(&arc_permutation_);
1111 GenericMaxFlow<Graph> max_flow(&graph, source, sink);
1113 for (arc = 0; arc < num_arcs; ++arc) {
1114 max_flow.SetArcCapacity(PermutedArc(arc), arc_capacity_[arc]);
1116 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1117 if (node_supply_[node] != 0) {
1118 max_flow.SetArcCapacity(PermutedArc(arc), std::abs(node_supply_[node]));
1122 CHECK_EQ(arc, augmented_num_arcs);
1123 if (!max_flow.Solve()) {
1124 LOG(ERROR) <<
"Max flow could not be computed.";
1125 switch (max_flow.status()) {
1130 <<
"Max flow failed but claimed to have an optimal solution";
1131 ABSL_FALLTHROUGH_INTENDED;
1136 maximum_flow_ = max_flow.GetOptimalFlow();
1139 if (adjustment == DONT_ADJUST && maximum_flow_ != total_supply) {
1143 GenericMinCostFlow<Graph> min_cost_flow(&graph);
1145 for (arc = 0; arc < num_arcs; ++arc) {
1146 ArcIndex permuted_arc = PermutedArc(arc);
1147 min_cost_flow.SetArcUnitCost(permuted_arc, arc_cost_[arc]);
1148 min_cost_flow.SetArcCapacity(permuted_arc, arc_capacity_[arc]);
1150 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1151 if (node_supply_[node] != 0) {
1152 ArcIndex permuted_arc = PermutedArc(arc);
1153 min_cost_flow.SetArcCapacity(permuted_arc, std::abs(node_supply_[node]));
1154 min_cost_flow.SetArcUnitCost(permuted_arc, 0);
1158 min_cost_flow.SetNodeSupply(source, maximum_flow_);
1159 min_cost_flow.SetNodeSupply(sink, -maximum_flow_);
1160 min_cost_flow.SetCheckFeasibility(
false);
1161 min_cost_flow.SetPriceScaling(scale_prices_);
1163 arc_flow_.resize(num_arcs);
1164 if (min_cost_flow.Solve()) {
1165 optimal_cost_ = min_cost_flow.GetOptimalCost();
1166 for (arc = 0; arc < num_arcs; ++arc) {
1167 arc_flow_[arc] = min_cost_flow.Flow(PermutedArc(arc));
1171 return min_cost_flow.status();
1175 return optimal_cost_;
1179 return maximum_flow_;
1183 return arc_flow_[arc];
1188 return node_supply_.size();
1192 return arc_tail_.size();
1196 return arc_tail_[arc];
1200 return arc_head_[arc];
1205 return arc_capacity_[arc];
1209 return arc_cost_[arc];
1214 return node_supply_[node];
1217void SimpleMinCostFlow::ResizeNodeVectors(
NodeIndex node) {
1218 if (node < node_supply_.size())
return;
1219 node_supply_.resize(node + 1);
FlowQuantity Flow(ArcIndex arc) const
void SetArcUnitCost(ArcIndex arc, ArcScaledCostType unit_cost)
Sets the unit cost for the given arc.
GenericMinCostFlow(const Graph *graph)
bool Solve()
Solves the problem, returning true if a min-cost flow could be found.
void SetArcCapacity(ArcIndex arc, ArcFlowType new_capacity)
Sets the capacity for the given arc.
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
const Graph * graph() const
Returns the graph associated to the current object.
CostValue UnitCost(ArcIndex arc) const
Returns the unscaled cost for the given arc.
FlowQuantity Supply(NodeIndex node) const
Graph::NodeIndex NodeIndex
FlowQuantity Capacity(ArcIndex arc) const
We use the equations given in the comment of residual_arc_capacity_.
CostValue GetOptimalCost()
NodeIndex Tail(ArcIndex arc) const
CostValue OptimalCost() const
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
void SetArcCapacity(ArcIndex arc, FlowQuantity capacity)
FlowQuantity Flow(ArcIndex arc) const
FlowQuantity Capacity(ArcIndex arc) const
CostValue UnitCost(ArcIndex arc) const
NodeIndex NumNodes() const
ArcIndex AddArcWithCapacityAndUnitCost(NodeIndex tail, NodeIndex head, FlowQuantity capacity, CostValue unit_cost)
FlowQuantity MaximumFlow() const
NodeIndex Head(ArcIndex arc) const
SimpleMinCostFlow(NodeIndex reserve_num_nodes=0, ArcIndex reserve_num_arcs=0)
FlowQuantity Supply(NodeIndex node) const
static constexpr bool kHasNegativeReverseArcs
static const int32_t kNilArc
ABSL_FLAG(int64_t, min_cost_flow_alpha, 5, "Divide factor for epsilon at each refine step.")
In SWIG mode, we don't want anything besides these top-level includes.
int64_t CapAdd(int64_t x, int64_t y)
@ INFEASIBLE
A solution could not be found.
int64_t CapSub(int64_t x, int64_t y)
int64_t CapProd(int64_t x, int64_t y)
util::ReverseArcStaticGraph Graph
Type of graph to use.
#define IF_STATS_ENABLED(instructions)
#define SCOPED_TIME_STAT(stats)