20 #include "absl/strings/str_format.h"
30 "Divide factor for epsilon at each refine step.");
31 ABSL_FLAG(
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.");
36 "Check that the sum of supplies is equal to the sum of demands.");
38 "Check that the magnitude of the costs will not exceed the "
39 "precision of the machine when scaled (multiplied) by the number "
42 "Check that the result is valid.");
46 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
52 residual_arc_capacity_(),
53 first_admissible_arc_(),
56 alpha_(
absl::GetFlag(FLAGS_min_cost_flow_alpha)),
57 cost_scaling_factor_(1),
58 scaled_arc_unit_cost_(),
61 initial_node_excess_(),
62 feasible_node_excess_(),
63 stats_(
"MinCostFlow"),
64 feasibility_checked_(false),
65 use_price_update_(false),
66 check_feasibility_(
absl::GetFlag(FLAGS_min_cost_flow_check_feasibility)) {
68 if (max_num_nodes > 0) {
69 node_excess_.
Reserve(0, max_num_nodes - 1);
71 node_potential_.
Reserve(0, max_num_nodes - 1);
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);
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);
89 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
92 DCHECK(graph_->IsNodeValid(node));
93 node_excess_.Set(node, supply);
94 initial_node_excess_.Set(node, supply);
96 feasibility_checked_ =
false;
99 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
101 ArcIndex arc, ArcScaledCostType unit_cost) {
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;
109 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
111 ArcIndex arc, ArcFlowType new_capacity) {
114 const FlowQuantity free_capacity = residual_arc_capacity_[arc];
115 const FlowQuantity capacity_delta = new_capacity - Capacity(arc);
116 if (capacity_delta == 0) {
119 status_ = NOT_SOLVED;
120 feasibility_checked_ =
false;
121 const FlowQuantity new_availability = free_capacity + capacity_delta;
122 if (new_availability >= 0) {
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]);
135 const FlowQuantity flow = residual_arc_capacity_[Opposite(arc)];
137 residual_arc_capacity_.Set(arc, 0);
138 residual_arc_capacity_.Set(Opposite(arc), new_capacity);
140 node_excess_.Set(
tail, node_excess_[
tail] + flow_excess);
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)]);
148 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
150 ArcIndex arc, ArcFlowType 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;
160 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
162 ArcScaledCostType>::CheckInputConsistency()
const {
164 uint64_t max_capacity = 0;
166 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
168 static_cast<uint64_t
>(residual_arc_capacity_[arc]);
171 uint64_t total_flow = 0;
172 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
174 total_supply += excess;
176 total_flow += excess;
178 max_capacity + total_flow) {
179 LOG(DFATAL) <<
"Input consistency error: max capacity + flow exceed "
185 if (total_supply != 0) {
186 LOG(DFATAL) <<
"Input consistency error: unbalanced problem";
192 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
193 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::CheckResult()
195 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
196 if (node_excess_[node] != 0) {
197 LOG(DFATAL) <<
"node_excess_[" << node <<
"] != 0";
200 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
204 if (residual_arc_capacity_[arc] < 0) {
205 LOG(DFATAL) <<
"residual_arc_capacity_[" << arc <<
"] < 0";
208 if (residual_arc_capacity_[arc] > 0 && ReducedCost(arc) < -epsilon_) {
209 LOG(DFATAL) <<
"residual_arc_capacity_[" << arc
210 <<
"] > 0 && ReducedCost(" << arc <<
") < " << -epsilon_
211 <<
". (epsilon_ = " << epsilon_ <<
").";
215 LOG(DFATAL) << DebugString(
"CheckResult ", arc);
223 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
224 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::CheckCostRange()
229 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
231 max_cost_magnitude =
std::max(max_cost_magnitude, cost_magnitude);
232 if (cost_magnitude != 0.0) {
233 min_cost_magnitude =
std::min(min_cost_magnitude, cost_magnitude);
236 VLOG(3) <<
"Min cost magnitude = " << min_cost_magnitude
237 <<
", Max cost magnitude = " << max_cost_magnitude;
238 #if !defined(_MSC_VER)
240 log(max_cost_magnitude + 1) + log(graph_->num_nodes() + 1)) {
241 LOG(DFATAL) <<
"Maximum cost magnitude " << max_cost_magnitude <<
" is too "
242 <<
"high for the number of nodes. Try changing the data.";
249 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
250 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
251 CheckRelabelPrecondition(
NodeIndex node)
const {
259 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
262 DCHECK(!IsAdmissible(arc)) << DebugString(
"CheckRelabelPrecondition:", arc);
267 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
269 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::DebugString(
276 const CostValue reduced_cost = scaled_arc_unit_cost_[arc] +
277 node_potential_[
tail] - node_potential_[
head];
278 return absl::StrFormat(
279 "%s Arc %d, from %d to %d, "
280 "Capacity = %d, Residual capacity = %d, "
281 "Flow = residual capacity for reverse arc = %d, "
282 "Height(tail) = %d, Height(head) = %d, "
283 "Excess(tail) = %d, Excess(head) = %d, "
284 "Cost = %d, Reduced cost = %d, ",
286 static_cast<FlowQuantity>(residual_arc_capacity_[arc]), Flow(arc),
287 node_potential_[
tail], node_potential_[
head], node_excess_[
tail],
288 node_excess_[
head],
static_cast<CostValue>(scaled_arc_unit_cost_[arc]),
292 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
295 std::vector<NodeIndex>*
const infeasible_demand_node) {
308 feasibility_checked_ =
false;
310 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
311 if (initial_node_excess_[node] != 0) {
315 const NodeIndex num_nodes_in_max_flow = graph_->num_nodes() + 2;
316 const ArcIndex num_arcs_in_max_flow = graph_->num_arcs() + num_extra_arcs;
317 const NodeIndex source = num_nodes_in_max_flow - 2;
318 const NodeIndex sink = num_nodes_in_max_flow - 1;
319 StarGraph checker_graph(num_nodes_in_max_flow, num_arcs_in_max_flow);
320 MaxFlow checker(&checker_graph, source, sink);
324 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
326 checker_graph.
AddArc(graph_->Tail(arc), graph_->Head(arc));
333 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
338 total_supply += supply;
339 }
else if (supply < 0) {
342 total_demand -= supply;
345 if (total_supply != total_demand) {
346 LOG(DFATAL) <<
"total_supply(" << total_supply <<
") != total_demand("
347 << total_demand <<
").";
351 LOG(DFATAL) <<
"Max flow could not be computed.";
355 feasible_node_excess_.SetAll(0);
356 for (StarGraph::OutgoingArcIterator it(checker_graph, source); it.Ok();
361 feasible_node_excess_.Set(node, flow);
362 if (infeasible_supply_node !=
nullptr) {
363 infeasible_supply_node->push_back(node);
366 for (StarGraph::IncomingArcIterator it(checker_graph, sink); it.Ok();
371 feasible_node_excess_.Set(node, -flow);
372 if (infeasible_demand_node !=
nullptr) {
373 infeasible_demand_node->push_back(node);
376 feasibility_checked_ =
true;
377 return optimal_max_flow == total_supply;
380 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
382 if (!feasibility_checked_) {
385 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
386 const FlowQuantity excess = feasible_node_excess_[node];
387 node_excess_.Set(node, excess);
388 initial_node_excess_.Set(node, excess);
393 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
396 if (IsArcDirect(arc)) {
397 return residual_arc_capacity_[Opposite(arc)];
399 return -residual_arc_capacity_[arc];
404 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
408 if (IsArcDirect(arc)) {
409 return residual_arc_capacity_[arc] + residual_arc_capacity_[Opposite(arc)];
415 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
419 DCHECK_EQ(uint64_t{1}, cost_scaling_factor_);
420 return scaled_arc_unit_cost_[arc];
423 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
426 DCHECK(graph_->IsNodeValid(node));
427 return node_excess_[node];
430 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
434 return initial_node_excess_[node];
437 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
441 return feasible_node_excess_[node];
444 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
447 return FastIsAdmissible(arc, node_potential_[Tail(arc)]);
450 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
451 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
453 DCHECK_EQ(node_potential_[Tail(arc)], tail_potential);
454 return residual_arc_capacity_[arc] > 0 &&
455 FastReducedCost(arc, tail_potential) < 0;
458 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
459 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsActive(
461 return node_excess_[node] > 0;
464 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
466 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ReducedCost(
468 return FastReducedCost(arc, node_potential_[Tail(arc)]);
471 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
473 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastReducedCost(
475 DCHECK_EQ(node_potential_[Tail(arc)], tail_potential);
476 DCHECK(graph_->IsNodeValid(Tail(arc)));
477 DCHECK(graph_->IsNodeValid(Head(arc)));
478 DCHECK_LE(node_potential_[Tail(arc)], 0) << DebugString(
"ReducedCost:", arc);
479 DCHECK_LE(node_potential_[Head(arc)], 0) << DebugString(
"ReducedCost:", arc);
480 return scaled_arc_unit_cost_[arc] + tail_potential -
481 node_potential_[Head(arc)];
484 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
486 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
487 GetFirstOutgoingOrOppositeIncomingArc(
NodeIndex node)
const {
488 OutgoingOrOppositeIncomingArcIterator arc_it(*graph_, node);
489 return arc_it.Index();
492 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
494 status_ = NOT_SOLVED;
495 if (absl::GetFlag(FLAGS_min_cost_flow_check_balance) &&
496 !CheckInputConsistency()) {
497 status_ = UNBALANCED;
500 if (absl::GetFlag(FLAGS_min_cost_flow_check_costs) && !CheckCostRange()) {
501 status_ = BAD_COST_RANGE;
504 if (check_feasibility_ && !CheckFeasibility(
nullptr,
nullptr)) {
505 status_ = INFEASIBLE;
508 node_potential_.SetAll(0);
509 ResetFirstAdmissibleArcs();
512 if (absl::GetFlag(FLAGS_min_cost_flow_check_result) && !CheckResult()) {
513 status_ = BAD_RESULT;
518 if (status_ != OPTIMAL) {
519 LOG(DFATAL) <<
"Status != OPTIMAL";
520 total_flow_cost_ = 0;
523 total_flow_cost_ = 0;
524 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
525 const FlowQuantity flow_on_arc = residual_arc_capacity_[Opposite(arc)];
526 total_flow_cost_ += scaled_arc_unit_cost_[arc] * flow_on_arc;
533 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
535 ArcScaledCostType>::ResetFirstAdmissibleArcs() {
536 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
537 first_admissible_arc_.Set(node,
538 GetFirstOutgoingOrOppositeIncomingArc(node));
542 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
543 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ScaleCosts() {
545 cost_scaling_factor_ = graph_->num_nodes() + 1;
547 VLOG(3) <<
"Number of nodes in the graph = " << graph_->num_nodes();
548 VLOG(3) <<
"Number of arcs in the graph = " << graph_->num_arcs();
549 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
550 const CostValue cost = scaled_arc_unit_cost_[arc] * cost_scaling_factor_;
551 scaled_arc_unit_cost_.Set(arc,
cost);
552 scaled_arc_unit_cost_.Set(Opposite(arc), -
cost);
555 VLOG(3) <<
"Initial epsilon = " << epsilon_;
556 VLOG(3) <<
"Cost scaling factor = " << cost_scaling_factor_;
559 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
560 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UnscaleCosts() {
562 for (
ArcIndex arc = 0; arc < graph_->num_arcs(); ++arc) {
563 const CostValue cost = scaled_arc_unit_cost_[arc] / cost_scaling_factor_;
564 scaled_arc_unit_cost_.Set(arc,
cost);
565 scaled_arc_unit_cost_.Set(Opposite(arc), -
cost);
567 cost_scaling_factor_ = 1;
570 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
571 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Optimize() {
573 num_relabels_since_last_price_update_ = 0;
576 epsilon_ =
std::max(epsilon_ / alpha_, kEpsilonMin);
577 VLOG(3) <<
"Epsilon changed to: " << epsilon_;
579 }
while (epsilon_ != 1LL && status_ != INFEASIBLE);
580 if (status_ == NOT_SOLVED) {
585 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
586 void GenericMinCostFlow<
Graph, ArcFlowType,
587 ArcScaledCostType>::SaturateAdmissibleArcs() {
589 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
590 const CostValue tail_potential = node_potential_[node];
591 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
592 first_admissible_arc_[node]);
593 it.Ok(); it.Next()) {
595 if (FastIsAdmissible(arc, tail_potential)) {
596 FastPushFlow(residual_arc_capacity_[arc], arc, node);
606 first_admissible_arc_[node] = Graph::kNilArc;
610 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
611 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::PushFlow(
614 FastPushFlow(flow, arc, Tail(arc));
617 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
618 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastPushFlow(
622 DCHECK_GT(residual_arc_capacity_[arc], 0);
623 DCHECK_LE(flow, residual_arc_capacity_[arc]);
625 residual_arc_capacity_.Set(arc, residual_arc_capacity_[arc] - flow);
627 const ArcIndex opposite = Opposite(arc);
628 residual_arc_capacity_.Set(opposite, residual_arc_capacity_[opposite] + flow);
630 node_excess_.Set(
tail, node_excess_[
tail] - flow);
632 node_excess_.Set(
head, node_excess_[
head] + flow);
635 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
636 void GenericMinCostFlow<
Graph, ArcFlowType,
637 ArcScaledCostType>::InitializeActiveNodeStack() {
639 DCHECK(active_nodes_.empty());
640 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
641 if (IsActive(node)) {
642 active_nodes_.push(node);
647 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
648 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UpdatePrices() {
667 const NodeIndex num_nodes = graph_->num_nodes();
668 std::vector<NodeIndex> bfs_queue;
669 std::vector<bool> node_in_queue(num_nodes,
false);
673 std::vector<CostValue> min_non_admissible_potential(num_nodes, kMinCostValue);
674 std::vector<NodeIndex> nodes_to_process;
680 for (
NodeIndex node = 0; node < num_nodes; ++node) {
681 if (node_excess_[node] < 0) {
682 bfs_queue.push_back(node);
683 node_in_queue[node] =
true;
686 remaining_excess -= node_excess_[node];
697 while (remaining_excess > 0) {
702 for (; queue_index < bfs_queue.size(); ++queue_index) {
704 const NodeIndex node = bfs_queue[queue_index];
705 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
708 if (node_in_queue[
head])
continue;
709 const ArcIndex opposite_arc = Opposite(it.Index());
710 if (residual_arc_capacity_[opposite_arc] > 0) {
711 node_potential_[
head] += potential_delta;
712 if (ReducedCost(opposite_arc) < 0) {
713 DCHECK(IsAdmissible(opposite_arc));
718 remaining_excess -= node_excess_[
head];
719 if (remaining_excess == 0) {
720 node_potential_[
head] -= potential_delta;
723 bfs_queue.push_back(
head);
724 node_in_queue[
head] =
true;
725 if (potential_delta < 0) {
726 first_admissible_arc_[
head] =
727 GetFirstOutgoingOrOppositeIncomingArc(
head);
732 node_potential_[
head] -= potential_delta;
733 if (min_non_admissible_potential[
head] == kMinCostValue) {
734 nodes_to_process.push_back(
head);
737 min_non_admissible_potential[
head],
738 node_potential_[node] - scaled_arc_unit_cost_[opposite_arc]);
742 if (remaining_excess == 0)
break;
744 if (remaining_excess == 0)
break;
748 CostValue max_potential_diff = kMinCostValue;
749 for (
int i = 0; i < nodes_to_process.size(); ++i) {
750 const NodeIndex node = nodes_to_process[i];
751 if (node_in_queue[node])
continue;
754 min_non_admissible_potential[node] - node_potential_[node]);
755 if (max_potential_diff == potential_delta)
break;
757 DCHECK_LE(max_potential_diff, potential_delta);
758 potential_delta = max_potential_diff - epsilon_;
767 for (
int i = 0; i < nodes_to_process.size(); ++i) {
768 const NodeIndex node = nodes_to_process[i];
769 if (node_in_queue[node])
continue;
770 if (node_potential_[node] + potential_delta <
771 min_non_admissible_potential[node]) {
772 node_potential_[node] += potential_delta;
773 first_admissible_arc_[node] =
774 GetFirstOutgoingOrOppositeIncomingArc(node);
775 bfs_queue.push_back(node);
776 node_in_queue[node] =
true;
777 remaining_excess -= node_excess_[node];
782 nodes_to_process[
index] = node;
785 nodes_to_process.resize(
index);
789 if (potential_delta == 0)
return;
790 for (
NodeIndex node = 0; node < num_nodes; ++node) {
791 if (!node_in_queue[node]) {
792 node_potential_[node] += potential_delta;
793 first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
798 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
799 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Refine() {
801 SaturateAdmissibleArcs();
802 InitializeActiveNodeStack();
804 const NodeIndex num_nodes = graph_->num_nodes();
805 while (status_ != INFEASIBLE && !active_nodes_.empty()) {
807 if (num_relabels_since_last_price_update_ >= num_nodes) {
808 num_relabels_since_last_price_update_ = 0;
809 if (use_price_update_) {
813 const NodeIndex node = active_nodes_.top();
820 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
821 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Discharge(
828 const CostValue tail_potential = node_potential_[node];
829 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
830 first_admissible_arc_[node]);
831 it.Ok(); it.Next()) {
833 if (FastIsAdmissible(arc, tail_potential)) {
835 if (!LookAhead(arc, tail_potential,
head))
continue;
836 const bool head_active_before_push = IsActive(
head);
839 static_cast<FlowQuantity>(residual_arc_capacity_[arc]));
840 FastPushFlow(
delta, arc, node);
841 if (IsActive(
head) && !head_active_before_push) {
842 active_nodes_.push(
head);
844 if (node_excess_[node] == 0) {
846 first_admissible_arc_.Set(node, arc);
852 }
while (status_ != INFEASIBLE);
855 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
856 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::LookAhead(
860 DCHECK_EQ(node_potential_[Tail(in_arc)], in_tail_potential);
861 if (node_excess_[node] < 0)
return true;
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_.Set(node, arc);
876 return FastIsAdmissible(in_arc, in_tail_potential);
879 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
880 void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Relabel(
883 DCHECK(CheckRelabelPrecondition(node));
884 ++num_relabels_since_last_price_update_;
891 const CostValue guaranteed_new_potential = node_potential_[node] - epsilon_;
899 CostValue min_non_admissible_potential = kMinCostValue;
904 CostValue previous_min_non_admissible_potential = kMinCostValue;
905 ArcIndex first_arc = Graph::kNilArc;
907 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
910 if (residual_arc_capacity_[arc] > 0) {
911 const CostValue min_non_admissible_potential_for_arc =
912 node_potential_[Head(arc)] - scaled_arc_unit_cost_[arc];
913 if (min_non_admissible_potential_for_arc > min_non_admissible_potential) {
914 if (min_non_admissible_potential_for_arc > guaranteed_new_potential) {
918 node_potential_.Set(node, guaranteed_new_potential);
919 first_admissible_arc_.Set(node, arc);
922 previous_min_non_admissible_potential = min_non_admissible_potential;
923 min_non_admissible_potential = min_non_admissible_potential_for_arc;
930 if (min_non_admissible_potential == kMinCostValue) {
931 if (node_excess_[node] != 0) {
935 LOG(
ERROR) <<
"Infeasible problem.";
940 node_potential_.Set(node, guaranteed_new_potential);
941 first_admissible_arc_.Set(node,
942 GetFirstOutgoingOrOppositeIncomingArc(node));
950 const CostValue new_potential = min_non_admissible_potential - epsilon_;
951 node_potential_.Set(node, new_potential);
952 if (previous_min_non_admissible_potential <= new_potential) {
953 first_admissible_arc_.Set(node, first_arc);
956 first_admissible_arc_.Set(node,
957 GetFirstOutgoingOrOppositeIncomingArc(node));
961 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
963 GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Opposite(
968 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
969 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcValid(
974 template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
975 bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcDirect(
985 template class GenericMinCostFlow<StarGraph>;
986 template class GenericMinCostFlow<::util::ReverseArcListGraph<>>;
987 template class GenericMinCostFlow<::util::ReverseArcStaticGraph<>>;
988 template class GenericMinCostFlow<::util::ReverseArcMixedGraph<>>;
989 template class GenericMinCostFlow<
993 template class GenericMinCostFlow<
1000 if (reserve_num_nodes > 0) {
1001 node_supply_.reserve(reserve_num_nodes);
1003 if (reserve_num_arcs > 0) {
1004 arc_tail_.reserve(reserve_num_arcs);
1005 arc_head_.reserve(reserve_num_arcs);
1006 arc_capacity_.reserve(reserve_num_arcs);
1007 arc_cost_.reserve(reserve_num_arcs);
1008 arc_permutation_.reserve(reserve_num_arcs);
1009 arc_flow_.reserve(reserve_num_arcs);
1014 ResizeNodeVectors(node);
1015 node_supply_[node] = supply;
1023 const ArcIndex arc = arc_tail_.size();
1024 arc_tail_.push_back(
tail);
1025 arc_head_.push_back(
head);
1027 arc_cost_.push_back(unit_cost);
1032 return arc < arc_permutation_.size() ? arc_permutation_[arc] : arc;
1036 SupplyAdjustment adjustment) {
1040 const NodeIndex num_nodes = node_supply_.size();
1041 const ArcIndex num_arcs = arc_capacity_.size();
1042 if (num_nodes == 0)
return OPTIMAL;
1044 int supply_node_count = 0, demand_node_count = 0;
1046 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1047 if (node_supply_[node] > 0) {
1048 ++supply_node_count;
1049 total_supply += node_supply_[node];
1050 }
else if (node_supply_[node] < 0) {
1051 ++demand_node_count;
1052 total_demand -= node_supply_[node];
1055 if (adjustment == DONT_ADJUST && total_supply != total_demand) {
1070 const ArcIndex augmented_num_arcs =
1071 num_arcs + supply_node_count + demand_node_count;
1074 const NodeIndex augmented_num_nodes = num_nodes + 2;
1076 Graph graph(augmented_num_nodes, augmented_num_arcs);
1077 for (
ArcIndex arc = 0; arc < num_arcs; ++arc) {
1078 graph.AddArc(arc_tail_[arc], arc_head_[arc]);
1081 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1082 if (node_supply_[node] > 0) {
1083 graph.AddArc(source, node);
1084 }
else if (node_supply_[node] < 0) {
1085 graph.AddArc(node, sink);
1089 graph.Build(&arc_permutation_);
1092 GenericMaxFlow<Graph> max_flow(&graph, source, sink);
1094 for (arc = 0; arc < num_arcs; ++arc) {
1095 max_flow.SetArcCapacity(PermutedArc(arc), arc_capacity_[arc]);
1097 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1098 if (node_supply_[node] != 0) {
1099 max_flow.SetArcCapacity(PermutedArc(arc), std::abs(node_supply_[node]));
1104 if (!max_flow.Solve()) {
1105 LOG(
ERROR) <<
"Max flow could not be computed.";
1106 switch (max_flow.status()) {
1111 <<
"Max flow failed but claimed to have an optimal solution";
1112 ABSL_FALLTHROUGH_INTENDED;
1117 maximum_flow_ = max_flow.GetOptimalFlow();
1120 if (adjustment == DONT_ADJUST && maximum_flow_ != total_supply) {
1124 GenericMinCostFlow<Graph> min_cost_flow(&graph);
1126 for (arc = 0; arc < num_arcs; ++arc) {
1127 ArcIndex permuted_arc = PermutedArc(arc);
1128 min_cost_flow.SetArcUnitCost(permuted_arc, arc_cost_[arc]);
1129 min_cost_flow.SetArcCapacity(permuted_arc, arc_capacity_[arc]);
1131 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1132 if (node_supply_[node] != 0) {
1133 ArcIndex permuted_arc = PermutedArc(arc);
1134 min_cost_flow.SetArcCapacity(permuted_arc, std::abs(node_supply_[node]));
1135 min_cost_flow.SetArcUnitCost(permuted_arc, 0);
1139 min_cost_flow.SetNodeSupply(source, maximum_flow_);
1140 min_cost_flow.SetNodeSupply(sink, -maximum_flow_);
1141 min_cost_flow.SetCheckFeasibility(
false);
1143 arc_flow_.resize(num_arcs);
1144 if (min_cost_flow.Solve()) {
1145 optimal_cost_ = min_cost_flow.GetOptimalCost();
1146 for (arc = 0; arc < num_arcs; ++arc) {
1147 arc_flow_[arc] = min_cost_flow.Flow(PermutedArc(arc));
1150 return min_cost_flow.status();
1158 return arc_flow_[arc];
1170 return arc_capacity_[arc];
1174 return arc_cost_[arc];
1178 return node_supply_[node];
1181 void SimpleMinCostFlow::ResizeNodeVectors(
NodeIndex node) {
1182 if (node < node_supply_.size())
return;
1183 node_supply_.resize(node + 1);
#define DCHECK_LE(val1, val2)
#define CHECK_EQ(val1, val2)
#define DCHECK_GE(val1, val2)
#define DCHECK_GT(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
#define VLOG(verboselevel)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
NodeIndexType Tail(const ArcIndexType arc) const
FlowQuantity GetOptimalFlow() const
void SetArcCapacity(ArcIndex arc, FlowQuantity new_capacity)
FlowQuantity Flow(ArcIndex arc) const
void SetCheckResult(bool value)
void SetCheckInput(bool value)
CostValue UnitCost(ArcIndex arc) const
FlowQuantity FeasibleSupply(NodeIndex node) const
FlowQuantity Flow(ArcIndex arc) const
GenericMinCostFlow(const Graph *graph)
Graph::NodeIndex NodeIndex
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
FlowQuantity InitialSupply(NodeIndex node) const
void SetArcFlow(ArcIndex arc, ArcFlowType new_flow)
bool CheckFeasibility(std::vector< NodeIndex > *const infeasible_supply_node, std::vector< NodeIndex > *const infeasible_demand_node)
FlowQuantity Capacity(ArcIndex arc) const
FlowQuantity Supply(NodeIndex node) const
void SetArcUnitCost(ArcIndex arc, ArcScaledCostType unit_cost)
void SetArcCapacity(ArcIndex arc, ArcFlowType new_capacity)
CostValue UnitCost(ArcIndex arc) const
ArcIndex AddArcWithCapacityAndUnitCost(NodeIndex tail, NodeIndex head, FlowQuantity capacity, CostValue unit_cost)
FlowQuantity Flow(ArcIndex arc) const
FlowQuantity MaximumFlow() const
NodeIndex NumNodes() const
SimpleMinCostFlow(NodeIndex reserve_num_nodes=0, ArcIndex reserve_num_arcs=0)
void SetNodeSupply(NodeIndex node, FlowQuantity supply)
NodeIndex Tail(ArcIndex arc) const
FlowQuantity Capacity(ArcIndex arc) const
FlowQuantity Supply(NodeIndex node) const
NodeIndex Head(ArcIndex arc) const
CostValue OptimalCost() const
NodeIndexType Head(const ArcIndexType arc) const
bool Reserve(int64_t new_min_index, int64_t new_max_index)
GurobiMPCallbackContext * context
ABSL_FLAG(int64_t, min_cost_flow_alpha, 5, "Divide factor for epsilon at each refine step.")
Collection of objects used to extend the Constraint Solver library.
#define IF_STATS_ENABLED(instructions)
#define SCOPED_TIME_STAT(stats)
static ArcIndex ArcReservation(const Graph &graph)
static NodeIndex NodeReservation(const Graph &graph)
static bool IsArcValid(const Graph &graph, ArcIndex arc)
static ArcIndex OppositeArc(const Graph &graph, ArcIndex arc)