0
2
0
58
24
... | ... |
@@ -152,49 +152,49 @@ |
152 | 152 |
|
153 | 153 |
// Data structures for storing the digraph |
154 | 154 |
IntNodeMap _node_id; |
155 | 155 |
IntArcMap _arc_idf; |
156 | 156 |
IntArcMap _arc_idb; |
157 | 157 |
IntVector _first_out; |
158 | 158 |
BoolVector _forward; |
159 | 159 |
IntVector _source; |
160 | 160 |
IntVector _target; |
161 | 161 |
IntVector _reverse; |
162 | 162 |
|
163 | 163 |
// Node and arc data |
164 | 164 |
ValueVector _lower; |
165 | 165 |
ValueVector _upper; |
166 | 166 |
CostVector _cost; |
167 | 167 |
ValueVector _supply; |
168 | 168 |
|
169 | 169 |
ValueVector _res_cap; |
170 | 170 |
CostVector _pi; |
171 | 171 |
ValueVector _excess; |
172 | 172 |
IntVector _excess_nodes; |
173 | 173 |
IntVector _deficit_nodes; |
174 | 174 |
|
175 | 175 |
Value _delta; |
176 |
int |
|
176 |
int _factor; |
|
177 | 177 |
IntVector _pred; |
178 | 178 |
|
179 | 179 |
public: |
180 | 180 |
|
181 | 181 |
/// \brief Constant for infinite upper bounds (capacities). |
182 | 182 |
/// |
183 | 183 |
/// Constant for infinite upper bounds (capacities). |
184 | 184 |
/// It is \c std::numeric_limits<Value>::infinity() if available, |
185 | 185 |
/// \c std::numeric_limits<Value>::max() otherwise. |
186 | 186 |
const Value INF; |
187 | 187 |
|
188 | 188 |
private: |
189 | 189 |
|
190 | 190 |
// Special implementation of the Dijkstra algorithm for finding |
191 | 191 |
// shortest paths in the residual network of the digraph with |
192 | 192 |
// respect to the reduced arc costs and modifying the node |
193 | 193 |
// potentials according to the found distance labels. |
194 | 194 |
class ResidualDijkstra |
195 | 195 |
{ |
196 | 196 |
private: |
197 | 197 |
|
198 | 198 |
int _node_num; |
199 | 199 |
const IntVector &_first_out; |
200 | 200 |
const IntVector &_target; |
... | ... |
@@ -492,82 +492,82 @@ |
492 | 492 |
/// @} |
493 | 493 |
|
494 | 494 |
/// \name Execution control |
495 | 495 |
/// The algorithm can be executed using \ref run(). |
496 | 496 |
|
497 | 497 |
/// @{ |
498 | 498 |
|
499 | 499 |
/// \brief Run the algorithm. |
500 | 500 |
/// |
501 | 501 |
/// This function runs the algorithm. |
502 | 502 |
/// The paramters can be specified using functions \ref lowerMap(), |
503 | 503 |
/// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). |
504 | 504 |
/// For example, |
505 | 505 |
/// \code |
506 | 506 |
/// CapacityScaling<ListDigraph> cs(graph); |
507 | 507 |
/// cs.lowerMap(lower).upperMap(upper).costMap(cost) |
508 | 508 |
/// .supplyMap(sup).run(); |
509 | 509 |
/// \endcode |
510 | 510 |
/// |
511 | 511 |
/// This function can be called more than once. All the parameters |
512 | 512 |
/// that have been given are kept for the next call, unless |
513 | 513 |
/// \ref reset() is called, thus only the modified parameters |
514 | 514 |
/// have to be set again. See \ref reset() for examples. |
515 | 515 |
/// However the underlying digraph must not be modified after this |
516 |
/// class have been constructed, since it copies the |
|
516 |
/// class have been constructed, since it copies and extends the graph. |
|
517 | 517 |
/// |
518 |
/// \param scaling Enable or disable capacity scaling. |
|
519 |
/// If the maximum upper bound and/or the amount of total supply |
|
520 |
/// is rather small, the algorithm could be slightly faster without |
|
521 |
/// scaling. |
|
518 |
/// \param factor The capacity scaling factor. It must be larger than |
|
519 |
/// one to use scaling. If it is less or equal to one, then scaling |
|
520 |
/// will be disabled. |
|
522 | 521 |
/// |
523 | 522 |
/// \return \c INFEASIBLE if no feasible flow exists, |
524 | 523 |
/// \n \c OPTIMAL if the problem has optimal solution |
525 | 524 |
/// (i.e. it is feasible and bounded), and the algorithm has found |
526 | 525 |
/// optimal flow and node potentials (primal and dual solutions), |
527 | 526 |
/// \n \c UNBOUNDED if the digraph contains an arc of negative cost |
528 | 527 |
/// and infinite upper bound. It means that the objective function |
529 | 528 |
/// is unbounded on that arc, however note that it could actually be |
530 | 529 |
/// bounded over the feasible flows, but this algroithm cannot handle |
531 | 530 |
/// these cases. |
532 | 531 |
/// |
533 | 532 |
/// \see ProblemType |
534 |
ProblemType run(bool scaling = true) { |
|
535 |
ProblemType pt = init(scaling); |
|
533 |
ProblemType run(int factor = 4) { |
|
534 |
_factor = factor; |
|
535 |
ProblemType pt = init(); |
|
536 | 536 |
if (pt != OPTIMAL) return pt; |
537 | 537 |
return start(); |
538 | 538 |
} |
539 | 539 |
|
540 | 540 |
/// \brief Reset all the parameters that have been given before. |
541 | 541 |
/// |
542 | 542 |
/// This function resets all the paramaters that have been given |
543 | 543 |
/// before using functions \ref lowerMap(), \ref upperMap(), |
544 | 544 |
/// \ref costMap(), \ref supplyMap(), \ref stSupply(). |
545 | 545 |
/// |
546 | 546 |
/// It is useful for multiple run() calls. If this function is not |
547 | 547 |
/// used, all the parameters given before are kept for the next |
548 | 548 |
/// \ref run() call. |
549 |
/// However the underlying digraph must not be modified after this |
|
549 |
/// However, the underlying digraph must not be modified after this |
|
550 | 550 |
/// class have been constructed, since it copies and extends the graph. |
551 | 551 |
/// |
552 | 552 |
/// For example, |
553 | 553 |
/// \code |
554 | 554 |
/// CapacityScaling<ListDigraph> cs(graph); |
555 | 555 |
/// |
556 | 556 |
/// // First run |
557 | 557 |
/// cs.lowerMap(lower).upperMap(upper).costMap(cost) |
558 | 558 |
/// .supplyMap(sup).run(); |
559 | 559 |
/// |
560 | 560 |
/// // Run again with modified cost map (reset() is not called, |
561 | 561 |
/// // so only the cost map have to be set again) |
562 | 562 |
/// cost[e] += 100; |
563 | 563 |
/// cs.costMap(cost).run(); |
564 | 564 |
/// |
565 | 565 |
/// // Run again from scratch using reset() |
566 | 566 |
/// // (the lower bounds will be set to zero on all arcs) |
567 | 567 |
/// cs.reset(); |
568 | 568 |
/// cs.upperMap(capacity).costMap(cost) |
569 | 569 |
/// .supplyMap(sup).run(); |
570 | 570 |
/// \endcode |
571 | 571 |
/// |
572 | 572 |
/// \return <tt>(*this)</tt> |
573 | 573 |
CapacityScaling& reset() { |
... | ... |
@@ -656,49 +656,49 @@ |
656 | 656 |
Cost potential(const Node& n) const { |
657 | 657 |
return _pi[_node_id[n]]; |
658 | 658 |
} |
659 | 659 |
|
660 | 660 |
/// \brief Return the potential map (the dual solution). |
661 | 661 |
/// |
662 | 662 |
/// This function copies the potential (dual value) of each node |
663 | 663 |
/// into the given map. |
664 | 664 |
/// The \c Cost type of the algorithm must be convertible to the |
665 | 665 |
/// \c Value type of the map. |
666 | 666 |
/// |
667 | 667 |
/// \pre \ref run() must be called before using this function. |
668 | 668 |
template <typename PotentialMap> |
669 | 669 |
void potentialMap(PotentialMap &map) const { |
670 | 670 |
for (NodeIt n(_graph); n != INVALID; ++n) { |
671 | 671 |
map.set(n, _pi[_node_id[n]]); |
672 | 672 |
} |
673 | 673 |
} |
674 | 674 |
|
675 | 675 |
/// @} |
676 | 676 |
|
677 | 677 |
private: |
678 | 678 |
|
679 | 679 |
// Initialize the algorithm |
680 |
ProblemType init( |
|
680 |
ProblemType init() { |
|
681 | 681 |
if (_node_num == 0) return INFEASIBLE; |
682 | 682 |
|
683 | 683 |
// Check the sum of supply values |
684 | 684 |
_sum_supply = 0; |
685 | 685 |
for (int i = 0; i != _root; ++i) { |
686 | 686 |
_sum_supply += _supply[i]; |
687 | 687 |
} |
688 | 688 |
if (_sum_supply > 0) return INFEASIBLE; |
689 | 689 |
|
690 | 690 |
// Initialize maps |
691 | 691 |
for (int i = 0; i != _root; ++i) { |
692 | 692 |
_pi[i] = 0; |
693 | 693 |
_excess[i] = _supply[i]; |
694 | 694 |
} |
695 | 695 |
|
696 | 696 |
// Remove non-zero lower bounds |
697 | 697 |
if (_have_lower) { |
698 | 698 |
for (int i = 0; i != _root; ++i) { |
699 | 699 |
for (int j = _first_out[i]; j != _first_out[i+1]; ++j) { |
700 | 700 |
if (_forward[j]) { |
701 | 701 |
Value c = _lower[j]; |
702 | 702 |
if (c >= 0) { |
703 | 703 |
_res_cap[j] = _upper[j] < INF ? _upper[j] - c : INF; |
704 | 704 |
} else { |
... | ... |
@@ -737,103 +737,99 @@ |
737 | 737 |
_excess[_root] = -_sum_supply; |
738 | 738 |
for (int a = _first_out[_root]; a != _res_arc_num; ++a) { |
739 | 739 |
int u = _target[a]; |
740 | 740 |
if (_excess[u] < 0) { |
741 | 741 |
_res_cap[a] = -_excess[u] + 1; |
742 | 742 |
} else { |
743 | 743 |
_res_cap[a] = 1; |
744 | 744 |
} |
745 | 745 |
_res_cap[_reverse[a]] = 0; |
746 | 746 |
_cost[a] = 0; |
747 | 747 |
_cost[_reverse[a]] = 0; |
748 | 748 |
} |
749 | 749 |
} else { |
750 | 750 |
_pi[_root] = 0; |
751 | 751 |
_excess[_root] = 0; |
752 | 752 |
for (int a = _first_out[_root]; a != _res_arc_num; ++a) { |
753 | 753 |
_res_cap[a] = 1; |
754 | 754 |
_res_cap[_reverse[a]] = 0; |
755 | 755 |
_cost[a] = 0; |
756 | 756 |
_cost[_reverse[a]] = 0; |
757 | 757 |
} |
758 | 758 |
} |
759 | 759 |
|
760 | 760 |
// Initialize delta value |
761 |
if ( |
|
761 |
if (_factor > 1) { |
|
762 | 762 |
// With scaling |
763 | 763 |
Value max_sup = 0, max_dem = 0; |
764 | 764 |
for (int i = 0; i != _node_num; ++i) { |
765 | 765 |
if ( _excess[i] > max_sup) max_sup = _excess[i]; |
766 | 766 |
if (-_excess[i] > max_dem) max_dem = -_excess[i]; |
767 | 767 |
} |
768 | 768 |
Value max_cap = 0; |
769 | 769 |
for (int j = 0; j != _res_arc_num; ++j) { |
770 | 770 |
if (_res_cap[j] > max_cap) max_cap = _res_cap[j]; |
771 | 771 |
} |
772 | 772 |
max_sup = std::min(std::min(max_sup, max_dem), max_cap); |
773 |
_phase_num = 0; |
|
774 |
for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) |
|
775 |
|
|
773 |
for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ; |
|
776 | 774 |
} else { |
777 | 775 |
// Without scaling |
778 | 776 |
_delta = 1; |
779 | 777 |
} |
780 | 778 |
|
781 | 779 |
return OPTIMAL; |
782 | 780 |
} |
783 | 781 |
|
784 | 782 |
ProblemType start() { |
785 | 783 |
// Execute the algorithm |
786 | 784 |
ProblemType pt; |
787 | 785 |
if (_delta > 1) |
788 | 786 |
pt = startWithScaling(); |
789 | 787 |
else |
790 | 788 |
pt = startWithoutScaling(); |
791 | 789 |
|
792 | 790 |
// Handle non-zero lower bounds |
793 | 791 |
if (_have_lower) { |
794 | 792 |
for (int j = 0; j != _res_arc_num - _node_num + 1; ++j) { |
795 | 793 |
if (!_forward[j]) _res_cap[j] += _lower[j]; |
796 | 794 |
} |
797 | 795 |
} |
798 | 796 |
|
799 | 797 |
// Shift potentials if necessary |
800 | 798 |
Cost pr = _pi[_root]; |
801 | 799 |
if (_sum_supply < 0 || pr > 0) { |
802 | 800 |
for (int i = 0; i != _node_num; ++i) { |
803 | 801 |
_pi[i] -= pr; |
804 | 802 |
} |
805 | 803 |
} |
806 | 804 |
|
807 | 805 |
return pt; |
808 | 806 |
} |
809 | 807 |
|
810 | 808 |
// Execute the capacity scaling algorithm |
811 | 809 |
ProblemType startWithScaling() { |
812 | 810 |
// Perform capacity scaling phases |
813 | 811 |
int s, t; |
814 |
int phase_cnt = 0; |
|
815 |
int factor = 4; |
|
816 | 812 |
ResidualDijkstra _dijkstra(*this); |
817 | 813 |
while (true) { |
818 | 814 |
// Saturate all arcs not satisfying the optimality condition |
819 | 815 |
for (int u = 0; u != _node_num; ++u) { |
820 | 816 |
for (int a = _first_out[u]; a != _first_out[u+1]; ++a) { |
821 | 817 |
int v = _target[a]; |
822 | 818 |
Cost c = _cost[a] + _pi[u] - _pi[v]; |
823 | 819 |
Value rc = _res_cap[a]; |
824 | 820 |
if (c < 0 && rc >= _delta) { |
825 | 821 |
_excess[u] -= rc; |
826 | 822 |
_excess[v] += rc; |
827 | 823 |
_res_cap[a] = 0; |
828 | 824 |
_res_cap[_reverse[a]] += rc; |
829 | 825 |
} |
830 | 826 |
} |
831 | 827 |
} |
832 | 828 |
|
833 | 829 |
// Find excess nodes and deficit nodes |
834 | 830 |
_excess_nodes.clear(); |
835 | 831 |
_deficit_nodes.clear(); |
836 | 832 |
for (int u = 0; u != _node_num; ++u) { |
837 | 833 |
if (_excess[u] >= _delta) _excess_nodes.push_back(u); |
838 | 834 |
if (_excess[u] <= -_delta) _deficit_nodes.push_back(u); |
839 | 835 |
} |
... | ... |
@@ -866,50 +862,49 @@ |
866 | 862 |
|
867 | 863 |
// Augment along a shortest path from s to t |
868 | 864 |
Value d = std::min(_excess[s], -_excess[t]); |
869 | 865 |
int u = t; |
870 | 866 |
int a; |
871 | 867 |
if (d > _delta) { |
872 | 868 |
while ((a = _pred[u]) != -1) { |
873 | 869 |
if (_res_cap[a] < d) d = _res_cap[a]; |
874 | 870 |
u = _source[a]; |
875 | 871 |
} |
876 | 872 |
} |
877 | 873 |
u = t; |
878 | 874 |
while ((a = _pred[u]) != -1) { |
879 | 875 |
_res_cap[a] -= d; |
880 | 876 |
_res_cap[_reverse[a]] += d; |
881 | 877 |
u = _source[a]; |
882 | 878 |
} |
883 | 879 |
_excess[s] -= d; |
884 | 880 |
_excess[t] += d; |
885 | 881 |
|
886 | 882 |
if (_excess[s] < _delta) ++next_node; |
887 | 883 |
} |
888 | 884 |
|
889 | 885 |
if (_delta == 1) break; |
890 |
if (++phase_cnt == _phase_num / 4) factor = 2; |
|
891 |
_delta = _delta <= factor ? 1 : _delta / factor; |
|
886 |
_delta = _delta <= _factor ? 1 : _delta / _factor; |
|
892 | 887 |
} |
893 | 888 |
|
894 | 889 |
return OPTIMAL; |
895 | 890 |
} |
896 | 891 |
|
897 | 892 |
// Execute the successive shortest path algorithm |
898 | 893 |
ProblemType startWithoutScaling() { |
899 | 894 |
// Find excess nodes |
900 | 895 |
_excess_nodes.clear(); |
901 | 896 |
for (int i = 0; i != _node_num; ++i) { |
902 | 897 |
if (_excess[i] > 0) _excess_nodes.push_back(i); |
903 | 898 |
} |
904 | 899 |
if (_excess_nodes.size() == 0) return OPTIMAL; |
905 | 900 |
int next_node = 0; |
906 | 901 |
|
907 | 902 |
// Find shortest paths |
908 | 903 |
int s, t; |
909 | 904 |
ResidualDijkstra _dijkstra(*this); |
910 | 905 |
while ( _excess[_excess_nodes[next_node]] > 0 || |
911 | 906 |
++next_node < int(_excess_nodes.size()) ) |
912 | 907 |
{ |
913 | 908 |
// Run Dijkstra in the residual network |
914 | 909 |
s = _excess_nodes[next_node]; |
915 | 910 |
if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE; |
... | ... |
@@ -89,48 +89,52 @@ |
89 | 89 |
/// \brief Implementation of the Cost Scaling algorithm for |
90 | 90 |
/// finding a \ref min_cost_flow "minimum cost flow". |
91 | 91 |
/// |
92 | 92 |
/// \ref CostScaling implements a cost scaling algorithm that performs |
93 | 93 |
/// push/augment and relabel operations for finding a minimum cost |
94 | 94 |
/// flow. It is an efficient primal-dual solution method, which |
95 | 95 |
/// can be viewed as the generalization of the \ref Preflow |
96 | 96 |
/// "preflow push-relabel" algorithm for the maximum flow problem. |
97 | 97 |
/// |
98 | 98 |
/// Most of the parameters of the problem (except for the digraph) |
99 | 99 |
/// can be given using separate functions, and the algorithm can be |
100 | 100 |
/// executed using the \ref run() function. If some parameters are not |
101 | 101 |
/// specified, then default values will be used. |
102 | 102 |
/// |
103 | 103 |
/// \tparam GR The digraph type the algorithm runs on. |
104 | 104 |
/// \tparam V The value type used for flow amounts, capacity bounds |
105 | 105 |
/// and supply values in the algorithm. By default it is \c int. |
106 | 106 |
/// \tparam C The value type used for costs and potentials in the |
107 | 107 |
/// algorithm. By default it is the same as \c V. |
108 | 108 |
/// |
109 | 109 |
/// \warning Both value types must be signed and all input data must |
110 | 110 |
/// be integer. |
111 | 111 |
/// \warning This algorithm does not support negative costs for such |
112 | 112 |
/// arcs that have infinite upper bound. |
113 |
/// |
|
114 |
/// \note %CostScaling provides three different internal methods, |
|
115 |
/// from which the most efficient one is used by default. |
|
116 |
/// For more information, see \ref Method. |
|
113 | 117 |
#ifdef DOXYGEN |
114 | 118 |
template <typename GR, typename V, typename C, typename TR> |
115 | 119 |
#else |
116 | 120 |
template < typename GR, typename V = int, typename C = V, |
117 | 121 |
typename TR = CostScalingDefaultTraits<GR, V, C> > |
118 | 122 |
#endif |
119 | 123 |
class CostScaling |
120 | 124 |
{ |
121 | 125 |
public: |
122 | 126 |
|
123 | 127 |
/// The type of the digraph |
124 | 128 |
typedef typename TR::Digraph Digraph; |
125 | 129 |
/// The type of the flow amounts, capacity bounds and supply values |
126 | 130 |
typedef typename TR::Value Value; |
127 | 131 |
/// The type of the arc costs |
128 | 132 |
typedef typename TR::Cost Cost; |
129 | 133 |
|
130 | 134 |
/// \brief The large cost type |
131 | 135 |
/// |
132 | 136 |
/// The large cost type used for internal computations. |
133 | 137 |
/// Using the \ref CostScalingDefaultTraits "default traits class", |
134 | 138 |
/// it is \c long \c long if the \c Cost type is integer, |
135 | 139 |
/// otherwise it is \c double. |
136 | 140 |
typedef typename TR::LargeCost LargeCost; |
... | ... |
@@ -138,48 +142,75 @@ |
138 | 142 |
/// The \ref CostScalingDefaultTraits "traits class" of the algorithm |
139 | 143 |
typedef TR Traits; |
140 | 144 |
|
141 | 145 |
public: |
142 | 146 |
|
143 | 147 |
/// \brief Problem type constants for the \c run() function. |
144 | 148 |
/// |
145 | 149 |
/// Enum type containing the problem type constants that can be |
146 | 150 |
/// returned by the \ref run() function of the algorithm. |
147 | 151 |
enum ProblemType { |
148 | 152 |
/// The problem has no feasible solution (flow). |
149 | 153 |
INFEASIBLE, |
150 | 154 |
/// The problem has optimal solution (i.e. it is feasible and |
151 | 155 |
/// bounded), and the algorithm has found optimal flow and node |
152 | 156 |
/// potentials (primal and dual solutions). |
153 | 157 |
OPTIMAL, |
154 | 158 |
/// The digraph contains an arc of negative cost and infinite |
155 | 159 |
/// upper bound. It means that the objective function is unbounded |
156 | 160 |
/// on that arc, however note that it could actually be bounded |
157 | 161 |
/// over the feasible flows, but this algroithm cannot handle |
158 | 162 |
/// these cases. |
159 | 163 |
UNBOUNDED |
160 | 164 |
}; |
161 | 165 |
|
166 |
/// \brief Constants for selecting the internal method. |
|
167 |
/// |
|
168 |
/// Enum type containing constants for selecting the internal method |
|
169 |
/// for the \ref run() function. |
|
170 |
/// |
|
171 |
/// \ref CostScaling provides three internal methods that differ mainly |
|
172 |
/// in their base operations, which are used in conjunction with the |
|
173 |
/// relabel operation. |
|
174 |
/// By default, the so called \ref PARTIAL_AUGMENT |
|
175 |
/// "Partial Augment-Relabel" method is used, which proved to be |
|
176 |
/// the most efficient and the most robust on various test inputs. |
|
177 |
/// However, the other methods can be selected using the \ref run() |
|
178 |
/// function with the proper parameter. |
|
179 |
enum Method { |
|
180 |
/// Local push operations are used, i.e. flow is moved only on one |
|
181 |
/// admissible arc at once. |
|
182 |
PUSH, |
|
183 |
/// Augment operations are used, i.e. flow is moved on admissible |
|
184 |
/// paths from a node with excess to a node with deficit. |
|
185 |
AUGMENT, |
|
186 |
/// Partial augment operations are used, i.e. flow is moved on |
|
187 |
/// admissible paths started from a node with excess, but the |
|
188 |
/// lengths of these paths are limited. This method can be viewed |
|
189 |
/// as a combined version of the previous two operations. |
|
190 |
PARTIAL_AUGMENT |
|
191 |
}; |
|
192 |
|
|
162 | 193 |
private: |
163 | 194 |
|
164 | 195 |
TEMPLATE_DIGRAPH_TYPEDEFS(GR); |
165 | 196 |
|
166 | 197 |
typedef std::vector<int> IntVector; |
167 | 198 |
typedef std::vector<char> BoolVector; |
168 | 199 |
typedef std::vector<Value> ValueVector; |
169 | 200 |
typedef std::vector<Cost> CostVector; |
170 | 201 |
typedef std::vector<LargeCost> LargeCostVector; |
171 | 202 |
|
172 | 203 |
private: |
173 | 204 |
|
174 | 205 |
template <typename KT, typename VT> |
175 | 206 |
class VectorMap { |
176 | 207 |
public: |
177 | 208 |
typedef KT Key; |
178 | 209 |
typedef VT Value; |
179 | 210 |
|
180 | 211 |
VectorMap(std::vector<Value>& v) : _v(v) {} |
181 | 212 |
|
182 | 213 |
const Value& operator[](const Key& key) const { |
183 | 214 |
return _v[StaticDigraph::id(key)]; |
184 | 215 |
} |
185 | 216 |
|
... | ... |
@@ -484,71 +515,71 @@ |
484 | 515 |
|
485 | 516 |
/// @} |
486 | 517 |
|
487 | 518 |
/// \name Execution control |
488 | 519 |
/// The algorithm can be executed using \ref run(). |
489 | 520 |
|
490 | 521 |
/// @{ |
491 | 522 |
|
492 | 523 |
/// \brief Run the algorithm. |
493 | 524 |
/// |
494 | 525 |
/// This function runs the algorithm. |
495 | 526 |
/// The paramters can be specified using functions \ref lowerMap(), |
496 | 527 |
/// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). |
497 | 528 |
/// For example, |
498 | 529 |
/// \code |
499 | 530 |
/// CostScaling<ListDigraph> cs(graph); |
500 | 531 |
/// cs.lowerMap(lower).upperMap(upper).costMap(cost) |
501 | 532 |
/// .supplyMap(sup).run(); |
502 | 533 |
/// \endcode |
503 | 534 |
/// |
504 | 535 |
/// This function can be called more than once. All the parameters |
505 | 536 |
/// that have been given are kept for the next call, unless |
506 | 537 |
/// \ref reset() is called, thus only the modified parameters |
507 | 538 |
/// have to be set again. See \ref reset() for examples. |
508 |
/// However the underlying digraph must not be modified after this |
|
509 |
/// class have been constructed, since it copies the digraph. |
|
539 |
/// However, the underlying digraph must not be modified after this |
|
540 |
/// class have been constructed, since it copies and extends the graph. |
|
510 | 541 |
/// |
511 |
/// \param partial_augment By default the algorithm performs |
|
512 |
/// partial augment and relabel operations in the cost scaling |
|
513 |
/// phases. Set this parameter to \c false for using local push and |
|
514 |
/// relabel operations instead. |
|
542 |
/// \param method The internal method that will be used in the |
|
543 |
/// algorithm. For more information, see \ref Method. |
|
544 |
/// \param factor The cost scaling factor. It must be larger than one. |
|
515 | 545 |
/// |
516 | 546 |
/// \return \c INFEASIBLE if no feasible flow exists, |
517 | 547 |
/// \n \c OPTIMAL if the problem has optimal solution |
518 | 548 |
/// (i.e. it is feasible and bounded), and the algorithm has found |
519 | 549 |
/// optimal flow and node potentials (primal and dual solutions), |
520 | 550 |
/// \n \c UNBOUNDED if the digraph contains an arc of negative cost |
521 | 551 |
/// and infinite upper bound. It means that the objective function |
522 | 552 |
/// is unbounded on that arc, however note that it could actually be |
523 | 553 |
/// bounded over the feasible flows, but this algroithm cannot handle |
524 | 554 |
/// these cases. |
525 | 555 |
/// |
526 |
/// \see ProblemType |
|
527 |
ProblemType run(bool partial_augment = true) { |
|
556 |
/// \see ProblemType, Method |
|
557 |
ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) { |
|
558 |
_alpha = factor; |
|
528 | 559 |
ProblemType pt = init(); |
529 | 560 |
if (pt != OPTIMAL) return pt; |
530 |
start( |
|
561 |
start(method); |
|
531 | 562 |
return OPTIMAL; |
532 | 563 |
} |
533 | 564 |
|
534 | 565 |
/// \brief Reset all the parameters that have been given before. |
535 | 566 |
/// |
536 | 567 |
/// This function resets all the paramaters that have been given |
537 | 568 |
/// before using functions \ref lowerMap(), \ref upperMap(), |
538 | 569 |
/// \ref costMap(), \ref supplyMap(), \ref stSupply(). |
539 | 570 |
/// |
540 | 571 |
/// It is useful for multiple run() calls. If this function is not |
541 | 572 |
/// used, all the parameters given before are kept for the next |
542 | 573 |
/// \ref run() call. |
543 | 574 |
/// However the underlying digraph must not be modified after this |
544 | 575 |
/// class have been constructed, since it copies and extends the graph. |
545 | 576 |
/// |
546 | 577 |
/// For example, |
547 | 578 |
/// \code |
548 | 579 |
/// CostScaling<ListDigraph> cs(graph); |
549 | 580 |
/// |
550 | 581 |
/// // First run |
551 | 582 |
/// cs.lowerMap(lower).upperMap(upper).costMap(cost) |
552 | 583 |
/// .supplyMap(sup).run(); |
553 | 584 |
/// |
554 | 585 |
/// // Run again with modified cost map (reset() is not called, |
... | ... |
@@ -660,51 +691,48 @@ |
660 | 691 |
|
661 | 692 |
/// \brief Return the potential map (the dual solution). |
662 | 693 |
/// |
663 | 694 |
/// This function copies the potential (dual value) of each node |
664 | 695 |
/// into the given map. |
665 | 696 |
/// The \c Cost type of the algorithm must be convertible to the |
666 | 697 |
/// \c Value type of the map. |
667 | 698 |
/// |
668 | 699 |
/// \pre \ref run() must be called before using this function. |
669 | 700 |
template <typename PotentialMap> |
670 | 701 |
void potentialMap(PotentialMap &map) const { |
671 | 702 |
for (NodeIt n(_graph); n != INVALID; ++n) { |
672 | 703 |
map.set(n, static_cast<Cost>(_pi[_node_id[n]])); |
673 | 704 |
} |
674 | 705 |
} |
675 | 706 |
|
676 | 707 |
/// @} |
677 | 708 |
|
678 | 709 |
private: |
679 | 710 |
|
680 | 711 |
// Initialize the algorithm |
681 | 712 |
ProblemType init() { |
682 | 713 |
if (_res_node_num == 0) return INFEASIBLE; |
683 | 714 |
|
684 |
// Scaling factor |
|
685 |
_alpha = 8; |
|
686 |
|
|
687 | 715 |
// Check the sum of supply values |
688 | 716 |
_sum_supply = 0; |
689 | 717 |
for (int i = 0; i != _root; ++i) { |
690 | 718 |
_sum_supply += _supply[i]; |
691 | 719 |
} |
692 | 720 |
if (_sum_supply > 0) return INFEASIBLE; |
693 | 721 |
|
694 | 722 |
|
695 | 723 |
// Initialize vectors |
696 | 724 |
for (int i = 0; i != _res_node_num; ++i) { |
697 | 725 |
_pi[i] = 0; |
698 | 726 |
_excess[i] = _supply[i]; |
699 | 727 |
} |
700 | 728 |
|
701 | 729 |
// Remove infinite upper bounds and check negative arcs |
702 | 730 |
const Value MAX = std::numeric_limits<Value>::max(); |
703 | 731 |
int last_out; |
704 | 732 |
if (_have_lower) { |
705 | 733 |
for (int i = 0; i != _root; ++i) { |
706 | 734 |
last_out = _first_out[i+1]; |
707 | 735 |
for (int j = _first_out[i]; j != last_out; ++j) { |
708 | 736 |
if (_forward[j]) { |
709 | 737 |
Value c = _scost[j] < 0 ? _upper[j] : _lower[j]; |
710 | 738 |
if (c >= MAX) return UNBOUNDED; |
... | ... |
@@ -796,90 +824,96 @@ |
796 | 824 |
_res_cap[ra] = -_excess[u]; |
797 | 825 |
_cost[a] = 0; |
798 | 826 |
_cost[ra] = 0; |
799 | 827 |
_excess[u] = 0; |
800 | 828 |
} |
801 | 829 |
} else { |
802 | 830 |
for (ArcIt a(_graph); a != INVALID; ++a) { |
803 | 831 |
Value fa = flow[a]; |
804 | 832 |
_res_cap[_arc_idf[a]] = cap[a] - fa; |
805 | 833 |
_res_cap[_arc_idb[a]] = fa; |
806 | 834 |
} |
807 | 835 |
for (int a = _first_out[_root]; a != _res_arc_num; ++a) { |
808 | 836 |
int ra = _reverse[a]; |
809 | 837 |
_res_cap[a] = 1; |
810 | 838 |
_res_cap[ra] = 0; |
811 | 839 |
_cost[a] = 0; |
812 | 840 |
_cost[ra] = 0; |
813 | 841 |
} |
814 | 842 |
} |
815 | 843 |
|
816 | 844 |
return OPTIMAL; |
817 | 845 |
} |
818 | 846 |
|
819 | 847 |
// Execute the algorithm and transform the results |
820 |
void start( |
|
848 |
void start(Method method) { |
|
849 |
// Maximum path length for partial augment |
|
850 |
const int MAX_PATH_LENGTH = 4; |
|
851 |
|
|
821 | 852 |
// Execute the algorithm |
822 |
if (partial_augment) { |
|
823 |
startPartialAugment(); |
|
824 |
} else { |
|
825 |
startPushRelabel(); |
|
853 |
switch (method) { |
|
854 |
case PUSH: |
|
855 |
startPush(); |
|
856 |
break; |
|
857 |
case AUGMENT: |
|
858 |
startAugment(); |
|
859 |
break; |
|
860 |
case PARTIAL_AUGMENT: |
|
861 |
startAugment(MAX_PATH_LENGTH); |
|
862 |
break; |
|
826 | 863 |
} |
827 | 864 |
|
828 | 865 |
// Compute node potentials for the original costs |
829 | 866 |
_arc_vec.clear(); |
830 | 867 |
_cost_vec.clear(); |
831 | 868 |
for (int j = 0; j != _res_arc_num; ++j) { |
832 | 869 |
if (_res_cap[j] > 0) { |
833 | 870 |
_arc_vec.push_back(IntPair(_source[j], _target[j])); |
834 | 871 |
_cost_vec.push_back(_scost[j]); |
835 | 872 |
} |
836 | 873 |
} |
837 | 874 |
_sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); |
838 | 875 |
|
839 | 876 |
typename BellmanFord<StaticDigraph, LargeCostArcMap> |
840 | 877 |
::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map); |
841 | 878 |
bf.distMap(_pi_map); |
842 | 879 |
bf.init(0); |
843 | 880 |
bf.start(); |
844 | 881 |
|
845 | 882 |
// Handle non-zero lower bounds |
846 | 883 |
if (_have_lower) { |
847 | 884 |
int limit = _first_out[_root]; |
848 | 885 |
for (int j = 0; j != limit; ++j) { |
849 | 886 |
if (!_forward[j]) _res_cap[j] += _lower[j]; |
850 | 887 |
} |
851 | 888 |
} |
852 | 889 |
} |
853 | 890 |
|
854 |
/// Execute the algorithm performing partial augmentation and |
|
855 |
/// relabel operations |
|
856 |
|
|
891 |
/// Execute the algorithm performing augment and relabel operations |
|
892 |
void startAugment(int max_length = std::numeric_limits<int>::max()) { |
|
857 | 893 |
// Paramters for heuristics |
858 | 894 |
const int BF_HEURISTIC_EPSILON_BOUND = 1000; |
859 | 895 |
const int BF_HEURISTIC_BOUND_FACTOR = 3; |
860 |
// Maximum augment path length |
|
861 |
const int MAX_PATH_LENGTH = 4; |
|
862 | 896 |
|
863 | 897 |
// Perform cost scaling phases |
864 | 898 |
IntVector pred_arc(_res_node_num); |
865 | 899 |
std::vector<int> path_nodes; |
866 | 900 |
for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? |
867 | 901 |
1 : _epsilon / _alpha ) |
868 | 902 |
{ |
869 | 903 |
// "Early Termination" heuristic: use Bellman-Ford algorithm |
870 | 904 |
// to check if the current flow is optimal |
871 | 905 |
if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) { |
872 | 906 |
_arc_vec.clear(); |
873 | 907 |
_cost_vec.clear(); |
874 | 908 |
for (int j = 0; j != _res_arc_num; ++j) { |
875 | 909 |
if (_res_cap[j] > 0) { |
876 | 910 |
_arc_vec.push_back(IntPair(_source[j], _target[j])); |
877 | 911 |
_cost_vec.push_back(_cost[j] + 1); |
878 | 912 |
} |
879 | 913 |
} |
880 | 914 |
_sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); |
881 | 915 |
|
882 | 916 |
BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map); |
883 | 917 |
bf.init(0); |
884 | 918 |
bool done = false; |
885 | 919 |
int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num)); |
... | ... |
@@ -904,49 +938,49 @@ |
904 | 938 |
for (int u = 0; u != _res_node_num; ++u) { |
905 | 939 |
if (_excess[u] > 0) _active_nodes.push_back(u); |
906 | 940 |
} |
907 | 941 |
|
908 | 942 |
// Initialize the next arcs |
909 | 943 |
for (int u = 0; u != _res_node_num; ++u) { |
910 | 944 |
_next_out[u] = _first_out[u]; |
911 | 945 |
} |
912 | 946 |
|
913 | 947 |
// Perform partial augment and relabel operations |
914 | 948 |
while (true) { |
915 | 949 |
// Select an active node (FIFO selection) |
916 | 950 |
while (_active_nodes.size() > 0 && |
917 | 951 |
_excess[_active_nodes.front()] <= 0) { |
918 | 952 |
_active_nodes.pop_front(); |
919 | 953 |
} |
920 | 954 |
if (_active_nodes.size() == 0) break; |
921 | 955 |
int start = _active_nodes.front(); |
922 | 956 |
path_nodes.clear(); |
923 | 957 |
path_nodes.push_back(start); |
924 | 958 |
|
925 | 959 |
// Find an augmenting path from the start node |
926 | 960 |
int tip = start; |
927 | 961 |
while (_excess[tip] >= 0 && |
928 |
int(path_nodes.size()) <= |
|
962 |
int(path_nodes.size()) <= max_length) { |
|
929 | 963 |
int u; |
930 | 964 |
LargeCost min_red_cost, rc; |
931 | 965 |
int last_out = _sum_supply < 0 ? |
932 | 966 |
_first_out[tip+1] : _first_out[tip+1] - 1; |
933 | 967 |
for (int a = _next_out[tip]; a != last_out; ++a) { |
934 | 968 |
if (_res_cap[a] > 0 && |
935 | 969 |
_cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) { |
936 | 970 |
u = _target[a]; |
937 | 971 |
pred_arc[u] = a; |
938 | 972 |
_next_out[tip] = a; |
939 | 973 |
tip = u; |
940 | 974 |
path_nodes.push_back(tip); |
941 | 975 |
goto next_step; |
942 | 976 |
} |
943 | 977 |
} |
944 | 978 |
|
945 | 979 |
// Relabel tip node |
946 | 980 |
min_red_cost = std::numeric_limits<LargeCost>::max() / 2; |
947 | 981 |
for (int a = _first_out[tip]; a != last_out; ++a) { |
948 | 982 |
rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]]; |
949 | 983 |
if (_res_cap[a] > 0 && rc < min_red_cost) { |
950 | 984 |
min_red_cost = rc; |
951 | 985 |
} |
952 | 986 |
} |
... | ... |
@@ -963,49 +997,49 @@ |
963 | 997 |
|
964 | 998 |
next_step: ; |
965 | 999 |
} |
966 | 1000 |
|
967 | 1001 |
// Augment along the found path (as much flow as possible) |
968 | 1002 |
Value delta; |
969 | 1003 |
int u, v = path_nodes.front(), pa; |
970 | 1004 |
for (int i = 1; i < int(path_nodes.size()); ++i) { |
971 | 1005 |
u = v; |
972 | 1006 |
v = path_nodes[i]; |
973 | 1007 |
pa = pred_arc[v]; |
974 | 1008 |
delta = std::min(_res_cap[pa], _excess[u]); |
975 | 1009 |
_res_cap[pa] -= delta; |
976 | 1010 |
_res_cap[_reverse[pa]] += delta; |
977 | 1011 |
_excess[u] -= delta; |
978 | 1012 |
_excess[v] += delta; |
979 | 1013 |
if (_excess[v] > 0 && _excess[v] <= delta) |
980 | 1014 |
_active_nodes.push_back(v); |
981 | 1015 |
} |
982 | 1016 |
} |
983 | 1017 |
} |
984 | 1018 |
} |
985 | 1019 |
|
986 | 1020 |
/// Execute the algorithm performing push and relabel operations |
987 |
void |
|
1021 |
void startPush() { |
|
988 | 1022 |
// Paramters for heuristics |
989 | 1023 |
const int BF_HEURISTIC_EPSILON_BOUND = 1000; |
990 | 1024 |
const int BF_HEURISTIC_BOUND_FACTOR = 3; |
991 | 1025 |
|
992 | 1026 |
// Perform cost scaling phases |
993 | 1027 |
BoolVector hyper(_res_node_num, false); |
994 | 1028 |
for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? |
995 | 1029 |
1 : _epsilon / _alpha ) |
996 | 1030 |
{ |
997 | 1031 |
// "Early Termination" heuristic: use Bellman-Ford algorithm |
998 | 1032 |
// to check if the current flow is optimal |
999 | 1033 |
if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) { |
1000 | 1034 |
_arc_vec.clear(); |
1001 | 1035 |
_cost_vec.clear(); |
1002 | 1036 |
for (int j = 0; j != _res_arc_num; ++j) { |
1003 | 1037 |
if (_res_cap[j] > 0) { |
1004 | 1038 |
_arc_vec.push_back(IntPair(_source[j], _target[j])); |
1005 | 1039 |
_cost_vec.push_back(_cost[j] + 1); |
1006 | 1040 |
} |
1007 | 1041 |
} |
1008 | 1042 |
_sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); |
1009 | 1043 |
|
1010 | 1044 |
BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map); |
1011 | 1045 |
bf.init(0); |
0 comments (0 inline)