472 if (absl::GetFlag(FLAGS_min_cost_flow_check_result) && !CheckResult()) {
473 status_ = BAD_RESULT;
483template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
493 const CostValue kMaxCost = std::numeric_limits<CostValue>::max();
494 const CostValue kMinCost = std::numeric_limits<CostValue>::min();
496 const CostValue flow_on_arc = residual_arc_capacity_[Opposite(
arc)];
498 CapProd(scaled_arc_unit_cost_[
arc], flow_on_arc);
499 if (flow_cost == kMaxCost || flow_cost == kMinCost)
return kMaxCost;
500 total_flow_cost =
CapAdd(flow_cost, total_flow_cost);
501 if (total_flow_cost == kMaxCost || total_flow_cost == kMinCost) {
505 return total_flow_cost;
508template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
510 ArcScaledCostType>::ResetFirstAdmissibleArcs() {
511 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
512 first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
516template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
517bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::ScaleCosts() {
519 cost_scaling_factor_ = scale_prices_ ? graph_->num_nodes() + 1 : 1;
521 VLOG(3) <<
"Number of nodes in the graph = " << graph_->num_nodes();
522 VLOG(3) <<
"Number of arcs in the graph = " << graph_->num_arcs();
524 std::numeric_limits<CostValue>::max() / (2 * cost_scaling_factor_);
526 if (scaled_arc_unit_cost_[
arc] > threshold ||
527 scaled_arc_unit_cost_[
arc] < -threshold) {
528 status_ = BAD_COST_RANGE;
531 const CostValue cost = scaled_arc_unit_cost_[
arc] * cost_scaling_factor_;
532 scaled_arc_unit_cost_.Set(
arc, cost);
533 scaled_arc_unit_cost_.Set(Opposite(
arc), -cost);
540 overflow_threshold_ = std::numeric_limits<CostValue>::min() + epsilon_;
542 VLOG(3) <<
"Initial epsilon = " << epsilon_;
543 VLOG(3) <<
"Cost scaling factor = " << cost_scaling_factor_;
547template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
548void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UnscaleCosts() {
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);
555 cost_scaling_factor_ = 1;
558template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
559bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Optimize() {
561 num_relabels_since_last_price_update_ = 0;
564 epsilon_ = std::max(epsilon_ / alpha_, kEpsilonMin);
565 VLOG(3) <<
"Epsilon changed to: " << epsilon_;
566 if (!Refine())
return false;
567 }
while (epsilon_ != 1LL);
571template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
572void GenericMinCostFlow<
Graph, ArcFlowType,
573 ArcScaledCostType>::SaturateAdmissibleArcs() {
575 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
576 const CostValue tail_potential = node_potential_[node];
577 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
578 first_admissible_arc_[node]);
579 it.Ok(); it.Next()) {
581 if (FastIsAdmissible(
arc, tail_potential)) {
582 FastPushFlow(residual_arc_capacity_[
arc],
arc, node);
596template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
597void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::PushFlow(
600 FastPushFlow(flow,
arc, Tail(
arc));
603template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
604void GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::FastPushFlow(
608 DCHECK_GT(residual_arc_capacity_[
arc], 0);
609 DCHECK_LE(flow, residual_arc_capacity_[
arc]);
611 residual_arc_capacity_.Set(
arc, residual_arc_capacity_[
arc] - flow);
614 residual_arc_capacity_.Set(opposite, residual_arc_capacity_[opposite] + flow);
616 node_excess_[
tail] -= flow;
617 node_excess_[Head(
arc)] += flow;
620template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
621void GenericMinCostFlow<
Graph, ArcFlowType,
622 ArcScaledCostType>::InitializeActiveNodeStack() {
624 DCHECK(active_nodes_.empty());
625 for (
NodeIndex node = 0; node < graph_->num_nodes(); ++node) {
626 if (IsActive(node)) {
627 active_nodes_.push(node);
632template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
633bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::UpdatePrices() {
652 const NodeIndex num_nodes = graph_->num_nodes();
653 std::vector<NodeIndex> bfs_queue;
654 std::vector<bool> node_in_queue(num_nodes,
false);
657 const CostValue kMinCostValue = std::numeric_limits<CostValue>::min();
658 std::vector<CostValue> min_non_admissible_potential(num_nodes, kMinCostValue);
659 std::vector<NodeIndex> nodes_to_process;
665 for (
NodeIndex node = 0; node < num_nodes; ++node) {
666 if (node_excess_[node] < 0) {
667 bfs_queue.push_back(node);
668 node_in_queue[node] =
true;
671 remaining_excess -= node_excess_[node];
682 while (remaining_excess > 0) {
687 for (; queue_index < bfs_queue.size(); ++queue_index) {
688 DCHECK_GE(num_nodes, bfs_queue.size());
689 const NodeIndex node = bfs_queue[queue_index];
690 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
693 if (node_in_queue[
head])
continue;
694 const ArcIndex opposite_arc = Opposite(it.Index());
695 if (residual_arc_capacity_[opposite_arc] > 0) {
696 node_potential_[
head] += potential_delta;
697 if (node_potential_[
head] < overflow_threshold_) {
698 status_ = BAD_COST_RANGE;
701 if (ReducedCost(opposite_arc) < 0) {
702 DCHECK(IsAdmissible(opposite_arc));
707 remaining_excess -= node_excess_[
head];
708 if (remaining_excess == 0) {
709 node_potential_[
head] -= potential_delta;
712 bfs_queue.push_back(
head);
713 node_in_queue[
head] =
true;
714 if (potential_delta < 0) {
715 first_admissible_arc_[
head] =
716 GetFirstOutgoingOrOppositeIncomingArc(
head);
721 node_potential_[
head] -= potential_delta;
722 if (min_non_admissible_potential[
head] == kMinCostValue) {
723 nodes_to_process.push_back(
head);
725 min_non_admissible_potential[
head] = std::max(
726 min_non_admissible_potential[
head],
727 node_potential_[node] - scaled_arc_unit_cost_[opposite_arc]);
731 if (remaining_excess == 0)
break;
733 if (remaining_excess == 0)
break;
737 CostValue max_potential_diff = kMinCostValue;
738 for (
int i = 0;
i < nodes_to_process.size(); ++
i) {
740 if (node_in_queue[node])
continue;
742 std::max(max_potential_diff,
743 min_non_admissible_potential[node] - node_potential_[node]);
744 if (max_potential_diff == potential_delta)
break;
746 DCHECK_LE(max_potential_diff, potential_delta);
747 potential_delta = max_potential_diff - epsilon_;
756 for (
int i = 0;
i < nodes_to_process.size(); ++
i) {
758 if (node_in_queue[node])
continue;
759 if (node_potential_[node] + potential_delta <
760 min_non_admissible_potential[node]) {
761 node_potential_[node] += potential_delta;
762 if (node_potential_[node] < overflow_threshold_) {
763 status_ = BAD_COST_RANGE;
766 first_admissible_arc_[node] =
767 GetFirstOutgoingOrOppositeIncomingArc(node);
768 bfs_queue.push_back(node);
769 node_in_queue[node] =
true;
770 remaining_excess -= node_excess_[node];
775 nodes_to_process[
index] = node;
778 nodes_to_process.resize(
index);
782 if (potential_delta == 0)
return true;
783 for (
NodeIndex node = 0; node < num_nodes; ++node) {
784 if (!node_in_queue[node]) {
785 node_potential_[node] += potential_delta;
786 if (node_potential_[node] < overflow_threshold_) {
787 status_ = BAD_COST_RANGE;
790 first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
796template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
797bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Refine() {
799 SaturateAdmissibleArcs();
800 InitializeActiveNodeStack();
802 const NodeIndex num_nodes = graph_->num_nodes();
803 while (!active_nodes_.empty()) {
805 if (num_relabels_since_last_price_update_ >= num_nodes) {
806 num_relabels_since_last_price_update_ = 0;
807 if (use_price_update_) {
808 if (!UpdatePrices())
return false;
811 const NodeIndex node = active_nodes_.top();
813 DCHECK(IsActive(node));
814 if (!Discharge(node))
return false;
819template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
820bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Discharge(
826 DCHECK(IsActive(node));
827 const CostValue tail_potential = node_potential_[node];
828 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
829 first_admissible_arc_[node]);
830 it.Ok(); it.Next()) {
832 if (!FastIsAdmissible(
arc, tail_potential))
continue;
838 if (node_excess_[
head] >= 0 && !NodeHasAdmissibleArc(
head)) {
840 if (!Relabel(
head))
return false;
841 if (!FastIsAdmissible(
arc, tail_potential))
continue;
845 std::min(node_excess_[node],
847 const bool head_active_before_push = IsActive(
head);
849 if (IsActive(
head) && !head_active_before_push) {
850 active_nodes_.push(
head);
853 if (node_excess_[node] == 0) {
855 first_admissible_arc_[node] =
arc;
859 if (!Relabel(node))
return false;
863template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
864bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::
867 const CostValue tail_potential = node_potential_[node];
868 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node,
869 first_admissible_arc_[node]);
870 it.Ok(); it.Next()) {
872 if (FastIsAdmissible(
arc, tail_potential)) {
873 first_admissible_arc_[node] =
arc;
881template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
882bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Relabel(
885 DCHECK(CheckRelabelPrecondition(node));
886 ++num_relabels_since_last_price_update_;
893 const CostValue guaranteed_new_potential = node_potential_[node] - epsilon_;
894 if (guaranteed_new_potential < overflow_threshold_) {
895 status_ = BAD_COST_RANGE;
904 const CostValue kMinCostValue = std::numeric_limits<CostValue>::min();
905 CostValue min_non_admissible_potential = kMinCostValue;
910 CostValue previous_min_non_admissible_potential = kMinCostValue;
913 for (OutgoingOrOppositeIncomingArcIterator it(*graph_, node); it.Ok();
916 if (residual_arc_capacity_[
arc] > 0) {
917 const CostValue min_non_admissible_potential_for_arc =
918 node_potential_[Head(
arc)] - scaled_arc_unit_cost_[
arc];
922 if (min_non_admissible_potential_for_arc > guaranteed_new_potential) {
926 node_potential_[node] = guaranteed_new_potential;
927 first_admissible_arc_[node] =
arc;
930 if (min_non_admissible_potential_for_arc > min_non_admissible_potential) {
931 previous_min_non_admissible_potential = min_non_admissible_potential;
932 min_non_admissible_potential = min_non_admissible_potential_for_arc;
942 if (min_non_admissible_potential == kMinCostValue) {
943 if (node_excess_[node] != 0) {
953 node_potential_[node] = guaranteed_new_potential;
962 if (min_non_admissible_potential < overflow_threshold_) {
963 status_ = BAD_COST_RANGE;
966 const CostValue new_potential = min_non_admissible_potential - epsilon_;
967 if (new_potential < overflow_threshold_) {
968 status_ = BAD_COST_RANGE;
971 node_potential_[node] = new_potential;
972 if (previous_min_non_admissible_potential <= new_potential) {
973 first_admissible_arc_[node] = first_arc;
976 first_admissible_arc_[node] = GetFirstOutgoingOrOppositeIncomingArc(node);
981template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
983GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::Opposite(
988template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
989bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcValid(
994template <
typename Graph,
typename ArcFlowType,
typename ArcScaledCostType>
995bool GenericMinCostFlow<Graph, ArcFlowType, ArcScaledCostType>::IsArcDirect(
997 DCHECK(IsArcValid(
arc));
1005template class GenericMinCostFlow<StarGraph>;
1006template class GenericMinCostFlow<::util::ReverseArcListGraph<>>;
1007template class GenericMinCostFlow<::util::ReverseArcStaticGraph<>>;
1008template class GenericMinCostFlow<::util::ReverseArcMixedGraph<>>;
1009template class GenericMinCostFlow<
1011template class GenericMinCostFlow<::util::ReverseArcListGraph<int64_t, int64_t>,
1015template class GenericMinCostFlow<
1022 if (reserve_num_nodes > 0) {
1023 node_supply_.reserve(reserve_num_nodes);
1025 if (reserve_num_arcs > 0) {
1026 arc_tail_.reserve(reserve_num_arcs);
1027 arc_head_.reserve(reserve_num_arcs);
1028 arc_capacity_.reserve(reserve_num_arcs);
1029 arc_cost_.reserve(reserve_num_arcs);
1030 arc_permutation_.reserve(reserve_num_arcs);
1031 arc_flow_.reserve(reserve_num_arcs);
1036 ResizeNodeVectors(node);
1037 node_supply_[node] = supply;
1044 ResizeNodeVectors(std::max(
tail,
head));
1046 arc_tail_.push_back(
tail);
1047 arc_head_.push_back(
head);
1048 arc_capacity_.push_back(capacity);
1049 arc_cost_.push_back(unit_cost);
1054 return arc < arc_permutation_.size() ? arc_permutation_[
arc] :
arc;
1058 SupplyAdjustment adjustment) {
1062 const NodeIndex num_nodes = node_supply_.size();
1063 const ArcIndex num_arcs = arc_capacity_.size();
1064 if (num_nodes == 0)
return OPTIMAL;
1066 int supply_node_count = 0, demand_node_count = 0;
1068 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1069 if (node_supply_[node] > 0) {
1070 ++supply_node_count;
1071 total_supply += node_supply_[node];
1072 }
else if (node_supply_[node] < 0) {
1073 ++demand_node_count;
1074 total_demand -= node_supply_[node];
1077 if (adjustment == DONT_ADJUST && total_supply != total_demand) {
1092 const ArcIndex augmented_num_arcs =
1093 num_arcs + supply_node_count + demand_node_count;
1096 const NodeIndex augmented_num_nodes = num_nodes + 2;
1098 Graph graph(augmented_num_nodes, augmented_num_arcs);
1103 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1104 if (node_supply_[node] > 0) {
1105 graph.AddArc(source, node);
1106 }
else if (node_supply_[node] < 0) {
1107 graph.AddArc(node, sink);
1111 graph.Build(&arc_permutation_);
1114 GenericMaxFlow<Graph> max_flow(&
graph, source, sink);
1117 max_flow.SetArcCapacity(PermutedArc(
arc), arc_capacity_[
arc]);
1119 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1120 if (node_supply_[node] != 0) {
1121 max_flow.SetArcCapacity(PermutedArc(
arc), std::abs(node_supply_[node]));
1125 CHECK_EQ(
arc, augmented_num_arcs);
1126 if (!max_flow.Solve()) {
1127 LOG(ERROR) <<
"Max flow could not be computed.";
1128 switch (max_flow.status()) {
1133 <<
"Max flow failed but claimed to have an optimal solution";
1134 ABSL_FALLTHROUGH_INTENDED;
1139 maximum_flow_ = max_flow.GetOptimalFlow();
1142 if (adjustment == DONT_ADJUST && maximum_flow_ != total_supply) {
1146 GenericMinCostFlow<Graph> min_cost_flow(&
graph);
1150 min_cost_flow.SetArcUnitCost(permuted_arc, arc_cost_[
arc]);
1151 min_cost_flow.SetArcCapacity(permuted_arc, arc_capacity_[
arc]);
1153 for (
NodeIndex node = 0; node < num_nodes; ++node) {
1154 if (node_supply_[node] != 0) {
1156 min_cost_flow.SetArcCapacity(permuted_arc, std::abs(node_supply_[node]));
1157 min_cost_flow.SetArcUnitCost(permuted_arc, 0);
1161 min_cost_flow.SetNodeSupply(source, maximum_flow_);
1162 min_cost_flow.SetNodeSupply(sink, -maximum_flow_);
1163 min_cost_flow.SetCheckFeasibility(
false);
1164 min_cost_flow.SetPriceScaling(scale_prices_);
1166 arc_flow_.resize(num_arcs);
1167 if (min_cost_flow.Solve()) {
1168 optimal_cost_ = min_cost_flow.GetOptimalCost();
1170 arc_flow_[
arc] = min_cost_flow.Flow(PermutedArc(
arc));
1173 return min_cost_flow.status();
1181 return arc_flow_[
arc];
1193 return arc_capacity_[
arc];
1197 return arc_cost_[
arc];
1201 return node_supply_[node];
1204void SimpleMinCostFlow::ResizeNodeVectors(
NodeIndex node) {
1205 if (node < node_supply_.size())
return;
1206 node_supply_.resize(node + 1);