21 #include "absl/strings/str_format.h" 30 ABSL_FLAG(int64_t, min_cost_flow_alpha, 5,
31 "Divide factor for epsilon at each refine step.");
32 ABSL_FLAG(
bool, min_cost_flow_check_feasibility,
true,
33 "Check that the graph has enough capacity to send all supplies " 34 "and serve all demands. Also check that the sum of supplies " 35 "is equal to the sum of demands.");
36 ABSL_FLAG(
bool, min_cost_flow_check_balance,
true,
37 "Check that the sum of supplies is equal to the sum of demands.");
38 ABSL_FLAG(
bool, min_cost_flow_check_costs,
true,
39 "Check that the magnitude of the costs will not exceed the " 40 "precision of the machine when scaled (multiplied) by the number " 42 ABSL_FLAG(
bool, min_cost_flow_check_result,
true,
43 "Check that the result is valid.");
47 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
53 residual_arc_capacity_(),
54 first_admissible_arc_(),
57 alpha_(
absl::GetFlag(FLAGS_min_cost_flow_alpha)),
58 cost_scaling_factor_(1),
59 scaled_arc_unit_cost_(),
62 initial_node_excess_(),
63 feasible_node_excess_(),
64 stats_(
"MinCostFlow"),
65 feasibility_checked_(false),
66 use_price_update_(false),
67 check_feasibility_(
absl::GetFlag(FLAGS_min_cost_flow_check_feasibility)) {
69 if (max_num_nodes > 0) {
70 node_excess_.Reserve(0, max_num_nodes - 1);
71 node_excess_.SetAll(0);
72 node_potential_.Reserve(0, max_num_nodes - 1);
73 node_potential_.SetAll(0);
74 first_admissible_arc_.Reserve(0, max_num_nodes - 1);
75 first_admissible_arc_.SetAll(Graph::kNilArc);
76 initial_node_excess_.Reserve(0, max_num_nodes - 1);
77 initial_node_excess_.SetAll(0);
78 feasible_node_excess_.Reserve(0, max_num_nodes - 1);
79 feasible_node_excess_.SetAll(0);
82 if (max_num_arcs > 0) {
83 residual_arc_capacity_.Reserve(-max_num_arcs, max_num_arcs - 1);
84 residual_arc_capacity_.SetAll(0);
85 scaled_arc_unit_cost_.Reserve(-max_num_arcs, max_num_arcs - 1);
86 scaled_arc_unit_cost_.SetAll(0);
90 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
93 DCHECK(graph_->IsNodeValid(node));
94 node_excess_.Set(node, supply);
95 initial_node_excess_.Set(node, supply);
97 feasibility_checked_ =
false;
100 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
102 ArcIndex arc, ArcScaledCostType unit_cost) {
104 scaled_arc_unit_cost_.Set(arc, unit_cost);
105 scaled_arc_unit_cost_.Set(Opposite(arc), -scaled_arc_unit_cost_[arc]);
106 status_ = NOT_SOLVED;
107 feasibility_checked_ =
false;
110 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
112 ArcIndex arc, ArcFlowType new_capacity) {
115 const FlowQuantity free_capacity = residual_arc_capacity_[arc];
116 const FlowQuantity capacity_delta = new_capacity - Capacity(arc);
117 if (capacity_delta == 0) {
120 status_ = NOT_SOLVED;
121 feasibility_checked_ =
false;
122 const FlowQuantity new_availability = free_capacity + capacity_delta;
123 if (new_availability >= 0) {
129 DCHECK((capacity_delta > 0) ||
130 (capacity_delta < 0 && new_availability >= 0));
131 residual_arc_capacity_.Set(arc, new_availability);
132 DCHECK_LE(0, residual_arc_capacity_[arc]);
136 const FlowQuantity flow = residual_arc_capacity_[Opposite(arc)];
138 residual_arc_capacity_.Set(arc, 0);
139 residual_arc_capacity_.Set(Opposite(arc), new_capacity);
141 node_excess_.Set(
tail, node_excess_[
tail] + flow_excess);
143 node_excess_.Set(
head, node_excess_[
head] - flow_excess);
144 DCHECK_LE(0, residual_arc_capacity_[arc]);
145 DCHECK_LE(0, residual_arc_capacity_[Opposite(arc)]);
149 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
151 ArcIndex arc, ArcFlowType new_flow) {
155 residual_arc_capacity_.Set(Opposite(arc), new_flow);
156 residual_arc_capacity_.Set(arc,
capacity - new_flow);
157 status_ = NOT_SOLVED;
158 feasibility_checked_ =
false;
161 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
163 ArcScaledCostType>::CheckInputConsistency()
const {
165 uint64_t max_capacity = 0;
167 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
169 static_cast<uint64_t>(residual_arc_capacity_[arc]);
172 uint64_t total_flow = 0;
173 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
175 total_supply += excess;
177 total_flow += excess;
179 max_capacity + total_flow) {
180 LOG(DFATAL) <<
"Input consistency error: max capacity + flow exceed " 186 if (total_supply != 0) {
187 LOG(DFATAL) <<
"Input consistency error: unbalanced problem";
193 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
194 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::CheckResult()
196 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
197 if (node_excess_[node] != 0) {
198 LOG(DFATAL) <<
"node_excess_[" << node <<
"] != 0";
201 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
205 if (residual_arc_capacity_[arc] < 0) {
206 LOG(DFATAL) <<
"residual_arc_capacity_[" << arc <<
"] < 0";
209 if (residual_arc_capacity_[arc] > 0 && ReducedCost(arc) < -epsilon_) {
210 LOG(DFATAL) <<
"residual_arc_capacity_[" << arc
211 <<
"] > 0 && ReducedCost(" << arc <<
") < " << -epsilon_
212 <<
". (epsilon_ = " << epsilon_ <<
").";
216 LOG(DFATAL) << DebugString(
"CheckResult ", arc);
224 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
225 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::CheckCostRange()
230 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
231 const CostValue cost_magnitude = MathUtil::Abs(scaled_arc_unit_cost_[arc]);
232 max_cost_magnitude =
std::max(max_cost_magnitude, cost_magnitude);
233 if (cost_magnitude != 0.0) {
234 min_cost_magnitude =
std::min(min_cost_magnitude, cost_magnitude);
237 VLOG(3) <<
"Min cost magnitude = " << min_cost_magnitude
238 <<
", Max cost magnitude = " << max_cost_magnitude;
239 #if !defined(_MSC_VER) 241 log(max_cost_magnitude + 1) + log(graph_->num_nodes() + 1)) {
242 LOG(DFATAL) <<
"Maximum cost magnitude " << max_cost_magnitude <<
" is too " 243 <<
"high for the number of nodes. Try changing the data.";
250 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
251 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
252 CheckRelabelPrecondition(
NodeIndex node)
const {
260 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
263 DCHECK(!IsAdmissible(arc)) << DebugString(
"CheckRelabelPrecondition:", arc);
268 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
270 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::DebugString(
277 const CostValue reduced_cost = scaled_arc_unit_cost_[arc] +
278 node_potential_[
tail] - node_potential_[
head];
279 return absl::StrFormat(
280 "%s Arc %d, from %d to %d, " 281 "Capacity = %d, Residual capacity = %d, " 282 "Flow = residual capacity for reverse arc = %d, " 283 "Height(tail) = %d, Height(head) = %d, " 284 "Excess(tail) = %d, Excess(head) = %d, " 285 "Cost = %d, Reduced cost = %d, ",
287 static_cast<FlowQuantity>(residual_arc_capacity_[arc]), Flow(arc),
288 node_potential_[
tail], node_potential_[
head], node_excess_[
tail],
289 node_excess_[
head], static_cast<CostValue>(scaled_arc_unit_cost_[arc]),
293 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
294 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
295 CheckFeasibility(std::vector<NodeIndex>*
const infeasible_supply_node,
296 std::vector<NodeIndex>*
const infeasible_demand_node) {
309 feasibility_checked_ =
false;
311 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
312 if (initial_node_excess_[node] != 0) {
316 const NodeIndex num_nodes_in_max_flow = graph_->num_nodes() + 2;
317 const ArcIndex num_arcs_in_max_flow = graph_->num_arcs() + num_extra_arcs;
318 const NodeIndex source = num_nodes_in_max_flow - 2;
319 const NodeIndex sink = num_nodes_in_max_flow - 1;
320 StarGraph checker_graph(num_nodes_in_max_flow, num_arcs_in_max_flow);
321 MaxFlow checker(&checker_graph, source, sink);
325 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
327 checker_graph.
AddArc(graph_->Tail(arc), graph_->Head(arc));
334 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
339 total_supply += supply;
340 }
else if (supply < 0) {
343 total_demand -= supply;
346 if (total_supply != total_demand) {
347 LOG(DFATAL) <<
"total_supply(" << total_supply <<
") != total_demand(" 348 << total_demand <<
").";
351 if (!checker.
Solve()) {
352 LOG(DFATAL) <<
"Max flow could not be computed.";
356 feasible_node_excess_.SetAll(0);
362 feasible_node_excess_.Set(node, flow);
363 if (infeasible_supply_node !=
nullptr) {
364 infeasible_supply_node->push_back(node);
372 feasible_node_excess_.Set(node, -flow);
373 if (infeasible_demand_node !=
nullptr) {
374 infeasible_demand_node->push_back(node);
377 feasibility_checked_ =
true;
378 return optimal_max_flow == total_supply;
381 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
383 if (!feasibility_checked_) {
386 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
387 const FlowQuantity excess = feasible_node_excess_[node];
388 node_excess_.Set(node, excess);
389 initial_node_excess_.Set(node, excess);
394 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
397 if (IsArcDirect(arc)) {
398 return residual_arc_capacity_[Opposite(arc)];
400 return -residual_arc_capacity_[arc];
405 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
409 if (IsArcDirect(arc)) {
410 return residual_arc_capacity_[arc] + residual_arc_capacity_[Opposite(arc)];
416 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
420 DCHECK_EQ(uint64_t{1}, cost_scaling_factor_);
421 return scaled_arc_unit_cost_[arc];
424 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
427 DCHECK(graph_->IsNodeValid(node));
428 return node_excess_[node];
431 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
435 return initial_node_excess_[node];
438 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
442 return feasible_node_excess_[node];
445 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
448 return FastIsAdmissible(arc, node_potential_[Tail(arc)]);
451 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
452 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
454 DCHECK_EQ(node_potential_[Tail(arc)], tail_potential);
455 return residual_arc_capacity_[arc] > 0 &&
456 FastReducedCost(arc, tail_potential) < 0;
459 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
460 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsActive(
462 return node_excess_[node] > 0;
465 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
467 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ReducedCost(
469 return FastReducedCost(arc, node_potential_[Tail(arc)]);
472 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
474 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastReducedCost(
476 DCHECK_EQ(node_potential_[Tail(arc)], tail_potential);
477 DCHECK(graph_->IsNodeValid(Tail(arc)));
478 DCHECK(graph_->IsNodeValid(Head(arc)));
479 DCHECK_LE(node_potential_[Tail(arc)], 0) << DebugString(
"ReducedCost:", arc);
480 DCHECK_LE(node_potential_[Head(arc)], 0) << DebugString(
"ReducedCost:", arc);
481 return scaled_arc_unit_cost_[arc] + tail_potential -
482 node_potential_[Head(arc)];
485 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
487 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
488 GetFirstOutgoingOrOppositeIncomingArc(
NodeIndex node)
const {
489 OutgoingOrOppositeIncomingArcIterator arc_it(*graph_, node);
490 return arc_it.Index();
493 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
495 status_ = NOT_SOLVED;
496 if (absl::GetFlag(FLAGS_min_cost_flow_check_balance) &&
497 !CheckInputConsistency()) {
498 status_ = UNBALANCED;
501 if (absl::GetFlag(FLAGS_min_cost_flow_check_costs) && !CheckCostRange()) {
502 status_ = BAD_COST_RANGE;
505 if (check_feasibility_ && !CheckFeasibility(
nullptr,
nullptr)) {
509 node_potential_.SetAll(0);
510 ResetFirstAdmissibleArcs();
513 if (absl::GetFlag(FLAGS_min_cost_flow_check_result) && !CheckResult()) {
514 status_ = BAD_RESULT;
520 LOG(DFATAL) <<
"Status != OPTIMAL";
521 total_flow_cost_ = 0;
524 total_flow_cost_ = 0;
525 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
526 const FlowQuantity flow_on_arc = residual_arc_capacity_[Opposite(arc)];
527 total_flow_cost_ += scaled_arc_unit_cost_[arc] * flow_on_arc;
534 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
536 ArcScaledCostType>::ResetFirstAdmissibleArcs() {
537 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
538 first_admissible_arc_.Set(node,
539 GetFirstOutgoingOrOppositeIncomingArc(node));
543 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
544 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ScaleCosts() {
546 cost_scaling_factor_ = graph_->num_nodes() + 1;
548 VLOG(3) <<
"Number of nodes in the graph = " << graph_->num_nodes();
549 VLOG(3) <<
"Number of arcs in the graph = " << graph_->num_arcs();
550 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
551 const CostValue cost = scaled_arc_unit_cost_[arc] * cost_scaling_factor_;
552 scaled_arc_unit_cost_.Set(arc,
cost);
553 scaled_arc_unit_cost_.Set(Opposite(arc), -
cost);
556 VLOG(3) <<
"Initial epsilon = " << epsilon_;
557 VLOG(3) <<
"Cost scaling factor = " << cost_scaling_factor_;
560 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
561 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UnscaleCosts() {
563 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
564 const CostValue cost = scaled_arc_unit_cost_[arc] / cost_scaling_factor_;
565 scaled_arc_unit_cost_.Set(arc,
cost);
566 scaled_arc_unit_cost_.Set(Opposite(arc), -
cost);
568 cost_scaling_factor_ = 1;
571 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
572 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Optimize() {
574 num_relabels_since_last_price_update_ = 0;
577 epsilon_ =
std::max(epsilon_ / alpha_, kEpsilonMin);
578 VLOG(3) <<
"Epsilon changed to: " << epsilon_;
580 }
while (epsilon_ != 1LL && status_ !=
INFEASIBLE);
581 if (status_ == NOT_SOLVED) {
586 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
587 void GenericMinCostFlow<
Graph, ArcFlowType,
588 ArcScaledCostType>::SaturateAdmissibleArcs() {
590 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
591 const CostValue tail_potential = node_potential_[node];
592 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
593 first_admissible_arc_[node]);
594 it.Ok(); it.Next()) {
596 if (FastIsAdmissible(arc, tail_potential)) {
597 FastPushFlow(residual_arc_capacity_[arc], arc, node);
607 first_admissible_arc_[node] = Graph::kNilArc;
611 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
612 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::PushFlow(
615 FastPushFlow(flow, arc, Tail(arc));
618 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
619 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastPushFlow(
623 DCHECK_GT(residual_arc_capacity_[arc], 0);
624 DCHECK_LE(flow, residual_arc_capacity_[arc]);
626 residual_arc_capacity_.Set(arc, residual_arc_capacity_[arc] - flow);
628 const ArcIndex opposite = Opposite(arc);
629 residual_arc_capacity_.Set(opposite, residual_arc_capacity_[opposite] + flow);
631 node_excess_.Set(
tail, node_excess_[
tail] - flow);
633 node_excess_.Set(
head, node_excess_[
head] + flow);
636 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
637 void GenericMinCostFlow<
Graph, ArcFlowType,
638 ArcScaledCostType>::InitializeActiveNodeStack() {
640 DCHECK(active_nodes_.empty());
641 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
642 if (IsActive(node)) {
643 active_nodes_.push(node);
648 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
649 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UpdatePrices() {
668 const NodeIndex num_nodes = graph_->num_nodes();
669 std::vector<NodeIndex> bfs_queue;
670 std::vector<bool> node_in_queue(num_nodes,
false);
674 std::vector<CostValue> min_non_admissible_potential(num_nodes, kMinCostValue);
675 std::vector<NodeIndex> nodes_to_process;
681 for (
NodeIndex node = 0; node < num_nodes; ++node) {
682 if (node_excess_[node] < 0) {
683 bfs_queue.push_back(node);
684 node_in_queue[node] =
true;
687 remaining_excess -= node_excess_[node];
698 while (remaining_excess > 0) {
703 for (; queue_index < bfs_queue.size(); ++queue_index) {
705 const NodeIndex node = bfs_queue[queue_index];
706 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
709 if (node_in_queue[
head])
continue;
710 const ArcIndex opposite_arc = Opposite(it.Index());
711 if (residual_arc_capacity_[opposite_arc] > 0) {
712 node_potential_[
head] += potential_delta;
713 if (ReducedCost(opposite_arc) < 0) {
714 DCHECK(IsAdmissible(opposite_arc));
719 remaining_excess -= node_excess_[
head];
720 if (remaining_excess == 0) {
721 node_potential_[
head] -= potential_delta;
724 bfs_queue.push_back(
head);
725 node_in_queue[
head] =
true;
726 if (potential_delta < 0) {
727 first_admissible_arc_[
head] =
728 GetFirstOutgoingOrOppositeIncomingArc(
head);
733 node_potential_[
head] -= potential_delta;
734 if (min_non_admissible_potential[
head] == kMinCostValue) {
735 nodes_to_process.push_back(
head);
738 min_non_admissible_potential[
head],
739 node_potential_[node] - scaled_arc_unit_cost_[opposite_arc]);
743 if (remaining_excess == 0)
break;
745 if (remaining_excess == 0)
break;
749 CostValue max_potential_diff = kMinCostValue;
750 for (
int i = 0; i < nodes_to_process.size(); ++i) {
751 const NodeIndex node = nodes_to_process[i];
752 if (node_in_queue[node])
continue;
755 min_non_admissible_potential[node] - node_potential_[node]);
756 if (max_potential_diff == potential_delta)
break;
758 DCHECK_LE(max_potential_diff, potential_delta);
759 potential_delta = max_potential_diff - epsilon_;
768 for (
int i = 0; i < nodes_to_process.size(); ++i) {
769 const NodeIndex node = nodes_to_process[i];
770 if (node_in_queue[node])
continue;
771 if (node_potential_[node] + potential_delta <
772 min_non_admissible_potential[node]) {
773 node_potential_[node] += potential_delta;
774 first_admissible_arc_[node] =
775 GetFirstOutgoingOrOppositeIncomingArc(node);
776 bfs_queue.push_back(node);
777 node_in_queue[node] =
true;
778 remaining_excess -= node_excess_[node];
783 nodes_to_process[
index] = node;
786 nodes_to_process.resize(
index);
790 if (potential_delta == 0)
return;
791 for (
NodeIndex node = 0; node < num_nodes; ++node) {
792 if (!node_in_queue[node]) {
793 node_potential_[node] += potential_delta;
794 first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
799 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
800 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Refine() {
802 SaturateAdmissibleArcs();
803 InitializeActiveNodeStack();
805 const NodeIndex num_nodes = graph_->num_nodes();
806 while (status_ !=
INFEASIBLE && !active_nodes_.empty()) {
808 if (num_relabels_since_last_price_update_ >= num_nodes) {
809 num_relabels_since_last_price_update_ = 0;
810 if (use_price_update_) {
814 const NodeIndex node = active_nodes_.top();
821 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
822 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Discharge(
829 const CostValue tail_potential = node_potential_[node];
830 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
831 first_admissible_arc_[node]);
832 it.Ok(); it.Next()) {
834 if (FastIsAdmissible(arc, tail_potential)) {
836 if (!LookAhead(arc, tail_potential,
head))
continue;
837 const bool head_active_before_push = IsActive(
head);
840 static_cast<FlowQuantity>(residual_arc_capacity_[arc]));
841 FastPushFlow(
delta, arc, node);
842 if (IsActive(
head) && !head_active_before_push) {
843 active_nodes_.push(
head);
845 if (node_excess_[node] == 0) {
847 first_admissible_arc_.Set(node, arc);
856 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
857 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::LookAhead(
861 DCHECK_EQ(node_potential_[Tail(in_arc)], in_tail_potential);
862 if (node_excess_[node] < 0)
return true;
863 const CostValue tail_potential = node_potential_[node];
864 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
865 first_admissible_arc_[node]);
866 it.Ok(); it.Next()) {
868 if (FastIsAdmissible(arc, tail_potential)) {
869 first_admissible_arc_.Set(node, arc);
877 return FastIsAdmissible(in_arc, in_tail_potential);
880 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
881 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Relabel(
884 DCHECK(CheckRelabelPrecondition(node));
885 ++num_relabels_since_last_price_update_;
892 const CostValue guaranteed_new_potential = node_potential_[node] - epsilon_;
900 CostValue min_non_admissible_potential = kMinCostValue;
905 CostValue previous_min_non_admissible_potential = kMinCostValue;
906 ArcIndex first_arc = Graph::kNilArc;
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];
914 if (min_non_admissible_potential_for_arc > min_non_admissible_potential) {
915 if (min_non_admissible_potential_for_arc > guaranteed_new_potential) {
919 node_potential_.Set(node, guaranteed_new_potential);
920 first_admissible_arc_.Set(node, arc);
923 previous_min_non_admissible_potential = min_non_admissible_potential;
924 min_non_admissible_potential = min_non_admissible_potential_for_arc;
931 if (min_non_admissible_potential == kMinCostValue) {
932 if (node_excess_[node] != 0) {
936 LOG(
ERROR) <<
"Infeasible problem.";
941 node_potential_.Set(node, guaranteed_new_potential);
942 first_admissible_arc_.Set(node,
943 GetFirstOutgoingOrOppositeIncomingArc(node));
951 const CostValue new_potential = min_non_admissible_potential - epsilon_;
952 node_potential_.Set(node, new_potential);
953 if (previous_min_non_admissible_potential <= new_potential) {
954 first_admissible_arc_.Set(node, first_arc);
957 first_admissible_arc_.Set(node,
958 GetFirstOutgoingOrOppositeIncomingArc(node));
962 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
964 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Opposite(
966 return Graphs<Graph>::OppositeArc(*graph_, arc);
969 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
970 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcValid(
972 return Graphs<Graph>::IsArcValid(*graph_, arc);
975 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
976 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcDirect(
986 template class GenericMinCostFlow<StarGraph>;
987 template class GenericMinCostFlow<::util::ReverseArcListGraph<>>;
988 template class GenericMinCostFlow<::util::ReverseArcStaticGraph<>>;
989 template class GenericMinCostFlow<::util::ReverseArcMixedGraph<>>;
990 template class GenericMinCostFlow<
994 template class GenericMinCostFlow<
999 SimpleMinCostFlow::SimpleMinCostFlow(
NodeIndex reserve_num_nodes,
1001 if (reserve_num_nodes > 0) {
1002 node_supply_.reserve(reserve_num_nodes);
1004 if (reserve_num_arcs > 0) {
1005 arc_tail_.reserve(reserve_num_arcs);
1006 arc_head_.reserve(reserve_num_arcs);
1007 arc_capacity_.reserve(reserve_num_arcs);
1008 arc_cost_.reserve(reserve_num_arcs);
1009 arc_permutation_.reserve(reserve_num_arcs);
1010 arc_flow_.reserve(reserve_num_arcs);
1015 ResizeNodeVectors(node);
1016 node_supply_[node] = supply;
1024 const ArcIndex arc = arc_tail_.size();
1025 arc_tail_.push_back(
tail);
1026 arc_head_.push_back(
head);
1028 arc_cost_.push_back(unit_cost);
1033 return arc < arc_permutation_.size() ? arc_permutation_[arc] : arc;
1036 SimpleMinCostFlow::Status SimpleMinCostFlow::SolveWithPossibleAdjustment(
1037 SupplyAdjustment adjustment) {
1041 const NodeIndex num_nodes = node_supply_.size();
1042 const ArcIndex num_arcs = arc_capacity_.size();
1043 if (num_nodes == 0)
return OPTIMAL;
1045 int supply_node_count = 0, demand_node_count = 0;
1047 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1048 if (node_supply_[node] > 0) {
1049 ++supply_node_count;
1050 total_supply += node_supply_[node];
1051 }
else if (node_supply_[node] < 0) {
1052 ++demand_node_count;
1053 total_demand -= node_supply_[node];
1056 if (adjustment == DONT_ADJUST && total_supply != total_demand) {
1071 const ArcIndex augmented_num_arcs =
1072 num_arcs + supply_node_count + demand_node_count;
1075 const NodeIndex augmented_num_nodes = num_nodes + 2;
1077 Graph graph(augmented_num_nodes, augmented_num_arcs);
1078 for (
ArcIndex arc = 0; arc < num_arcs; ++arc) {
1079 graph.AddArc(arc_tail_[arc], arc_head_[arc]);
1082 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1083 if (node_supply_[node] > 0) {
1084 graph.AddArc(source, node);
1085 }
else if (node_supply_[node] < 0) {
1086 graph.AddArc(node, sink);
1090 graph.Build(&arc_permutation_);
1093 GenericMaxFlow<Graph> max_flow(&graph, source, sink);
1095 for (arc = 0; arc < num_arcs; ++arc) {
1096 max_flow.SetArcCapacity(PermutedArc(arc), arc_capacity_[arc]);
1098 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1099 if (node_supply_[node] != 0) {
1100 max_flow.SetArcCapacity(PermutedArc(arc), std::abs(node_supply_[node]));
1105 if (!max_flow.Solve()) {
1106 LOG(
ERROR) <<
"Max flow could not be computed.";
1107 switch (max_flow.status()) {
1108 case MaxFlowStatusClass::NOT_SOLVED:
1112 <<
"Max flow failed but claimed to have an optimal solution";
1113 ABSL_FALLTHROUGH_INTENDED;
1118 maximum_flow_ = max_flow.GetOptimalFlow();
1121 if (adjustment == DONT_ADJUST && maximum_flow_ != total_supply) {
1125 GenericMinCostFlow<Graph> min_cost_flow(&graph);
1127 for (arc = 0; arc < num_arcs; ++arc) {
1128 ArcIndex permuted_arc = PermutedArc(arc);
1129 min_cost_flow.SetArcUnitCost(permuted_arc, arc_cost_[arc]);
1130 min_cost_flow.SetArcCapacity(permuted_arc, arc_capacity_[arc]);
1132 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1133 if (node_supply_[node] != 0) {
1134 ArcIndex permuted_arc = PermutedArc(arc);
1135 min_cost_flow.SetArcCapacity(permuted_arc, std::abs(node_supply_[node]));
1136 min_cost_flow.SetArcUnitCost(permuted_arc, 0);
1140 min_cost_flow.SetNodeSupply(source, maximum_flow_);
1141 min_cost_flow.SetNodeSupply(sink, -maximum_flow_);
1142 min_cost_flow.SetCheckFeasibility(
false);
1144 arc_flow_.resize(num_arcs);
1145 if (min_cost_flow.Solve()) {
1146 optimal_cost_ = min_cost_flow.GetOptimalCost();
1147 for (arc = 0; arc < num_arcs; ++arc) {
1148 arc_flow_[arc] = min_cost_flow.Flow(PermutedArc(arc));
1151 return min_cost_flow.status();
1154 CostValue SimpleMinCostFlow::OptimalCost()
const {
return optimal_cost_; }
1156 FlowQuantity SimpleMinCostFlow::MaximumFlow()
const {
return maximum_flow_; }
1159 return arc_flow_[arc];
1162 NodeIndex SimpleMinCostFlow::NumNodes()
const {
return node_supply_.size(); }
1164 ArcIndex SimpleMinCostFlow::NumArcs()
const {
return arc_tail_.size(); }
1171 return arc_capacity_[arc];
1175 return arc_cost_[arc];
1179 return node_supply_[node];
1182 void SimpleMinCostFlow::ResizeNodeVectors(
NodeIndex node) {
1183 if (node < node_supply_.size())
return;
1184 node_supply_.resize(node + 1);
FlowQuantity Flow(ArcIndex arc) const
#define VLOG(verboselevel)
#define SCOPED_TIME_STAT(stats)
CpSolverResponse Solve(const CpModelProto &model_proto)
Solves the given CpModelProto and returns an instance of CpSolverResponse.
#define DCHECK_GT(val1, val2)
void SetCheckInput(bool value)
void SetArcCapacity(ArcIndex arc, FlowQuantity new_capacity)
void SetCheckResult(bool value)
GenericMinCostFlow(const Graph *graph)
StarGraph ::NodeIndex NodeIndex
StarGraph ::ArcIndex ArcIndex
#define DCHECK_GE(val1, val2)
#define CHECK_EQ(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
NodeIndexType Head(const ArcIndexType arc) const
#define DCHECK_LE(val1, val2)
ABSL_FLAG(int64_t, min_cost_flow_alpha, 5, "Divide factor for epsilon at each refine step.")
NodeIndexType Tail(const ArcIndexType arc) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Collection of objects used to extend the Constraint Solver library.
GurobiMPCallbackContext * context
FlowQuantity GetOptimalFlow() const
#define IF_STATS_ENABLED(instructions)