<ahref="linear__assignment_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aname="l00001"></a><spanclass="lineno"> 1</span> <spanclass="comment">// Copyright 2010-2021 Google LLC</span></div>
<divclass="line"><aname="l00002"></a><spanclass="lineno"> 2</span> <spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aname="l00003"></a><spanclass="lineno"> 3</span> <spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aname="l00004"></a><spanclass="lineno"> 4</span> <spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aname="l00008"></a><spanclass="lineno"> 8</span> <spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aname="l00009"></a><spanclass="lineno"> 9</span> <spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aname="l00010"></a><spanclass="lineno"> 10</span> <spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aname="l00011"></a><spanclass="lineno"> 11</span> <spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aname="l00012"></a><spanclass="lineno"> 12</span> <spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aname="l00015"></a><spanclass="lineno"> 15</span> <spanclass="comment">// An implementation of a cost-scaling push-relabel algorithm for the</span></div>
<divclass="line"><aname="l00016"></a><spanclass="lineno"> 16</span> <spanclass="comment">// assignment problem (minimum-cost perfect bipartite matching), from</span></div>
<divclass="line"><aname="l00017"></a><spanclass="lineno"> 17</span> <spanclass="comment">// the paper of Goldberg and Kennedy (1995).</span></div>
<divclass="line"><aname="l00020"></a><spanclass="lineno"> 20</span> <spanclass="comment">// This implementation finds the minimum-cost perfect assignment in</span></div>
<divclass="line"><aname="l00021"></a><spanclass="lineno"> 21</span> <spanclass="comment">// the given graph with integral edge weights set through the</span></div>
<divclass="line"><aname="l00024"></a><spanclass="lineno"> 24</span> <spanclass="comment">// The running time is O(n*m*log(nC)) where n is the number of nodes,</span></div>
<divclass="line"><aname="l00025"></a><spanclass="lineno"> 25</span> <spanclass="comment">// m is the number of edges, and C is the largest magnitude of an edge cost.</span></div>
<divclass="line"><aname="l00026"></a><spanclass="lineno"> 26</span> <spanclass="comment">// In principle it can be worse than the Hungarian algorithm but we don't know</span></div>
<divclass="line"><aname="l00027"></a><spanclass="lineno"> 27</span> <spanclass="comment">// of any class of problems where that actually happens. An additional sqrt(n)</span></div>
<divclass="line"><aname="l00028"></a><spanclass="lineno"> 28</span> <spanclass="comment">// factor could be shaved off the running time bound using the technique</span></div>
<divclass="line"><aname="l00029"></a><spanclass="lineno"> 29</span> <spanclass="comment">// described in http://dx.doi.org/10.1137/S0895480194281185</span></div>
<divclass="line"><aname="l00030"></a><spanclass="lineno"> 30</span> <spanclass="comment">// (see also http://theory.stanford.edu/~robert/papers/glob_upd.ps).</span></div>
<divclass="line"><aname="l00048"></a><spanclass="lineno"> 48</span> <spanclass="comment">// const int arc_tail = ... // must be in [0, num_left_nodes)</span></div>
<divclass="line"><aname="l00049"></a><spanclass="lineno"> 49</span> <spanclass="comment">// const int arc_head = ... // must be in [num_left_nodes, num_nodes)</span></div>
<divclass="line"><aname="l00054"></a><spanclass="lineno"> 54</span> <spanclass="comment">// // Build the StaticGraph. You can skip this step by using a ListGraph<></span></div>
<divclass="line"><aname="l00055"></a><spanclass="lineno"> 55</span> <spanclass="comment">// // instead, but then the ComputeAssignment() below will be slower. It is</span></div>
<divclass="line"><aname="l00056"></a><spanclass="lineno"> 56</span> <spanclass="comment">// // okay if your graph is small and performance is not critical though.</span></div>
<divclass="line"><aname="l00066"></a><spanclass="lineno"> 66</span> <spanclass="comment">// // You can also replace 'arc_costs[arc]' by something like</span></div>
<divclass="line"><aname="l00068"></a><spanclass="lineno"> 68</span> <spanclass="comment">// // if you don't want to store the costs in arc_costs to save memory.</span></div>
<divclass="line"><aname="l00074"></a><spanclass="lineno"> 74</span> <spanclass="comment">// // Retrieve the cost of the optimum assignment.</span></div>
<divclass="line"><aname="l00076"></a><spanclass="lineno"> 76</span> <spanclass="comment">// // Retrieve the node-node correspondence of the optimum assignment and the</span></div>
<divclass="line"><aname="l00077"></a><spanclass="lineno"> 77</span> <spanclass="comment">// // cost of each node pairing.</span></div>
<divclass="line"><aname="l00085"></a><spanclass="lineno"> 85</span> <spanclass="comment">// In the following, we consider a bipartite graph</span></div>
<divclass="line"><aname="l00086"></a><spanclass="lineno"> 86</span> <spanclass="comment">// G = (V = X union Y, E subset XxY),</span></div>
<divclass="line"><aname="l00087"></a><spanclass="lineno"> 87</span> <spanclass="comment">// where V denotes the set of nodes (vertices) in the graph, E denotes</span></div>
<divclass="line"><aname="l00088"></a><spanclass="lineno"> 88</span> <spanclass="comment">// the set of arcs (edges), n = |V| denotes the number of nodes in the</span></div>
<divclass="line"><aname="l00089"></a><spanclass="lineno"> 89</span> <spanclass="comment">// graph, and m = |E| denotes the number of arcs in the graph.</span></div>
<divclass="line"><aname="l00091"></a><spanclass="lineno"> 91</span> <spanclass="comment">// The set of nodes is divided into two parts, X and Y, and every arc</span></div>
<divclass="line"><aname="l00092"></a><spanclass="lineno"> 92</span> <spanclass="comment">// must go between a node of X and a node of Y. With each arc is</span></div>
<divclass="line"><aname="l00093"></a><spanclass="lineno"> 93</span> <spanclass="comment">// associated a cost c(v, w). A matching M is a subset of E with the</span></div>
<divclass="line"><aname="l00094"></a><spanclass="lineno"> 94</span> <spanclass="comment">// property that no two arcs in M have a head or tail node in common,</span></div>
<divclass="line"><aname="l00095"></a><spanclass="lineno"> 95</span> <spanclass="comment">// and a perfect matching is a matching that touches every node in the</span></div>
<divclass="line"><aname="l00096"></a><spanclass="lineno"> 96</span> <spanclass="comment">// graph. The cost of a matching M is the sum of the costs of all the</span></div>
<divclass="line"><aname="l00097"></a><spanclass="lineno"> 97</span> <spanclass="comment">// arcs in M.</span></div>
<divclass="line"><aname="l00099"></a><spanclass="lineno"> 99</span> <spanclass="comment">// The assignment problem is to find a perfect matching of minimum</span></div>
<divclass="line"><aname="l00100"></a><spanclass="lineno"> 100</span> <spanclass="comment">// cost in the given bipartite graph. The present algorithm reduces</span></div>
<divclass="line"><aname="l00101"></a><spanclass="lineno"> 101</span> <spanclass="comment">// the assignment problem to an instance of the minimum-cost flow</span></div>
<divclass="line"><aname="l00102"></a><spanclass="lineno"> 102</span> <spanclass="comment">// problem and takes advantage of special properties of the resulting</span></div>
<divclass="line"><aname="l00103"></a><spanclass="lineno"> 103</span> <spanclass="comment">// minimum-cost flow problem to solve it efficiently using a</span></div>
<divclass="line"><aname="l00104"></a><spanclass="lineno"> 104</span> <spanclass="comment">// push-relabel method. For more information about minimum-cost flow</span></div>
<divclass="line"><aname="l00105"></a><spanclass="lineno"> 105</span> <spanclass="comment">// see google3/ortools/graph/min_cost_flow.h</span></div>
<divclass="line"><aname="l00107"></a><spanclass="lineno"> 107</span> <spanclass="comment">// The method used here is the cost-scaling approach for the</span></div>
<divclass="line"><aname="l00108"></a><spanclass="lineno"> 108</span> <spanclass="comment">// minimum-cost circulation problem as described in [Goldberg and</span></div>
<divclass="line"><aname="l00109"></a><spanclass="lineno"> 109</span> <spanclass="comment">// Tarjan] with some technical modifications:</span></div>
<divclass="line"><aname="l00110"></a><spanclass="lineno"> 110</span> <spanclass="comment">// 1. For efficiency, we solve a transportation problem instead of</span></div>
<divclass="line"><aname="l00111"></a><spanclass="lineno"> 111</span> <spanclass="comment">// minimum-cost circulation. We might revisit this decision if it</span></div>
<divclass="line"><aname="l00112"></a><spanclass="lineno"> 112</span> <spanclass="comment">// is important to handle problems in which no perfect matching</span></div>
<divclass="line"><aname="l00114"></a><spanclass="lineno"> 114</span> <spanclass="comment">// 2. We use a modified "asymmetric" notion of epsilon-optimality in</span></div>
<divclass="line"><aname="l00115"></a><spanclass="lineno"> 115</span> <spanclass="comment">// which left-to-right residual arcs are required to have reduced</span></div>
<divclass="line"><aname="l00116"></a><spanclass="lineno"> 116</span> <spanclass="comment">// cost bounded below by zero and right-to-left residual arcs are</span></div>
<divclass="line"><aname="l00117"></a><spanclass="lineno"> 117</span> <spanclass="comment">// required to have reduced cost bounded below by -epsilon. For</span></div>
<divclass="line"><aname="l00118"></a><spanclass="lineno"> 118</span> <spanclass="comment">// each residual arc direction, the reduced-cost threshold for</span></div>
<divclass="line"><aname="l00119"></a><spanclass="lineno"> 119</span> <spanclass="comment">// admissibility is epsilon/2 above the threshold for epsilon</span></div>
<divclass="line"><aname="l00121"></a><spanclass="lineno"> 121</span> <spanclass="comment">// 3. We do not limit the applicability of the relabeling operation to</span></div>
<divclass="line"><aname="l00122"></a><spanclass="lineno"> 122</span> <spanclass="comment">// nodes with excess. Instead we use the double-push operation</span></div>
<divclass="line"><aname="l00123"></a><spanclass="lineno"> 123</span> <spanclass="comment">// (discussed in the Goldberg and Kennedy CSA paper and Kennedy's</span></div>
<divclass="line"><aname="l00124"></a><spanclass="lineno"> 124</span> <spanclass="comment">// thesis) which relabels right-side nodes just *after* they have</span></div>
<divclass="line"><aname="l00125"></a><spanclass="lineno"> 125</span> <spanclass="comment">// been discharged.</span></div>
<divclass="line"><aname="l00126"></a><spanclass="lineno"> 126</span> <spanclass="comment">// The above differences are explained in detail in [Kennedy's thesis]</span></div>
<divclass="line"><aname="l00127"></a><spanclass="lineno"> 127</span> <spanclass="comment">// and explained not quite as cleanly in [Goldberg and Kennedy's CSA</span></div>
<divclass="line"><aname="l00128"></a><spanclass="lineno"> 128</span> <spanclass="comment">// paper]. But note that the thesis explanation uses a value of</span></div>
<divclass="line"><aname="l00129"></a><spanclass="lineno"> 129</span> <spanclass="comment">// epsilon that's double what we use here.</span></div>
<divclass="line"><aname="l00131"></a><spanclass="lineno"> 131</span> <spanclass="comment">// Some definitions:</span></div>
<divclass="line"><aname="l00132"></a><spanclass="lineno"> 132</span> <spanclass="comment">// Active: A node is called active when it has excess. It is</span></div>
<divclass="line"><aname="l00133"></a><spanclass="lineno"> 133</span> <spanclass="comment">// eligible to be pushed from. In this implementation, every active</span></div>
<divclass="line"><aname="l00134"></a><spanclass="lineno"> 134</span> <spanclass="comment">// node is on the left side of the graph where prices are determined</span></div>
<divclass="line"><aname="l00135"></a><spanclass="lineno"> 135</span> <spanclass="comment">// implicitly, so no left-side relabeling is necessary before</span></div>
<divclass="line"><aname="l00136"></a><spanclass="lineno"> 136</span> <spanclass="comment">// pushing from an active node. We do, however, need to compute</span></div>
<divclass="line"><aname="l00137"></a><spanclass="lineno"> 137</span> <spanclass="comment">// the implications for price changes on the affected right-side</span></div>
<divclass="line"><aname="l00139"></a><spanclass="lineno"> 139</span> <spanclass="comment">// Admissible: A residual arc (one that can carry more flow) is</span></div>
<divclass="line"><aname="l00140"></a><spanclass="lineno"> 140</span> <spanclass="comment">// called admissible when its reduced cost is small enough. We can</span></div>
<divclass="line"><aname="l00141"></a><spanclass="lineno"> 141</span> <spanclass="comment">// push additional flow along such an arc without violating</span></div>
<divclass="line"><aname="l00142"></a><spanclass="lineno"> 142</span> <spanclass="comment">// epsilon-optimality. In the case of a left-to-right residual</span></div>
<divclass="line"><aname="l00143"></a><spanclass="lineno"> 143</span> <spanclass="comment">// arc, the reduced cost must be at most epsilon/2. In the case of</span></div>
<divclass="line"><aname="l00144"></a><spanclass="lineno"> 144</span> <spanclass="comment">// a right-to-left residual arc, the reduced cost must be at</span></div>
<divclass="line"><aname="l00145"></a><spanclass="lineno"> 145</span> <spanclass="comment">// most -epsilon/2. The careful reader will note that these thresholds</span></div>
<divclass="line"><aname="l00146"></a><spanclass="lineno"> 146</span> <spanclass="comment">// are not used explicitly anywhere in this implementation, and</span></div>
<divclass="line"><aname="l00147"></a><spanclass="lineno"> 147</span> <spanclass="comment">// the reason is the implicit pricing of left-side nodes.</span></div>
<divclass="line"><aname="l00148"></a><spanclass="lineno"> 148</span> <spanclass="comment">// Reduced cost: Essentially an arc's reduced cost is its</span></div>
<divclass="line"><aname="l00149"></a><spanclass="lineno"> 149</span> <spanclass="comment">// complementary slackness. In push-relabel algorithms this is</span></div>
<divclass="line"><aname="l00151"></a><spanclass="lineno"> 151</span> <spanclass="comment">// where p() is the node price function and c(v, w) is the cost of</span></div>
<divclass="line"><aname="l00152"></a><spanclass="lineno"> 152</span> <spanclass="comment">// the arc from v to w. See min_cost_flow.h for more details.</span></div>
<divclass="line"><aname="l00153"></a><spanclass="lineno"> 153</span> <spanclass="comment">// Partial reduced cost: We maintain prices implicitly for left-side</span></div>
<divclass="line"><aname="l00154"></a><spanclass="lineno"> 154</span> <spanclass="comment">// nodes in this implementation, so instead of reduced costs we</span></div>
<divclass="line"><aname="l00155"></a><spanclass="lineno"> 155</span> <spanclass="comment">// work with partial reduced costs, defined as</span></div>
<divclass="line"><aname="l00158"></a><spanclass="lineno"> 158</span> <spanclass="comment">// We check at initialization time for the possibility of arithmetic</span></div>
<divclass="line"><aname="l00159"></a><spanclass="lineno"> 159</span> <spanclass="comment">// overflow and warn if the given costs are too large. In many cases</span></div>
<divclass="line"><aname="l00160"></a><spanclass="lineno"> 160</span> <spanclass="comment">// the bound we use to trigger the warning is pessimistic so the given</span></div>
<divclass="line"><aname="l00161"></a><spanclass="lineno"> 161</span> <spanclass="comment">// problem can often be solved even if we warn that overflow is</span></div>
<divclass="line"><aname="l00164"></a><spanclass="lineno"> 164</span> <spanclass="comment">// We don't use the interface from</span></div>
<divclass="line"><aname="l00165"></a><spanclass="lineno"> 165</span> <spanclass="comment">// operations_research/algorithms/hungarian.h because we want to be</span></div>
<divclass="line"><aname="l00166"></a><spanclass="lineno"> 166</span> <spanclass="comment">// able to express sparse problems efficiently.</span></div>
<divclass="line"><aname="l00168"></a><spanclass="lineno"> 168</span> <spanclass="comment">// When asked to solve the given assignment problem we return a</span></div>
<divclass="line"><aname="l00169"></a><spanclass="lineno"> 169</span> <spanclass="comment">// boolean to indicate whether the given problem was feasible.</span></div>
<divclass="line"><aname="l00172"></a><spanclass="lineno"> 172</span> <spanclass="comment">// [ Goldberg and Kennedy's CSA paper ] A. V. Goldberg and R. Kennedy,</span></div>
<divclass="line"><aname="l00173"></a><spanclass="lineno"> 173</span> <spanclass="comment">// "An Efficient Cost Scaling Algorithm for the Assignment Problem."</span></div>
<divclass="line"><aname="l00174"></a><spanclass="lineno"> 174</span> <spanclass="comment">// Mathematical Programming, Vol. 71, pages 153-178, December 1995.</span></div>
<divclass="line"><aname="l00176"></a><spanclass="lineno"> 176</span> <spanclass="comment">// [ Goldberg and Tarjan ] A. V. Goldberg and R. E. Tarjan, "Finding</span></div>
<divclass="line"><aname="l00177"></a><spanclass="lineno"> 177</span> <spanclass="comment">// Minimum-Cost Circulations by Successive Approximation." Mathematics</span></div>
<divclass="line"><aname="l00178"></a><spanclass="lineno"> 178</span> <spanclass="comment">// of Operations Research, Vol. 15, No. 3, pages 430-466, August 1990.</span></div>
<divclass="line"><aname="l00180"></a><spanclass="lineno"> 180</span> <spanclass="comment">// [ Kennedy's thesis ] J. R. Kennedy, Jr., "Solving Unweighted and</span></div>
<divclass="line"><aname="l00181"></a><spanclass="lineno"> 181</span> <spanclass="comment">// Weighted Bipartite Matching Problems in Theory and Practice."</span></div>
<divclass="line"><aname="l00182"></a><spanclass="lineno"> 182</span> <spanclass="comment">// Stanford University Doctoral Dissertation, Department of Computer</span></div>
<divclass="line"><aname="l00185"></a><spanclass="lineno"> 185</span> <spanclass="comment">// [ Burkard et al. ] R. Burkard, M. Dell'Amico, S. Martello, "Assignment</span></div>
<divclass="line"><aname="l00189"></a><spanclass="lineno"> 189</span> <spanclass="comment">// [ Ahuja et al. ] R. K. Ahuja, T. L. Magnanti, J. B. Orlin, "Network Flows:</span></div>
<divclass="line"><aname="l00190"></a><spanclass="lineno"> 190</span> <spanclass="comment">// Theory, Algorithms, and Applications," Prentice Hall, 1993,</span></div>
<divclass="line"><aname="l00224"></a><spanclass="lineno"> 224</span> <spanclass="comment">// This class does not take ownership of its underlying graph.</span></div>
<divclass="line"><aname="l00231"></a><spanclass="lineno"> 231</span> <spanclass="comment">// Constructor for the case in which we will build the graph</span></div>
<divclass="line"><aname="l00232"></a><spanclass="lineno"> 232</span> <spanclass="comment">// incrementally as we discover arc costs, as might be done with any</span></div>
<divclass="line"><aname="l00233"></a><spanclass="lineno"> 233</span> <spanclass="comment">// of the dynamic graph representations such as StarGraph or ForwardStarGraph.</span></div>
<divclass="line"><aname="l00236"></a><spanclass="lineno"> 236</span> <spanclass="comment">// Constructor for the case in which the underlying graph cannot be</span></div>
<divclass="line"><aname="l00237"></a><spanclass="lineno"> 237</span> <spanclass="comment">// built until after all the arc costs are known, as is the case</span></div>
<divclass="line"><aname="l00238"></a><spanclass="lineno"> 238</span> <spanclass="comment">// with ForwardStarStaticGraph. In this case, the graph is passed to</span></div>
<divclass="line"><aname="l00239"></a><spanclass="lineno"> 239</span> <spanclass="comment">// us later via the SetGraph() method, below.</span></div>
<divclass="line"><aname="l00244"></a><spanclass="lineno"> 244</span> <spanclass="comment">// Sets the graph used by the LinearSumAssignment instance, for use</span></div>
<divclass="line"><aname="l00245"></a><spanclass="lineno"> 245</span> <spanclass="comment">// when the graph layout can be determined only after arc costs are</span></div>
<divclass="line"><aname="l00246"></a><spanclass="lineno"> 246</span> <spanclass="comment">// set. This happens, for example, when we use a ForwardStarStaticGraph.</span></div>
<divclass="line"><aname="l00252"></a><spanclass="lineno"> 252</span> <spanclass="comment">// Sets the cost-scaling divisor, i.e., the amount by which we</span></div>
<divclass="line"><aname="l00253"></a><spanclass="lineno"> 253</span> <spanclass="comment">// divide the scaling parameter on each iteration.</span></div>
<divclass="line"><aname="l00256"></a><spanclass="lineno"> 256</span> <spanclass="comment">// Returns a permutation cycle handler that can be passed to the</span></div>
<divclass="line"><aname="l00257"></a><spanclass="lineno"> 257</span> <spanclass="comment">// TransformToForwardStaticGraph method so that arc costs get</span></div>
<divclass="line"><aname="l00258"></a><spanclass="lineno"> 258</span> <spanclass="comment">// permuted along with arcs themselves.</span></div>
<divclass="line"><aname="l00260"></a><spanclass="lineno"> 260</span> <spanclass="comment">// Passes ownership of the cycle handler to the caller.</span></div>
<divclass="line"><aname="l00265"></a><spanclass="lineno"> 265</span> <spanclass="comment">// Optimizes the layout of the graph for the access pattern our</span></div>
<divclass="line"><aname="l00266"></a><spanclass="lineno"> 266</span> <spanclass="comment">// implementation will use.</span></div>
<divclass="line"><aname="l00268"></a><spanclass="lineno"> 268</span> <spanclass="comment">// REQUIRES for LinearSumAssignment template instantiation if a call</span></div>
<divclass="line"><aname="l00269"></a><spanclass="lineno"> 269</span> <spanclass="comment">// to the OptimizeGraphLayout() method is compiled: GraphType is a</span></div>
<divclass="line"><aname="l00270"></a><spanclass="lineno"> 270</span> <spanclass="comment">// dynamic graph, i.e., one that implements the</span></div>
<divclass="line"><aname="l00271"></a><spanclass="lineno"> 271</span> <spanclass="comment">// GroupForwardArcsByFunctor() member template method.</span></div>
<divclass="line"><aname="l00273"></a><spanclass="lineno"> 273</span> <spanclass="comment">// If analogous optimization is needed for LinearSumAssignment</span></div>
<divclass="line"><aname="l00274"></a><spanclass="lineno"> 274</span> <spanclass="comment">// instances based on static graphs, the graph layout should be</span></div>
<divclass="line"><aname="l00275"></a><spanclass="lineno"> 275</span> <spanclass="comment">// constructed such that each node's outgoing arcs are sorted by</span></div>
<divclass="line"><aname="l00276"></a><spanclass="lineno"> 276</span> <spanclass="comment">// head node index before the</span></div>
<divclass="line"><aname="l00277"></a><spanclass="lineno"> 277</span> <spanclass="comment">// LinearSumAssignment<GraphType>::SetGraph() method is called.</span></div>
<divclass="line"><aname="l00283"></a><spanclass="lineno"> 283</span> <spanclass="comment">// These handy member functions make the code more compact, and we</span></div>
<divclass="line"><aname="l00284"></a><spanclass="lineno"> 284</span> <spanclass="comment">// expose them to clients so that client code that doesn't have</span></div>
<divclass="line"><aname="l00285"></a><spanclass="lineno"> 285</span> <spanclass="comment">// direct access to the graph can learn about the optimum assignment</span></div>
<divclass="line"><aname="l00286"></a><spanclass="lineno"> 286</span> <spanclass="comment">// once it is computed.</span></div>
<divclass="line"><aname="l00289"></a><spanclass="lineno"> 289</span> <spanclass="comment">// Returns the original arc cost for use by a client that's</span></div>
<divclass="line"><aname="l00290"></a><spanclass="lineno"> 290</span> <spanclass="comment">// iterating over the optimum assignment.</span></div>
<divclass="line"><aname="l00296"></a><spanclass="lineno"> 296</span> <spanclass="comment">// Sets the cost of an arc already present in the given graph.</span></div>
<divclass="line"><aname="l00299"></a><spanclass="lineno"> 299</span> <spanclass="comment">// Completes initialization after the problem is fully specified.</span></div>
<divclass="line"><aname="l00300"></a><spanclass="lineno"> 300</span> <spanclass="comment">// Returns true if we successfully prove that arithmetic</span></div>
<divclass="line"><aname="l00301"></a><spanclass="lineno"> 301</span> <spanclass="comment">// calculations are guaranteed not to overflow. ComputeAssignment()</span></div>
<divclass="line"><aname="l00302"></a><spanclass="lineno"> 302</span> <spanclass="comment">// calls this method itself, so only clients that care about</span></div>
<divclass="line"><aname="l00303"></a><spanclass="lineno"> 303</span> <spanclass="comment">// obtaining a warning about the possibility of arithmetic precision</span></div>
<divclass="line"><aname="l00304"></a><spanclass="lineno"> 304</span> <spanclass="comment">// problems need to call this method explicitly.</span></div>
<divclass="line"><aname="l00306"></a><spanclass="lineno"> 306</span> <spanclass="comment">// Separate from ComputeAssignment() for white-box testing and for</span></div>
<divclass="line"><aname="l00307"></a><spanclass="lineno"> 307</span> <spanclass="comment">// clients that need to react to the possibility that arithmetic</span></div>
<divclass="line"><aname="l00308"></a><spanclass="lineno"> 308</span> <spanclass="comment">// overflow is not ruled out.</span></div>
<divclass="line"><aname="l00313"></a><spanclass="lineno"> 313</span> <spanclass="comment">// Computes the optimum assignment. Returns true on success. Return</span></div>
<divclass="line"><aname="l00314"></a><spanclass="lineno"> 314</span> <spanclass="comment">// value of false implies the given problem is infeasible.</span></div>
<divclass="line"><aname="l00317"></a><spanclass="lineno"> 317</span> <spanclass="comment">// Returns the cost of the minimum-cost perfect matching.</span></div>
<divclass="line"><aname="l00318"></a><spanclass="lineno"> 318</span> <spanclass="comment">// Precondition: success_ == true, signifying that we computed the</span></div>
<divclass="line"><aname="l00319"></a><spanclass="lineno"> 319</span> <spanclass="comment">// optimum assignment for a feasible problem.</span></div>
<divclass="line"><aname="l00322"></a><spanclass="lineno"> 322</span> <spanclass="comment">// Returns the total number of nodes in the given problem.</span></div>
<divclass="line"><aname="l00325"></a><spanclass="lineno"> 325</span> <spanclass="comment">// Return a guess that must be true if ultimately we are given a</span></div>
<divclass="line"><aname="l00326"></a><spanclass="lineno"> 326</span> <spanclass="comment">// feasible problem to solve.</span></div>
<divclass="line"><aname="l00333"></a><spanclass="lineno"> 333</span> <spanclass="comment">// Returns the number of nodes on the left side of the given</span></div>
<divclass="line"><aname="l00337"></a><spanclass="lineno"> 337</span> <spanclass="comment">// Returns the arc through which the given node is matched.</span></div>
<divclass="line"><aname="l00343"></a><spanclass="lineno"> 343</span> <spanclass="comment">// Returns the cost of the assignment arc incident to the given</span></div>
<divclass="line"><aname="l00349"></a><spanclass="lineno"> 349</span> <spanclass="comment">// Returns the node to which the given node is matched.</span></div>
<divclass="line"><aname="l00424"></a><spanclass="lineno"> 424</span> <aclass="code"href="classoperations__research_1_1_linear_sum_assignment.html#aca73212d30b08a7c287c311b74311a6e">NodeIndex</a> result = v_.back();</div>
<divclass="line"><aname="l00443"></a><spanclass="lineno"> 443</span> <aclass="code"href="classoperations__research_1_1_linear_sum_assignment.html#aca73212d30b08a7c287c311b74311a6e">NodeIndex</a> result = q_.back();</div>
<divclass="line"><aname="l00455"></a><spanclass="lineno"> 455</span> <spanclass="comment">// giving the arc along which we will push from a given left-side</span></div>
<divclass="line"><aname="l00456"></a><spanclass="lineno"> 456</span> <spanclass="comment">// node and the gap between that arc's partial reduced cost and the</span></div>
<divclass="line"><aname="l00457"></a><spanclass="lineno"> 457</span> <spanclass="comment">// reduced cost of the next-best (necessarily residual) arc out of</span></div>
<divclass="line"><aname="l00458"></a><spanclass="lineno"> 458</span> <spanclass="comment">// the node. This information helps us efficiently relabel</span></div>
<divclass="line"><aname="l00459"></a><spanclass="lineno"> 459</span> <spanclass="comment">// right-side nodes during DoublePush operations.</span></div>
<divclass="line"><aname="l00462"></a><spanclass="lineno"> 462</span> <spanclass="comment">// Returns true if and only if the current pseudoflow is</span></div>
<divclass="line"><aname="l00463"></a><spanclass="lineno"> 463</span> <spanclass="comment">// epsilon-optimal. To be used in a DCHECK.</span></div>
<divclass="line"><aname="l00470"></a><spanclass="lineno"> 470</span> <spanclass="comment">// Calculates the implicit price of the given node.</span></div>
<divclass="line"><aname="l00471"></a><spanclass="lineno"> 471</span> <spanclass="comment">// Only for debugging, for use in EpsilonOptimal().</span></div>
<divclass="line"><aname="l00477"></a><spanclass="lineno"> 477</span> <spanclass="comment">// Accumulates stats between iterations and reports them if the</span></div>
<divclass="line"><aname="l00478"></a><spanclass="lineno"> 478</span> <spanclass="comment">// verbosity level is high enough.</span></div>
<divclass="line"><aname="l00481"></a><spanclass="lineno"> 481</span> <spanclass="comment">// Utility function to compute the next error parameter value. This</span></div>
<divclass="line"><aname="l00482"></a><spanclass="lineno"> 482</span> <spanclass="comment">// is used to ensure that the same sequence of error parameter</span></div>
<divclass="line"><aname="l00483"></a><spanclass="lineno"> 483</span> <spanclass="comment">// values is used for computation of price bounds as is used for</span></div>
<divclass="line"><aname="l00484"></a><spanclass="lineno"> 484</span> <spanclass="comment">// computing the optimum assignment.</span></div>
<divclass="line"><aname="l00487"></a><spanclass="lineno"> 487</span> <spanclass="comment">// Advances internal state to prepare for the next scaling</span></div>
<divclass="line"><aname="l00488"></a><spanclass="lineno"> 488</span> <spanclass="comment">// iteration. Returns false if infeasibility is detected, true</span></div>
<divclass="line"><aname="l00492"></a><spanclass="lineno"> 492</span> <spanclass="comment">// Indicates whether the given left_node has positive excess. Called</span></div>
<divclass="line"><aname="l00493"></a><spanclass="lineno"> 493</span> <spanclass="comment">// only for nodes on the left side.</span></div>
<divclass="line"><aname="l00496"></a><spanclass="lineno"> 496</span> <spanclass="comment">// Indicates whether the given node has nonzero excess. The idea</span></div>
<divclass="line"><aname="l00497"></a><spanclass="lineno"> 497</span> <spanclass="comment">// here is the same as the IsActive method above, but that method</span></div>
<divclass="line"><aname="l00498"></a><spanclass="lineno"> 498</span> <spanclass="comment">// contains a safety DCHECK() that its argument is a left-side node,</span></div>
<divclass="line"><aname="l00499"></a><spanclass="lineno"> 499</span> <spanclass="comment">// while this method is usable for any node.</span></div>
<divclass="line"><aname="l00500"></a><spanclass="lineno"> 500</span> <spanclass="comment">// To be used in a DCHECK.</span></div>
<divclass="line"><aname="l00503"></a><spanclass="lineno"> 503</span> <spanclass="comment">// Performs the push/relabel work for one scaling iteration.</span></div>
<divclass="line"><aname="l00506"></a><spanclass="lineno"> 506</span> <spanclass="comment">// Puts all left-side nodes in the active set in preparation for the</span></div>
<divclass="line"><aname="l00507"></a><spanclass="lineno"> 507</span> <spanclass="comment">// first scaling iteration.</span></div>
<divclass="line"><aname="l00510"></a><spanclass="lineno"> 510</span> <spanclass="comment">// Saturates all negative-reduced-cost arcs at the beginning of each</span></div>
<divclass="line"><aname="l00511"></a><spanclass="lineno"> 511</span> <spanclass="comment">// scaling iteration. Note that according to the asymmetric</span></div>
<divclass="line"><aname="l00512"></a><spanclass="lineno"> 512</span> <spanclass="comment">// definition of admissibility, this action is different from</span></div>
<divclass="line"><aname="l00513"></a><spanclass="lineno"> 513</span> <spanclass="comment">// saturating all admissible arcs (which we never do). All negative</span></div>
<divclass="line"><aname="l00514"></a><spanclass="lineno"> 514</span> <spanclass="comment">// arcs are admissible, but not all admissible arcs are negative. It</span></div>
<divclass="line"><aname="l00515"></a><spanclass="lineno"> 515</span> <spanclass="comment">// is alwsys enough to saturate only the negative ones.</span></div>
<divclass="line"><aname="l00518"></a><spanclass="lineno"> 518</span> <spanclass="comment">// Performs an optimized sequence of pushing a unit of excess out of</span></div>
<divclass="line"><aname="l00519"></a><spanclass="lineno"> 519</span> <spanclass="comment">// the left-side node v and back to another left-side node if no</span></div>
<divclass="line"><aname="l00520"></a><spanclass="lineno"> 520</span> <spanclass="comment">// deficit is cancelled with the first push.</span></div>
<divclass="line"><aname="l00523"></a><spanclass="lineno"> 523</span> <spanclass="comment">// Returns the partial reduced cost of the given arc.</span></div>
<divclass="line"><aname="l00528"></a><spanclass="lineno"> 528</span> <spanclass="comment">// The graph underlying the problem definition we are given. Not</span></div>
<divclass="line"><aname="l00529"></a><spanclass="lineno"> 529</span> <spanclass="comment">// owned by *this.</span></div>
<divclass="line"><aname="l00532"></a><spanclass="lineno"> 532</span> <spanclass="comment">// The number of nodes on the left side of the graph we are given.</span></div>
<divclass="line"><aname="l00535"></a><spanclass="lineno"> 535</span> <spanclass="comment">// A flag indicating, after FinalizeSetup() has run, whether the</span></div>
<divclass="line"><aname="l00536"></a><spanclass="lineno"> 536</span> <spanclass="comment">// arc-incidence precondition required by BestArcAndGap() is</span></div>
<divclass="line"><aname="l00537"></a><spanclass="lineno"> 537</span> <spanclass="comment">// satisfied by every left-side node. If not, the problem is</span></div>
<divclass="line"><aname="l00541"></a><spanclass="lineno"> 541</span> <spanclass="comment">// A flag indicating that an optimal perfect matching has been computed.</span></div>
<divclass="line"><aname="l00544"></a><spanclass="lineno"> 544</span> <spanclass="comment">// The value by which we multiply all the arc costs we are given in</span></div>
<divclass="line"><aname="l00545"></a><spanclass="lineno"> 545</span> <spanclass="comment">// order to be able to use integer arithmetic in all our</span></div>
<divclass="line"><aname="l00546"></a><spanclass="lineno"> 546</span> <spanclass="comment">// computations. In order to establish optimality of the final</span></div>
<divclass="line"><aname="l00547"></a><spanclass="lineno"> 547</span> <spanclass="comment">// matching we compute, we need that</span></div>
<divclass="line"><aname="l00554"></a><spanclass="lineno"> 554</span> <spanclass="comment">// Minimum value of epsilon. When a flow is epsilon-optimal for</span></div>
<divclass="line"><aname="l00555"></a><spanclass="lineno"> 555</span> <spanclass="comment">// epsilon == kMinEpsilon, the flow is optimal.</span></div>
<divclass="line"><aname="l00558"></a><spanclass="lineno"> 558</span> <spanclass="comment">// Current value of epsilon, the cost scaling parameter.</span></div>
<divclass="line"><aname="l00561"></a><spanclass="lineno"> 561</span> <spanclass="comment">// The following two data members, price_lower_bound_ and</span></div>
<divclass="line"><aname="l00562"></a><spanclass="lineno"> 562</span> <spanclass="comment">// slack_relabeling_price_, have to do with bounds on the amount by</span></div>
<divclass="line"><aname="l00563"></a><spanclass="lineno"> 563</span> <spanclass="comment">// which node prices can change during execution of the algorithm.</span></div>
<divclass="line"><aname="l00564"></a><spanclass="lineno"> 564</span> <spanclass="comment">// We need some detailed discussion of this topic because we violate</span></div>
<divclass="line"><aname="l00565"></a><spanclass="lineno"> 565</span> <spanclass="comment">// several simplifying assumptions typically made in the theoretical</span></div>
<divclass="line"><aname="l00566"></a><spanclass="lineno"> 566</span> <spanclass="comment">// literature. In particular, we use integer arithmetic, we use a</span></div>
<divclass="line"><aname="l00567"></a><spanclass="lineno"> 567</span> <spanclass="comment">// reduction to the transportation problem rather than min-cost</span></div>
<divclass="line"><aname="l00568"></a><spanclass="lineno"> 568</span> <spanclass="comment">// circulation, we provide detection of infeasible problems rather</span></div>
<divclass="line"><aname="l00569"></a><spanclass="lineno"> 569</span> <spanclass="comment">// than assume feasibility, we detect when our computations might</span></div>
<divclass="line"><aname="l00570"></a><spanclass="lineno"> 570</span> <spanclass="comment">// exceed the range of representable cost values, and we use the</span></div>
<divclass="line"><aname="l00571"></a><spanclass="lineno"> 571</span> <spanclass="comment">// double-push heuristic which relabels nodes that do not have</span></div>
<divclass="line"><aname="l00574"></a><spanclass="lineno"> 574</span> <spanclass="comment">// In the following discussion, we prove the following propositions:</span></div>
<divclass="line"><aname="l00575"></a><spanclass="lineno"> 575</span> <spanclass="comment">// Proposition 1. [Fidelity of arithmetic precision guarantee] If</span></div>
<divclass="line"><aname="l00576"></a><spanclass="lineno"> 576</span> <spanclass="comment">// FinalizeSetup() returns true, no arithmetic</span></div>
<divclass="line"><aname="l00577"></a><spanclass="lineno"> 577</span> <spanclass="comment">// overflow occurs during ComputeAssignment().</span></div>
<divclass="line"><aname="l00578"></a><spanclass="lineno"> 578</span> <spanclass="comment">// Proposition 2. [Fidelity of feasibility detection] If no</span></div>
<divclass="line"><aname="l00580"></a><spanclass="lineno"> 580</span> <spanclass="comment">// ComputeAssignment(), the return value of</span></div>
<divclass="line"><aname="l00586"></a><spanclass="lineno"> 586</span> <spanclass="comment">// The ideas used to prove our two propositions are essentially</span></div>
<divclass="line"><aname="l00587"></a><spanclass="lineno"> 587</span> <spanclass="comment">// those that appear in [Goldberg and Tarjan], but several details</span></div>
<divclass="line"><aname="l00588"></a><spanclass="lineno"> 588</span> <spanclass="comment">// are different: [Goldberg and Tarjan] assumes a feasible problem,</span></div>
<divclass="line"><aname="l00589"></a><spanclass="lineno"> 589</span> <spanclass="comment">// uses a symmetric notion of epsilon-optimality, considers only</span></div>
<divclass="line"><aname="l00590"></a><spanclass="lineno"> 590</span> <spanclass="comment">// nodes with excess eligible for relabeling, and does not treat the</span></div>
<divclass="line"><aname="l00591"></a><spanclass="lineno"> 591</span> <spanclass="comment">// question of arithmetic overflow. This implementation, on the</span></div>
<divclass="line"><aname="l00592"></a><spanclass="lineno"> 592</span> <spanclass="comment">// other hand, detects and reports infeasible problems, uses</span></div>
<divclass="line"><aname="l00593"></a><spanclass="lineno"> 593</span> <spanclass="comment">// asymmetric epsilon-optimality, relabels nodes with no excess in</span></div>
<divclass="line"><aname="l00594"></a><spanclass="lineno"> 594</span> <spanclass="comment">// the course of the double-push operation, and gives a reasonably</span></div>
<divclass="line"><aname="l00595"></a><spanclass="lineno"> 595</span> <spanclass="comment">// tight guarantee of arithmetic precision. No fundamentally new</span></div>
<divclass="line"><aname="l00596"></a><spanclass="lineno"> 596</span> <spanclass="comment">// ideas are involved, but the details are a bit tricky so they are</span></div>
<divclass="line"><aname="l00599"></a><spanclass="lineno"> 599</span> <spanclass="comment">// We have two intertwined needs that lead us to compute bounds on</span></div>
<divclass="line"><aname="l00600"></a><spanclass="lineno"> 600</span> <spanclass="comment">// the prices nodes can have during the assignment computation, on</span></div>
<divclass="line"><aname="l00601"></a><spanclass="lineno"> 601</span> <spanclass="comment">// the assumption that the given problem is feasible:</span></div>
<divclass="line"><aname="l00602"></a><spanclass="lineno"> 602</span> <spanclass="comment">// 1. Infeasibility detection: Infeasibility is detected by</span></div>
<divclass="line"><aname="l00603"></a><spanclass="lineno"> 603</span> <spanclass="comment">// observing that some node's price has been reduced too much by</span></div>
<divclass="line"><aname="l00604"></a><spanclass="lineno"> 604</span> <spanclass="comment">// relabeling operations (see [Goldberg and Tarjan] for the</span></div>
<divclass="line"><aname="l00605"></a><spanclass="lineno"> 605</span> <spanclass="comment">// argument -- duplicated in modified form below -- bounding the</span></div>
<divclass="line"><aname="l00606"></a><spanclass="lineno"> 606</span> <spanclass="comment">// running time of the push/relabel min-cost flow algorithm for</span></div>
<divclass="line"><aname="l00609"></a><spanclass="lineno"> 609</span> <spanclass="comment">// forced: When a left-side node is incident to only one arc a,</span></div>
<divclass="line"><aname="l00610"></a><spanclass="lineno"> 610</span> <spanclass="comment">// any feasible solution must include a, and reducing the price</span></div>
<divclass="line"><aname="l00611"></a><spanclass="lineno"> 611</span> <spanclass="comment">// of Head(a) by any nonnegative amount preserves epsilon-</span></div>
<divclass="line"><aname="l00612"></a><spanclass="lineno"> 612</span> <spanclass="comment">// optimality. Because of this freedom, we'll call this sort of</span></div>
<divclass="line"><aname="l00613"></a><spanclass="lineno"> 613</span> <spanclass="comment">// relabeling (i.e., a relabeling of a right-side node that is</span></div>
<divclass="line"><aname="l00614"></a><spanclass="lineno"> 614</span> <spanclass="comment">// the only neighbor of the left-side node to which it has been</span></div>
<divclass="line"><aname="l00615"></a><spanclass="lineno"> 615</span> <spanclass="comment">// matched in the present double-push operation) a "slack"</span></div>
<divclass="line"><aname="l00616"></a><spanclass="lineno"> 616</span> <spanclass="comment">// relabeling. Relabelings that are not slack relabelings are</span></div>
<divclass="line"><aname="l00617"></a><spanclass="lineno"> 617</span> <spanclass="comment">// called "confined" relabelings. By relabeling Head(a) to have</span></div>
<divclass="line"><aname="l00618"></a><spanclass="lineno"> 618</span> <spanclass="comment">// p(Head(a))=-infinity, we could guarantee that a never becomes</span></div>
<divclass="line"><aname="l00619"></a><spanclass="lineno"> 619</span> <spanclass="comment">// unmatched during the current iteration, and this would prevent</span></div>
<divclass="line"><aname="l00620"></a><spanclass="lineno"> 620</span> <spanclass="comment">// our wasting time repeatedly unmatching and rematching a. But</span></div>
<divclass="line"><aname="l00621"></a><spanclass="lineno"> 621</span> <spanclass="comment">// there are some details we need to handle:</span></div>
<divclass="line"><aname="l00622"></a><spanclass="lineno"> 622</span> <spanclass="comment">// a. The CostValue type cannot represent -infinity;</span></div>
<divclass="line"><aname="l00623"></a><spanclass="lineno"> 623</span> <spanclass="comment">// b. Low node prices are precisely the signal we use to detect</span></div>
<divclass="line"><aname="l00624"></a><spanclass="lineno"> 624</span> <spanclass="comment">// infeasibility (see (1)), so we must be careful not to</span></div>
<divclass="line"><aname="l00625"></a><spanclass="lineno"> 625</span> <spanclass="comment">// falsely conclude that the problem is infeasible as a result</span></div>
<divclass="line"><aname="l00626"></a><spanclass="lineno"> 626</span> <spanclass="comment">// of the low price we gave Head(a); and</span></div>
<divclass="line"><aname="l00627"></a><spanclass="lineno"> 627</span> <spanclass="comment">// c. We need to indicate accurately to the client when our best</span></div>
<divclass="line"><aname="l00628"></a><spanclass="lineno"> 628</span> <spanclass="comment">// understanding indicates that we can't rule out arithmetic</span></div>
<divclass="line"><aname="l00629"></a><spanclass="lineno"> 629</span> <spanclass="comment">// overflow in our calculations. Most importantly, if we don't</span></div>
<divclass="line"><aname="l00630"></a><spanclass="lineno"> 630</span> <spanclass="comment">// warn the client, we must be certain to avoid overflow. This</span></div>
<divclass="line"><aname="l00631"></a><spanclass="lineno"> 631</span> <spanclass="comment">// means our slack relabelings must not be so aggressive as to</span></div>
<divclass="line"><aname="l00632"></a><spanclass="lineno"> 632</span> <spanclass="comment">// create the possibility of unforeseen overflow. Although we</span></div>
<divclass="line"><aname="l00633"></a><spanclass="lineno"> 633</span> <spanclass="comment">// will not achieve this in practice, slack relabelings would</span></div>
<divclass="line"><aname="l00634"></a><spanclass="lineno"> 634</span> <spanclass="comment">// ideally not introduce overflow unless overflow was</span></div>
<divclass="line"><aname="l00635"></a><spanclass="lineno"> 635</span> <spanclass="comment">// inevitable were even the smallest reasonable price change</span></div>
<divclass="line"><aname="l00636"></a><spanclass="lineno"> 636</span> <spanclass="comment">// (== epsilon) used for slack relabelings.</span></div>
<divclass="line"><aname="l00637"></a><spanclass="lineno"> 637</span> <spanclass="comment">// Using the analysis below, we choose a finite amount of price</span></div>
<divclass="line"><aname="l00638"></a><spanclass="lineno"> 638</span> <spanclass="comment">// change for slack relabelings aggressive enough that we don't</span></div>
<divclass="line"><aname="l00639"></a><spanclass="lineno"> 639</span> <spanclass="comment">// waste time doing repeated slack relabelings in a single</span></div>
<divclass="line"><aname="l00640"></a><spanclass="lineno"> 640</span> <spanclass="comment">// iteration, yet modest enough that we keep a good handle on</span></div>
<divclass="line"><aname="l00641"></a><spanclass="lineno"> 641</span> <spanclass="comment">// arithmetic precision and our ability to detect infeasible</span></div>
<divclass="line"><aname="l00644"></a><spanclass="lineno"> 644</span> <spanclass="comment">// To provide faithful detection of infeasibility, a dependable</span></div>
<divclass="line"><aname="l00645"></a><spanclass="lineno"> 645</span> <spanclass="comment">// guarantee of arithmetic precision whenever possible, and good</span></div>
<divclass="line"><aname="l00646"></a><spanclass="lineno"> 646</span> <spanclass="comment">// performance by aggressively relabeling nodes whose matching is</span></div>
<divclass="line"><aname="l00647"></a><spanclass="lineno"> 647</span> <spanclass="comment">// forced, we exploit these facts:</span></div>
<divclass="line"><aname="l00648"></a><spanclass="lineno"> 648</span> <spanclass="comment">// 1. Beyond the first iteration, infeasibility detection isn't needed</span></div>
<divclass="line"><aname="l00649"></a><spanclass="lineno"> 649</span> <spanclass="comment">// because a problem is feasible in some iteration if and only if</span></div>
<divclass="line"><aname="l00650"></a><spanclass="lineno"> 650</span> <spanclass="comment">// it's feasible in all others. Therefore we are free to use an</span></div>
<divclass="line"><aname="l00651"></a><spanclass="lineno"> 651</span> <spanclass="comment">// infeasibility detection mechanism that might work in just one</span></div>
<divclass="line"><aname="l00652"></a><spanclass="lineno"> 652</span> <spanclass="comment">// iteration and switch it off in all other iterations.</span></div>
<divclass="line"><aname="l00653"></a><spanclass="lineno"> 653</span> <spanclass="comment">// 2. When we do a slack relabeling, we must choose the amount of</span></div>
<divclass="line"><aname="l00654"></a><spanclass="lineno"> 654</span> <spanclass="comment">// price reduction to use. We choose an amount large enough to</span></div>
<divclass="line"><aname="l00655"></a><spanclass="lineno"> 655</span> <spanclass="comment">// guarantee putting the node's matching to rest, yet (although</span></div>
<divclass="line"><aname="l00656"></a><spanclass="lineno"> 656</span> <spanclass="comment">// we don't bother to prove this explicitly) small enough that</span></div>
<divclass="line"><aname="l00657"></a><spanclass="lineno"> 657</span> <spanclass="comment">// the node's price obeys the overall lower bound that holds if</span></div>
<divclass="line"><aname="l00658"></a><spanclass="lineno"> 658</span> <spanclass="comment">// the slack relabeling amount is small.</span></div>
<divclass="line"><aname="l00660"></a><spanclass="lineno"> 660</span> <spanclass="comment">// We will establish Propositions (1) and (2) above according to the</span></div>
<divclass="line"><aname="l00661"></a><spanclass="lineno"> 661</span> <spanclass="comment">// following steps:</span></div>
<divclass="line"><aname="l00662"></a><spanclass="lineno"> 662</span> <spanclass="comment">// First, we prove Lemma 1, which is a modified form of lemma 5.8 of</span></div>
<divclass="line"><aname="l00663"></a><spanclass="lineno"> 663</span> <spanclass="comment">// [Goldberg and Tarjan] giving a bound on the difference in price</span></div>
<divclass="line"><aname="l00664"></a><spanclass="lineno"> 664</span> <spanclass="comment">// between the end nodes of certain paths in the residual graph.</span></div>
<divclass="line"><aname="l00665"></a><spanclass="lineno"> 665</span> <spanclass="comment">// Second, we prove Lemma 2, which is technical lemma to establish</span></div>
<divclass="line"><aname="l00666"></a><spanclass="lineno"> 666</span> <spanclass="comment">// reachability of certain "anchor" nodes in the residual graph from</span></div>
<divclass="line"><aname="l00667"></a><spanclass="lineno"> 667</span> <spanclass="comment">// any node where a relabeling takes place.</span></div>
<divclass="line"><aname="l00668"></a><spanclass="lineno"> 668</span> <spanclass="comment">// Third, we apply the first two lemmas to prove Lemma 3 and Lemma</span></div>
<divclass="line"><aname="l00669"></a><spanclass="lineno"> 669</span> <spanclass="comment">// 4, which give two similar bounds that hold whenever the given</span></div>
<divclass="line"><aname="l00670"></a><spanclass="lineno"> 670</span> <spanclass="comment">// problem is feasible: (for feasibility detection) a bound on the</span></div>
<divclass="line"><aname="l00671"></a><spanclass="lineno"> 671</span> <spanclass="comment">// price of any node we relabel during any iteration (and the first</span></div>
<divclass="line"><aname="l00672"></a><spanclass="lineno"> 672</span> <spanclass="comment">// iteration in particular), and (for arithmetic precision) a bound</span></div>
<divclass="line"><aname="l00673"></a><spanclass="lineno"> 673</span> <spanclass="comment">// on the price of any node we relabel during the entire algorithm.</span></div>
<divclass="line"><aname="l00675"></a><spanclass="lineno"> 675</span> <spanclass="comment">// Finally, we note that if the whole-algorithm price bound can be</span></div>
<divclass="line"><aname="l00676"></a><spanclass="lineno"> 676</span> <spanclass="comment">// represented precisely by the CostValue type, arithmetic overflow</span></div>
<divclass="line"><aname="l00677"></a><spanclass="lineno"> 677</span> <spanclass="comment">// cannot occur (establishing Proposition 1), and assuming no</span></div>
<divclass="line"><aname="l00678"></a><spanclass="lineno"> 678</span> <spanclass="comment">// overflow occurs during the first iteration, any violation of the</span></div>
<divclass="line"><aname="l00682"></a><spanclass="lineno"> 682</span> <spanclass="comment">// The statement of Lemma 1 is perhaps easier to understand when the</span></div>
<divclass="line"><aname="l00683"></a><spanclass="lineno"> 683</span> <spanclass="comment">// reader knows how it will be used. To wit: In this lemma, f' and</span></div>
<divclass="line"><aname="l00684"></a><spanclass="lineno"> 684</span> <spanclass="comment">// e_0 are the flow and error parameter (epsilon) at the beginning</span></div>
<divclass="line"><aname="l00685"></a><spanclass="lineno"> 685</span> <spanclass="comment">// of the current iteration, while f and e_1 are the current</span></div>
<divclass="line"><aname="l00686"></a><spanclass="lineno"> 686</span> <spanclass="comment">// pseudoflow and error parameter when a relabeling of interest</span></div>
<divclass="line"><aname="l00687"></a><spanclass="lineno"> 687</span> <spanclass="comment">// occurs. Without loss of generality, c is the reduced cost</span></div>
<divclass="line"><aname="l00688"></a><spanclass="lineno"> 688</span> <spanclass="comment">// function at the beginning of the current iteration and p is the</span></div>
<divclass="line"><aname="l00689"></a><spanclass="lineno"> 689</span> <spanclass="comment">// change in prices that has taken place in the current iteration.</span></div>
<divclass="line"><aname="l00691"></a><spanclass="lineno"> 691</span> <spanclass="comment">// Lemma 1 (a variant of lemma 5.8 from [Goldberg and Tarjan]): Let</span></div>
<divclass="line"><aname="l00692"></a><spanclass="lineno"> 692</span> <spanclass="comment">// f be a pseudoflow and let f' be a flow. Suppose P is a simple</span></div>
<divclass="line"><aname="l00693"></a><spanclass="lineno"> 693</span> <spanclass="comment">// path from right-side node v to right-side node w such that P is</span></div>
<divclass="line"><aname="l00694"></a><spanclass="lineno"> 694</span> <spanclass="comment">// residual with respect to f and reverse(P) is residual with</span></div>
<divclass="line"><aname="l00695"></a><spanclass="lineno"> 695</span> <spanclass="comment">// respect to f'. Further, suppose c is an arc cost function with</span></div>
<divclass="line"><aname="l00696"></a><spanclass="lineno"> 696</span> <spanclass="comment">// respect to which f' is e_0-optimal with the zero price function</span></div>
<divclass="line"><aname="l00697"></a><spanclass="lineno"> 697</span> <spanclass="comment">// and p is a price function with respect to which f is e_1-optimal</span></div>
<divclass="line"><aname="l00698"></a><spanclass="lineno"> 698</span> <spanclass="comment">// with respect to p. Then</span></div>
<divclass="line"><aname="l00701"></a><spanclass="lineno"> 701</span> <spanclass="comment">// Proof: We have c_p(P) = p(v) + c(P) - p(w) and hence</span></div>
<divclass="line"><aname="l00705"></a><spanclass="lineno"> 705</span> <spanclass="comment">// Let arc a lie on P, which implies that a is residual with respect</span></div>
<divclass="line"><aname="l00706"></a><spanclass="lineno"> 706</span> <spanclass="comment">// to f and reverse(a) is residual with respect to f'.</span></div>
<divclass="line"><aname="l00707"></a><spanclass="lineno"> 707</span> <spanclass="comment">// Case 1: a is a forward arc. Then by e_1-optimality of f with</span></div>
<divclass="line"><aname="l00708"></a><spanclass="lineno"> 708</span> <spanclass="comment">// respect to p, c_p(a) >= 0 and reverse(a) is residual with</span></div>
<divclass="line"><aname="l00709"></a><spanclass="lineno"> 709</span> <spanclass="comment">// respect to f'. By e_0-optimality of f', c(a) <= e_0. So</span></div>
<divclass="line"><aname="l00711"></a><spanclass="lineno"> 711</span> <spanclass="comment">// Case 2: a is a reverse arc. Then by e_1-optimality of f with</span></div>
<divclass="line"><aname="l00712"></a><spanclass="lineno"> 712</span> <spanclass="comment">// respect to p, c_p(a) >= -e_1 and reverse(a) is residual</span></div>
<divclass="line"><aname="l00713"></a><spanclass="lineno"> 713</span> <spanclass="comment">// with respect to f'. By e_0-optimality of f', c(a) <= 0.</span></div>
<divclass="line"><aname="l00716"></a><spanclass="lineno"> 716</span> <spanclass="comment">// We assumed v and w are both right-side nodes, so there are at</span></div>
<divclass="line"><aname="l00717"></a><spanclass="lineno"> 717</span> <spanclass="comment">// most n - 2 arcs on the path P, of which at most (n-2)/2 are</span></div>
<divclass="line"><aname="l00718"></a><spanclass="lineno"> 718</span> <spanclass="comment">// forward arcs and at most (n-2)/2 are reverse arcs, so</span></div>
<divclass="line"><aname="l00722"></a><spanclass="lineno"> 722</span> <spanclass="comment">// Some of the rest of our argument is given as a sketch, omitting</span></div>
<divclass="line"><aname="l00723"></a><spanclass="lineno"> 723</span> <spanclass="comment">// several details. Also elided here are some minor technical issues</span></div>
<divclass="line"><aname="l00724"></a><spanclass="lineno"> 724</span> <spanclass="comment">// related to the first iteration, inasmuch as our arguments assume</span></div>
<divclass="line"><aname="l00725"></a><spanclass="lineno"> 725</span> <spanclass="comment">// on the surface a "previous iteration" that doesn't exist in that</span></div>
<divclass="line"><aname="l00726"></a><spanclass="lineno"> 726</span> <spanclass="comment">// case. The issues are not substantial, just a bit messy.</span></div>
<divclass="line"><aname="l00728"></a><spanclass="lineno"> 728</span> <spanclass="comment">// Lemma 2 is analogous to lemma 5.7 of [Goldberg and Tarjan], where</span></div>
<divclass="line"><aname="l00729"></a><spanclass="lineno"> 729</span> <spanclass="comment">// they have only relabelings that take place at nodes with excess</span></div>
<divclass="line"><aname="l00730"></a><spanclass="lineno"> 730</span> <spanclass="comment">// while we have only relabelings that take place as part of the</span></div>
<divclass="line"><aname="l00731"></a><spanclass="lineno"> 731</span> <spanclass="comment">// double-push operation at nodes without excess.</span></div>
<divclass="line"><aname="l00733"></a><spanclass="lineno"> 733</span> <spanclass="comment">// Lemma 2: If the problem is feasible, for any node v with excess,</span></div>
<divclass="line"><aname="l00734"></a><spanclass="lineno"> 734</span> <spanclass="comment">// there exists a path P from v to a node w with deficit such that P</span></div>
<divclass="line"><aname="l00735"></a><spanclass="lineno"> 735</span> <spanclass="comment">// is residual with respect to the current pseudoflow, and</span></div>
<divclass="line"><aname="l00736"></a><spanclass="lineno"> 736</span> <spanclass="comment">// reverse(P) is residual with respect to the flow at the beginning</span></div>
<divclass="line"><aname="l00737"></a><spanclass="lineno"> 737</span> <spanclass="comment">// of the current iteration. (Note that such a path exactly</span></div>
<divclass="line"><aname="l00738"></a><spanclass="lineno"> 738</span> <spanclass="comment">// satisfies the conditions of Lemma 1.)</span></div>
<divclass="line"><aname="l00740"></a><spanclass="lineno"> 740</span> <spanclass="comment">// Let the bound from Lemma 1 with p(w) = 0 be called B(e_0, e_1),</span></div>
<divclass="line"><aname="l00741"></a><spanclass="lineno"> 741</span> <spanclass="comment">// and let us say that when a slack relabeling of a node v occurs,</span></div>
<divclass="line"><aname="l00742"></a><spanclass="lineno"> 742</span> <spanclass="comment">// we will change the price of v by B(e_0, e_1) such that v tightly</span></div>
<divclass="line"><aname="l00743"></a><spanclass="lineno"> 743</span> <spanclass="comment">// satisfies the bound of Lemma 1. Explicitly, we define</span></div>
<divclass="line"><aname="l00746"></a><spanclass="lineno"> 746</span> <spanclass="comment">// Lemma 1 and Lemma 2 combine to bound the price change during an</span></div>
<divclass="line"><aname="l00747"></a><spanclass="lineno"> 747</span> <spanclass="comment">// iteration for any node with excess. Viewed a different way, Lemma</span></div>
<divclass="line"><aname="l00748"></a><spanclass="lineno"> 748</span> <spanclass="comment">// 1 and Lemma 2 tell us that if epsilon-optimality can be preserved</span></div>
<divclass="line"><aname="l00749"></a><spanclass="lineno"> 749</span> <spanclass="comment">// by changing the price of a node by B(e_0, e_1), that node will</span></div>
<divclass="line"><aname="l00750"></a><spanclass="lineno"> 750</span> <spanclass="comment">// never have excess again during the current iteration unless the</span></div>
<divclass="line"><aname="l00751"></a><spanclass="lineno"> 751</span> <spanclass="comment">// problem is infeasible. This insight gives us an approach to</span></div>
<divclass="line"><aname="l00752"></a><spanclass="lineno"> 752</span> <spanclass="comment">// detect infeasibility (by observing prices on nodes with excess</span></div>
<divclass="line"><aname="l00753"></a><spanclass="lineno"> 753</span> <spanclass="comment">// that violate this bound) and to relabel nodes aggressively enough</span></div>
<divclass="line"><aname="l00754"></a><spanclass="lineno"> 754</span> <spanclass="comment">// to avoid unnecessary future work while we also avoid falsely</span></div>
<divclass="line"><aname="l00755"></a><spanclass="lineno"> 755</span> <spanclass="comment">// concluding the problem is infeasible.</span></div>
<divclass="line"><aname="l00757"></a><spanclass="lineno"> 757</span> <spanclass="comment">// From Lemma 1 and Lemma 2, and taking into account our knowledge</span></div>
<divclass="line"><aname="l00758"></a><spanclass="lineno"> 758</span> <spanclass="comment">// of the slack relabeling amount, we have Lemma 3.</span></div>
<divclass="line"><aname="l00760"></a><spanclass="lineno"> 760</span> <spanclass="comment">// Lemma 3: During any iteration, if the given problem is feasible</span></div>
<divclass="line"><aname="l00761"></a><spanclass="lineno"> 761</span> <spanclass="comment">// the price of any node is reduced by less than</span></div>
<divclass="line"><aname="l00766"></a><spanclass="lineno"> 766</span> <spanclass="comment">// In the case where e_0 = e_1 * alpha, we can express the bound</span></div>
<divclass="line"><aname="l00767"></a><spanclass="lineno"> 767</span> <spanclass="comment">// just in terms of e_1, the current iteration's value of epsilon_:</span></div>
<divclass="line"><aname="l00769"></a><spanclass="lineno"> 769</span> <spanclass="comment">// so we have that p(v) is reduced by less than 2 * B(e_1).</span></div>
<divclass="line"><aname="l00771"></a><spanclass="lineno"> 771</span> <spanclass="comment">// Because we use truncating division to compute each iteration's error</span></div>
<divclass="line"><aname="l00772"></a><spanclass="lineno"> 772</span> <spanclass="comment">// parameter from that of the previous iteration, it isn't exactly</span></div>
<divclass="line"><aname="l00773"></a><spanclass="lineno"> 773</span> <spanclass="comment">// the case that e_0 = e_1 * alpha as we just assumed. To patch this</span></div>
<divclass="line"><aname="l00774"></a><spanclass="lineno"> 774</span> <spanclass="comment">// up, we can use the observation that</span></div>
<divclass="line"><aname="l00785"></a><spanclass="lineno"> 785</span> <spanclass="comment">// We sum up the bounds for all the iterations to get Lemma 4:</span></div>
<divclass="line"><aname="l00787"></a><spanclass="lineno"> 787</span> <spanclass="comment">// Lemma 4: If the given problem is feasible, after k iterations the</span></div>
<divclass="line"><aname="l00788"></a><spanclass="lineno"> 788</span> <spanclass="comment">// price of any node is always greater than</span></div>
<divclass="line"><aname="l00791"></a><spanclass="lineno"> 791</span> <spanclass="comment">// Proof: Suppose the price decrease of every node in the iteration</span></div>
<divclass="line"><aname="l00792"></a><spanclass="lineno"> 792</span> <spanclass="comment">// with epsilon_ == x is bounded by B(x) which is proportional to x</span></div>
<divclass="line"><aname="l00793"></a><spanclass="lineno"> 793</span> <spanclass="comment">// (not surprisingly, this will be the same function B() as</span></div>
<divclass="line"><aname="l00794"></a><spanclass="lineno"> 794</span> <spanclass="comment">// above). Assume for simplicity that C, the largest cost magnitude,</span></div>
<divclass="line"><aname="l00795"></a><spanclass="lineno"> 795</span> <spanclass="comment">// is a power of alpha. Then the price of each node, tallied across</span></div>
<divclass="line"><aname="l00796"></a><spanclass="lineno"> 796</span> <spanclass="comment">// all iterations is bounded</span></div>
<divclass="line"><aname="l00800"></a><spanclass="lineno"> 800</span> <spanclass="comment">// As above, this needs some patching up to handle the fact that we</span></div>
<divclass="line"><aname="l00801"></a><spanclass="lineno"> 801</span> <spanclass="comment">// use truncating arithmetic. We saw that each iteration effectively</span></div>
<divclass="line"><aname="l00802"></a><spanclass="lineno"> 802</span> <spanclass="comment">// reduces the price bound by alpha * (n-2), hence if there are k</span></div>
<divclass="line"><aname="l00803"></a><spanclass="lineno"> 803</span> <spanclass="comment">// iterations, the bound is</span></div>
<divclass="line"><aname="l00808"></a><spanclass="lineno"> 808</span> <spanclass="comment">// The bound of lemma 4 can be used to warn for possible overflow of</span></div>
<divclass="line"><aname="l00809"></a><spanclass="lineno"> 809</span> <spanclass="comment">// arithmetic precision. But because it involves the number of</span></div>
<divclass="line"><aname="l00810"></a><spanclass="lineno"> 810</span> <spanclass="comment">// iterations, k, we might as well count through the iterations</span></div>
<divclass="line"><aname="l00811"></a><spanclass="lineno"> 811</span> <spanclass="comment">// simply adding up the bounds given by Lemma 3 to get a tighter</span></div>
<divclass="line"><aname="l00812"></a><spanclass="lineno"> 812</span> <spanclass="comment">// result. This is what the implementation does.</span></div>
<divclass="line"><aname="l00814"></a><spanclass="lineno"> 814</span> <spanclass="comment">// A lower bound on the price of any node at any time throughout the</span></div>
<divclass="line"><aname="l00815"></a><spanclass="lineno"> 815</span> <spanclass="comment">// computation. A price below this level proves infeasibility; this</span></div>
<divclass="line"><aname="l00816"></a><spanclass="lineno"> 816</span> <spanclass="comment">// value is used for feasibility detection. We use this value also</span></div>
<divclass="line"><aname="l00817"></a><spanclass="lineno"> 817</span> <spanclass="comment">// to rule out the possibility of arithmetic overflow or warn the</span></div>
<divclass="line"><aname="l00818"></a><spanclass="lineno"> 818</span> <spanclass="comment">// client that we have not been able to rule out that possibility.</span></div>
<divclass="line"><aname="l00820"></a><spanclass="lineno"> 820</span> <spanclass="comment">// We can use the value implied by Lemma 4 here, but note that that</span></div>
<divclass="line"><aname="l00821"></a><spanclass="lineno"> 821</span> <spanclass="comment">// value includes k, the number of iterations. It's plenty fast if</span></div>
<divclass="line"><aname="l00822"></a><spanclass="lineno"> 822</span> <spanclass="comment">// we count through the iterations to compute that value, but if</span></div>
<divclass="line"><aname="l00823"></a><spanclass="lineno"> 823</span> <spanclass="comment">// we're going to count through the iterations, we might as well use</span></div>
<divclass="line"><aname="l00824"></a><spanclass="lineno"> 824</span> <spanclass="comment">// the two-parameter bound from Lemma 3, summing up as we go. This</span></div>
<divclass="line"><aname="l00825"></a><spanclass="lineno"> 825</span> <spanclass="comment">// gives us a tighter bound and more comprehensible code.</span></div>
<divclass="line"><aname="l00827"></a><spanclass="lineno"> 827</span> <spanclass="comment">// While computing this bound, if we find the value justified by the</span></div>
<divclass="line"><aname="l00828"></a><spanclass="lineno"> 828</span> <spanclass="comment">// theory lies outside the representable range of CostValue, we</span></div>
<divclass="line"><aname="l00829"></a><spanclass="lineno"> 829</span> <spanclass="comment">// conclude that the given arc costs have magnitudes so large that</span></div>
<divclass="line"><aname="l00830"></a><spanclass="lineno"> 830</span> <spanclass="comment">// we cannot guarantee our calculations don't overflow. If the value</span></div>
<divclass="line"><aname="l00831"></a><spanclass="lineno"> 831</span> <spanclass="comment">// justified by the theory lies inside the representable range of</span></div>
<divclass="line"><aname="l00832"></a><spanclass="lineno"> 832</span> <spanclass="comment">// CostValue, we commit that our calculation will not overflow. This</span></div>
<divclass="line"><aname="l00833"></a><spanclass="lineno"> 833</span> <spanclass="comment">// commitment means we need to be careful with the amount by which</span></div>
<divclass="line"><aname="l00834"></a><spanclass="lineno"> 834</span> <spanclass="comment">// we relabel right-side nodes that are incident to any node with</span></div>
<divclass="line"><aname="l00835"></a><spanclass="lineno"> 835</span> <spanclass="comment">// only one neighbor.</span></div>
<divclass="line"><aname="l00838"></a><spanclass="lineno"> 838</span> <spanclass="comment">// A bound on the amount by which a node's price can be reduced</span></div>
<divclass="line"><aname="l00839"></a><spanclass="lineno"> 839</span> <spanclass="comment">// during the current iteration, used only for slack</span></div>
<divclass="line"><aname="l00840"></a><spanclass="lineno"> 840</span> <spanclass="comment">// relabelings. Where epsilon is the first iteration's error</span></div>
<divclass="line"><aname="l00841"></a><spanclass="lineno"> 841</span> <spanclass="comment">// parameter and C is the largest magnitude of an arc cost, we set</span></div>
<divclass="line"><aname="l00845"></a><spanclass="lineno"> 845</span> <spanclass="comment">// We could use slack_relabeling_price_ for feasibility detection</span></div>
<divclass="line"><aname="l00846"></a><spanclass="lineno"> 846</span> <spanclass="comment">// but the feasibility threshold is double the slack relabeling</span></div>
<divclass="line"><aname="l00847"></a><spanclass="lineno"> 847</span> <spanclass="comment">// amount and we judge it not to be worth having to multiply by two</span></div>
<divclass="line"><aname="l00848"></a><spanclass="lineno"> 848</span> <spanclass="comment">// gratuitously to check feasibility in each double push</span></div>
<divclass="line"><aname="l00849"></a><spanclass="lineno"> 849</span> <spanclass="comment">// operation. Instead we settle for feasibility detection using</span></div>
<divclass="line"><aname="l00850"></a><spanclass="lineno"> 850</span> <spanclass="comment">// price_lower_bound_ instead, which is somewhat slower in the</span></div>
<divclass="line"><aname="l00851"></a><spanclass="lineno"> 851</span> <spanclass="comment">// infeasible case because more relabelings will be required for</span></div>
<divclass="line"><aname="l00852"></a><spanclass="lineno"> 852</span> <spanclass="comment">// some node price to attain the looser bound.</span></div>
<divclass="line"><aname="l00855"></a><spanclass="lineno"> 855</span> <spanclass="comment">// Computes the value of the bound on price reduction for an</span></div>
<divclass="line"><aname="l00856"></a><spanclass="lineno"> 856</span> <spanclass="comment">// iteration, given the old and new values of epsilon_. Because the</span></div>
<divclass="line"><aname="l00857"></a><spanclass="lineno"> 857</span> <spanclass="comment">// expression computed here is used in at least one place where we</span></div>
<divclass="line"><aname="l00858"></a><spanclass="lineno"> 858</span> <spanclass="comment">// want an additional factor in the denominator, we take that factor</span></div>
<divclass="line"><aname="l00859"></a><spanclass="lineno"> 859</span> <spanclass="comment">// as an argument. If extra_divisor == 1, this function computes of</span></div>
<divclass="line"><aname="l00860"></a><spanclass="lineno"> 860</span> <spanclass="comment">// the function B() discussed above.</span></div>
<divclass="line"><aname="l00862"></a><spanclass="lineno"> 862</span> <spanclass="comment">// Avoids overflow in computing the bound, and sets *in_range =</span></div>
<divclass="line"><aname="l00863"></a><spanclass="lineno"> 863</span> <spanclass="comment">// false if the value of the bound doesn't fit in CostValue.</span></div>
<divclass="line"><aname="l00867"></a><spanclass="lineno"> 867</span> <spanclass="keyword">const</span><aclass="code"href="namespaceoperations__research.html#a1d1a935ab48f768867fc7e8607ca97b4">CostValue</a> n = graph_->num_nodes();</div>
<divclass="line"><aname="l00868"></a><spanclass="lineno"> 868</span> <spanclass="comment">// We work in double-precision floating point to determine whether</span></div>
<divclass="line"><aname="l00869"></a><spanclass="lineno"> 869</span> <spanclass="comment">// we'll overflow the integral CostValue type's range of</span></div>
<divclass="line"><aname="l00870"></a><spanclass="lineno"> 870</span> <spanclass="comment">// representation. Switching between integer and double is a</span></div>
<divclass="line"><aname="l00871"></a><spanclass="lineno"> 871</span> <spanclass="comment">// rather expensive operation, but we do this only twice per</span></div>
<divclass="line"><aname="l00872"></a><spanclass="lineno"> 872</span> <spanclass="comment">// scaling iteration, so we can afford it rather than resort to</span></div>
<divclass="line"><aname="l00873"></a><spanclass="lineno"> 873</span> <spanclass="comment">// complex and subtle tricks within the bounds of integer</span></div>
<divclass="line"><aname="l00876"></a><spanclass="lineno"> 876</span> <spanclass="comment">// You will want to read the comments above about</span></div>
<divclass="line"><aname="l00877"></a><spanclass="lineno"> 877</span> <spanclass="comment">// price_lower_bound_ and slack_relabeling_price_, and have a</span></div>
<divclass="line"><aname="l00879"></a><spanclass="lineno"> 879</span> <spanclass="keyword">const</span><spanclass="keywordtype">double</span> result =</div>
<divclass="line"><aname="l00889"></a><spanclass="lineno"> 889</span> <spanclass="comment">// Don't touch *in_range; other computations could already have</span></div>
<divclass="line"><aname="l00890"></a><spanclass="lineno"> 890</span> <spanclass="comment">// set it to false and we don't want to overwrite that result.</span></div>
<divclass="line"><aname="l00895"></a><spanclass="lineno"> 895</span> <spanclass="comment">// A scaled record of the largest arc-cost magnitude we've been</span></div>
<divclass="line"><aname="l00896"></a><spanclass="lineno"> 896</span> <spanclass="comment">// given during problem setup. This is used to set the initial value</span></div>
<divclass="line"><aname="l00897"></a><spanclass="lineno"> 897</span> <spanclass="comment">// of epsilon_, which in turn is used not only as the error</span></div>
<divclass="line"><aname="l00898"></a><spanclass="lineno"> 898</span> <spanclass="comment">// parameter but also to determine whether we risk arithmetic</span></div>
<divclass="line"><aname="l00899"></a><spanclass="lineno"> 899</span> <spanclass="comment">// overflow during the algorithm.</span></div>
<divclass="line"><aname="l00901"></a><spanclass="lineno"> 901</span> <spanclass="comment">// Note: Our treatment of arithmetic overflow assumes the following</span></div>
<divclass="line"><aname="l00902"></a><spanclass="lineno"> 902</span> <spanclass="comment">// property of CostValue:</span></div>
<divclass="line"><aname="l00903"></a><spanclass="lineno"> 903</span> <spanclass="comment">// -std::numeric_limits<CostValue>::max() is a representable</span></div>
<divclass="line"><aname="l00905"></a><spanclass="lineno"> 905</span> <spanclass="comment">// That property is satisfied if CostValue uses a two's-complement</span></div>
<divclass="line"><aname="l00909"></a><spanclass="lineno"> 909</span> <spanclass="comment">// The total excess in the graph. Given our asymmetric definition of</span></div>
<divclass="line"><aname="l00910"></a><spanclass="lineno"> 910</span> <spanclass="comment">// epsilon-optimality and our use of the double-push operation, this</span></div>
<divclass="line"><aname="l00911"></a><spanclass="lineno"> 911</span> <spanclass="comment">// equals the number of unmatched left-side nodes.</span></div>
<divclass="line"><aname="l00914"></a><spanclass="lineno"> 914</span> <spanclass="comment">// Indexed by node index, the price_ values are maintained only for</span></div>
<divclass="line"><aname="l00917"></a><spanclass="lineno"> 917</span> <spanclass="comment">// Note: We use a ZVector to only allocate a vector of size num_left_nodes_</span></div>
<divclass="line"><aname="l00918"></a><spanclass="lineno"> 918</span> <spanclass="comment">// instead of 2*num_left_nodes_ since the right-side node indices start at</span></div>
<divclass="line"><aname="l00922"></a><spanclass="lineno"> 922</span> <spanclass="comment">// Indexed by left-side node index, the matched_arc_ array gives the</span></div>
<divclass="line"><aname="l00923"></a><spanclass="lineno"> 923</span> <spanclass="comment">// arc index of the arc matching any given left-side node, or</span></div>
<divclass="line"><aname="l00924"></a><spanclass="lineno"> 924</span> <spanclass="comment">// GraphType::kNilArc if the node is unmatched.</span></div>
<divclass="line"><aname="l00927"></a><spanclass="lineno"> 927</span> <spanclass="comment">// Indexed by right-side node index, the matched_node_ array gives</span></div>
<divclass="line"><aname="l00928"></a><spanclass="lineno"> 928</span> <spanclass="comment">// the node index of the left-side node matching any given</span></div>
<divclass="line"><aname="l00929"></a><spanclass="lineno"> 929</span> <spanclass="comment">// right-side node, or GraphType::kNilNode if the right-side node is</span></div>
<divclass="line"><aname="l00932"></a><spanclass="lineno"> 932</span> <spanclass="comment">// Note: We use a ZVector for the same reason as for price_.</span></div>
<divclass="line"><aname="l00935"></a><spanclass="lineno"> 935</span> <spanclass="comment">// The array of arc costs as given in the problem definition, except</span></div>
<divclass="line"><aname="l00936"></a><spanclass="lineno"> 936</span> <spanclass="comment">// that they are scaled up by the number of nodes in the graph so we</span></div>
<divclass="line"><aname="l00937"></a><spanclass="lineno"> 937</span> <spanclass="comment">// can use integer arithmetic throughout.</span></div>
<divclass="line"><aname="l00940"></a><spanclass="lineno"> 940</span> <spanclass="comment">// The container of active nodes (i.e., unmatched nodes). This can</span></div>
<divclass="line"><aname="l00941"></a><spanclass="lineno"> 941</span> <spanclass="comment">// be switched easily between ActiveNodeStack and ActiveNodeQueue</span></div>
<divclass="line"><aname="l00942"></a><spanclass="lineno"> 942</span> <spanclass="comment">// for experimentation.</span></div>
<divclass="line"><aname="l00945"></a><spanclass="lineno"> 945</span> <spanclass="comment">// Statistics giving the overall numbers of various operations the</span></div>
<divclass="line"><aname="l00949"></a><spanclass="lineno"> 949</span> <spanclass="comment">// Statistics giving the numbers of various operations the algorithm</span></div>
<divclass="line"><aname="l00950"></a><spanclass="lineno"> 950</span> <spanclass="comment">// has performed in the current iteration.</span></div>
<divclass="line"><aname="l01013"></a><spanclass="lineno"> 1013</span> <aclass="code"href="classoperations__research_1_1_linear_sum_assignment.html#aca73212d30b08a7c287c311b74311a6e">NodeIndex</a> head = Head(arc);</div>
<divclass="line"><aname="l01051"></a><spanclass="lineno"> 1051</span> <spanclass="comment">// Logically this class should be defined inside OptimizeGraphLayout,</span></div>
<divclass="line"><aname="l01052"></a><spanclass="lineno"> 1052</span> <spanclass="comment">// but compilation fails if we do that because C++98 doesn't allow</span></div>
<divclass="line"><aname="l01053"></a><spanclass="lineno"> 1053</span> <spanclass="comment">// instantiation of member templates with function-scoped types as</span></div>
<divclass="line"><aname="l01054"></a><spanclass="lineno"> 1054</span> <spanclass="comment">// template parameters, which in turn is because those function-scoped</span></div>
<divclass="line"><aname="l01061"></a><spanclass="lineno"> 1061</span> <spanclass="comment">// Says ArcIndex a is less than ArcIndex b if arc a's tail is less</span></div>
<divclass="line"><aname="l01062"></a><spanclass="lineno"> 1062</span> <spanclass="comment">// than arc b's tail. If their tails are equal, orders according to</span></div>
<divclass="line"><aname="l01074"></a><spanclass="lineno"> 1074</span> <spanclass="comment">// Copy and assign are allowed; they have to be for STL to work</span></div>
<divclass="line"><aname="l01075"></a><spanclass="lineno"> 1075</span> <spanclass="comment">// with this functor, although it seems like a bug for STL to be</span></div>
<divclass="line"><aname="l01076"></a><spanclass="lineno"> 1076</span> <spanclass="comment">// written that way.</span></div>
<divclass="line"><aname="l01079"></a><spanclass="lineno"> 1079</span> <spanclass="comment">// Passes ownership of the cycle handler to the caller.</span></div>
<divclass="line"><aname="l01089"></a><spanclass="lineno"> 1089</span> <spanclass="comment">// The graph argument is only to give us a non-const-qualified</span></div>
<divclass="line"><aname="l01090"></a><spanclass="lineno"> 1090</span> <spanclass="comment">// handle on the graph we already have. Any different graph is</span></div>
<divclass="line"><aname="l01116"></a><spanclass="lineno"> 1116</span> <spanclass="comment">// For today we always return true; in the future updating epsilon</span></div>
<divclass="line"><aname="l01117"></a><spanclass="lineno"> 1117</span> <spanclass="comment">// in sophisticated ways could conceivably detect infeasibility</span></div>
<divclass="line"><aname="l01118"></a><spanclass="lineno"> 1118</span> <spanclass="comment">// before the first iteration of Refine().</span></div>
<divclass="line"><aname="l01122"></a><spanclass="lineno"> 1122</span> <spanclass="comment">// For production code that checks whether a left-side node is active.</span></div>
<divclass="line"><aname="l01130"></a><spanclass="lineno"> 1130</span> <spanclass="comment">// Only for debugging. Separate from the production IsActive() method</span></div>
<divclass="line"><aname="l01131"></a><spanclass="lineno"> 1131</span> <spanclass="comment">// so that method can assert that its argument is a left-side node,</span></div>
<divclass="line"><aname="l01132"></a><spanclass="lineno"> 1132</span> <spanclass="comment">// while for debugging we need to be able to test any node.</span></div>
<divclass="line"><aname="l01155"></a><spanclass="lineno"> 1155</span> <spanclass="comment">// There exists a price function such that the admissible arcs at the</span></div>
<divclass="line"><aname="l01156"></a><spanclass="lineno"> 1156</span> <spanclass="comment">// beginning of an iteration are exactly the reverse arcs of all</span></div>
<divclass="line"><aname="l01157"></a><spanclass="lineno"> 1157</span> <spanclass="comment">// matching arcs. Saturating all admissible arcs with respect to that</span></div>
<divclass="line"><aname="l01158"></a><spanclass="lineno"> 1158</span> <spanclass="comment">// price function therefore means simply unmatching every matched</span></div>
<divclass="line"><aname="l01161"></a><spanclass="lineno"> 1161</span> <spanclass="comment">// In the future we will price out arcs, which will reduce the set of</span></div>
<divclass="line"><aname="l01162"></a><spanclass="lineno"> 1162</span> <spanclass="comment">// nodes we unmatch here. If a matching arc is priced out, we will not</span></div>
<divclass="line"><aname="l01163"></a><spanclass="lineno"> 1163</span> <spanclass="comment">// unmatch its endpoints since that element of the matching is</span></div>
<divclass="line"><aname="l01164"></a><spanclass="lineno"> 1164</span> <spanclass="comment">// guaranteed not to change.</span></div>
<divclass="line"><aname="l01172"></a><spanclass="lineno"> 1172</span> <spanclass="comment">// This can happen in the first iteration when nothing is</span></div>
<divclass="line"><aname="l01176"></a><spanclass="lineno"> 1176</span> <spanclass="comment">// We're about to create a unit of excess by unmatching these nodes.</span></div>
<divclass="line"><aname="l01185"></a><spanclass="lineno"> 1185</span> <spanclass="comment">// Returns true for success, false for infeasible.</span></div>
<divclass="line"><aname="l01190"></a><spanclass="lineno"> 1190</span> <<<spanclass="stringliteral">"must be active (unmatched)!"</span>;</div>
<divclass="line"><aname="l01193"></a><spanclass="lineno"> 1193</span> <spanclass="keyword">const</span><aclass="code"href="namespaceoperations__research.html#a1d1a935ab48f768867fc7e8607ca97b4">CostValue</a> gap = summary.second;</div>
<divclass="line"><aname="l01194"></a><spanclass="lineno"> 1194</span> <spanclass="comment">// Now we have the best arc incident to source, i.e., the one with</span></div>
<divclass="line"><aname="l01195"></a><spanclass="lineno"> 1195</span> <spanclass="comment">// minimum reduced cost. Match that arc, unmatching its head if</span></div>
<divclass="line"><aname="l01203"></a><spanclass="lineno"> 1203</span> <spanclass="comment">// Unmatch new_mate from its current mate, pushing the unit of</span></div>
<divclass="line"><aname="l01204"></a><spanclass="lineno"> 1204</span> <spanclass="comment">// flow back to a node on the left side as a unit of excess.</span></div>
<divclass="line"><aname="l01210"></a><spanclass="lineno"> 1210</span> <spanclass="comment">// We are about to increase the cardinality of the matching.</span></div>
<divclass="line"><aname="l01229"></a><spanclass="lineno"> 1229</span> <spanclass="comment">// Get an active node (i.e., one with excess == 1) and discharge</span></div>
<divclass="line"><aname="l01230"></a><spanclass="lineno"> 1230</span> <spanclass="comment">// it using DoublePush.</span></div>
<divclass="line"><aname="l01235"></a><spanclass="lineno"> 1235</span> <spanclass="comment">// If infeasibility is detected after the first iteration, we</span></div>
<divclass="line"><aname="l01236"></a><spanclass="lineno"> 1236</span> <spanclass="comment">// have a bug. We don't crash production code in this case but</span></div>
<divclass="line"><aname="l01237"></a><spanclass="lineno"> 1237</span> <spanclass="comment">// we know we're returning a wrong answer so we we leave a</span></div>
<divclass="line"><aname="l01238"></a><spanclass="lineno"> 1238</span> <spanclass="comment">// message in the logs to increase our hope of chasing down the</span></div>
<divclass="line"><aname="l01241"></a><spanclass="lineno"> 1241</span> <<<spanclass="stringliteral">"Infeasibility detection triggered after first iteration found "</span></div>
<divclass="line"><aname="l01251"></a><spanclass="lineno"> 1251</span> <spanclass="comment">// Computes best_arc, the minimum reduced-cost arc incident to</span></div>
<divclass="line"><aname="l01252"></a><spanclass="lineno"> 1252</span> <spanclass="comment">// left_node and admissibility_gap, the amount by which the reduced</span></div>
<divclass="line"><aname="l01253"></a><spanclass="lineno"> 1253</span> <spanclass="comment">// cost of best_arc must be increased to make it equal in reduced cost</span></div>
<divclass="line"><aname="l01254"></a><spanclass="lineno"> 1254</span> <spanclass="comment">// to another residual arc incident to left_node.</span></div>
<divclass="line"><aname="l01256"></a><spanclass="lineno"> 1256</span> <spanclass="comment">// Precondition: left_node is unmatched and has at least one incident</span></div>
<divclass="line"><aname="l01257"></a><spanclass="lineno"> 1257</span> <spanclass="comment">// arc. This allows us to simplify the code. The debug-only</span></div>
<divclass="line"><aname="l01258"></a><spanclass="lineno"> 1258</span> <spanclass="comment">// counterpart to this routine is LinearSumAssignment::ImplicitPrice()</span></div>
<divclass="line"><aname="l01259"></a><spanclass="lineno"> 1259</span> <spanclass="comment">// and it assumes there is an incident arc but does not assume the</span></div>
<divclass="line"><aname="l01260"></a><spanclass="lineno"> 1260</span> <spanclass="comment">// node is unmatched. The condition that each left node has at least</span></div>
<divclass="line"><aname="l01261"></a><spanclass="lineno"> 1261</span> <spanclass="comment">// one incident arc is explicitly computed during FinalizeSetup().</span></div>
<divclass="line"><aname="l01263"></a><spanclass="lineno"> 1263</span> <spanclass="comment">// This function is large enough that our suggestion that the compiler</span></div>
<divclass="line"><aname="l01264"></a><spanclass="lineno"> 1264</span> <spanclass="comment">// inline it might be pointless.</span></div>
<divclass="line"><aname="l01269"></a><spanclass="lineno"> 1269</span> <<<spanclass="stringliteral">"Node "</span><< left_node <<<spanclass="stringliteral">" must be active (unmatched)!"</span>;</div>
<divclass="line"><aname="l01274"></a><spanclass="lineno"> 1274</span> <spanclass="comment">// We choose second_min_partial_reduced_cost so that in the case of</span></div>
<divclass="line"><aname="l01275"></a><spanclass="lineno"> 1275</span> <spanclass="comment">// the largest possible gap (which results from a left-side node</span></div>
<divclass="line"><aname="l01276"></a><spanclass="lineno"> 1276</span> <spanclass="comment">// with only a single incident residual arc), the corresponding</span></div>
<divclass="line"><aname="l01277"></a><spanclass="lineno"> 1277</span> <spanclass="comment">// right-side node will be relabeled by an amount that exactly</span></div>
<divclass="line"><aname="l01295"></a><spanclass="lineno"> 1295</span> <spanclass="keyword">const</span><aclass="code"href="namespaceoperations__research.html#a1d1a935ab48f768867fc7e8607ca97b4">CostValue</a> gap = std::min<CostValue>(</div>
<divclass="line"><aname="l01303"></a><spanclass="lineno"> 1303</span> <spanclass="comment">// Requires the precondition, explicitly computed in FinalizeSetup(),</span></div>
<divclass="line"><aname="l01304"></a><spanclass="lineno"> 1304</span> <spanclass="comment">// that every left-side node has at least one incident arc.</span></div>
<divclass="line"><aname="l01311"></a><spanclass="lineno"> 1311</span> <spanclass="comment">// We must not execute this method if left_node has no incident arc.</span></div>
<divclass="line"><aname="l01322"></a><spanclass="lineno"> 1322</span> <spanclass="comment">// Only one arc is incident to left_node, and the node is</span></div>
<divclass="line"><aname="l01323"></a><spanclass="lineno"> 1323</span> <spanclass="comment">// currently matched along that arc, which must be the case in any</span></div>
<divclass="line"><aname="l01324"></a><spanclass="lineno"> 1324</span> <spanclass="comment">// feasible solution. Therefore we implicitly price this node so</span></div>
<divclass="line"><aname="l01325"></a><spanclass="lineno"> 1325</span> <spanclass="comment">// low that we will never consider unmatching it.</span></div>
<divclass="line"><aname="l01357"></a><spanclass="lineno"> 1357</span> <spanclass="comment">// Get the implicit price of left_node and make sure the reduced</span></div>
<divclass="line"><aname="l01358"></a><spanclass="lineno"> 1358</span> <spanclass="comment">// costs of left_node's incident arcs are in bounds.</span></div>
<divclass="line"><aname="l01364"></a><spanclass="lineno"> 1364</span> <spanclass="comment">// Note the asymmetric definition of epsilon-optimality that we</span></div>
<divclass="line"><aname="l01365"></a><spanclass="lineno"> 1365</span> <spanclass="comment">// use because it means we can saturate all admissible arcs in</span></div>
<divclass="line"><aname="l01366"></a><spanclass="lineno"> 1366</span> <spanclass="comment">// the beginning of Refine() just by unmatching all matched</span></div>
<divclass="line"><aname="l01369"></a><spanclass="lineno"> 1369</span> <spanclass="comment">// The reverse arc is residual. Epsilon-optimality requires</span></div>
<divclass="line"><aname="l01370"></a><spanclass="lineno"> 1370</span> <spanclass="comment">// that the reduced cost of the forward arc be at most</span></div>
<divclass="line"><aname="l01376"></a><spanclass="lineno"> 1376</span> <spanclass="comment">// The forward arc is residual. Epsilon-optimality requires</span></div>
<divclass="line"><aname="l01377"></a><spanclass="lineno"> 1377</span> <spanclass="comment">// that the reduced cost of the forward arc be at least zero.</span></div>
<divclass="line"><aname="l01390"></a><spanclass="lineno"> 1390</span> <spanclass="comment">// epsilon_ must be greater than kMinEpsilon so that in the case</span></div>
<divclass="line"><aname="l01391"></a><spanclass="lineno"> 1391</span> <spanclass="comment">// where the largest arc cost is zero, we still do a Refine()</span></div>
<divclass="line"><aname="l01433"></a><spanclass="lineno"> 1433</span>  LOG(WARNING) <<<spanclass="stringliteral">"Price change bound exceeds range of representable "</span></div>
<divclass="line"><aname="l01434"></a><spanclass="lineno"> 1434</span> <<<spanclass="stringliteral">"costs; arithmetic overflow is not ruled out and "</span></div>
<divclass="line"><aname="l01435"></a><spanclass="lineno"> 1435</span> <<<spanclass="stringliteral">"infeasibility might go undetected."</span>;</div>
<divclass="line"><aname="l01452"></a><spanclass="lineno"> 1452</span> <spanclass="comment">// Note: FinalizeSetup() might have been called already by white-box</span></div>
<divclass="line"><aname="l01453"></a><spanclass="lineno"> 1453</span> <spanclass="comment">// test code or by a client that wants to react to the possibility</span></div>
<divclass="line"><aname="l01454"></a><spanclass="lineno"> 1454</span> <spanclass="comment">// of overflow before solving the given problem, but FinalizeSetup()</span></div>
<divclass="line"><aname="l01455"></a><spanclass="lineno"> 1455</span> <spanclass="comment">// is idempotent and reasonably fast, so we call it unconditionally</span></div>
<divclass="line"><aname="l01474"></a><spanclass="lineno"> 1474</span> <spanclass="comment">// It is illegal to call this method unless we successfully computed</span></div>
<divclass="line"><aname="l01475"></a><spanclass="lineno"> 1475</span> <spanclass="comment">// an optimum assignment.</span></div>
<divclass="ttc"id="aclassoperations__research_1_1_arc_index_ordering_by_tail_node_html_a7fc8cebeaaae309b2282772d6cac1888"><divclass="ttname"><ahref="classoperations__research_1_1_arc_index_ordering_by_tail_node.html#a7fc8cebeaaae309b2282772d6cac1888">operations_research::ArcIndexOrderingByTailNode::operator()</a></div><divclass="ttdeci">bool operator()(typename GraphType::ArcIndex a, typename GraphType::ArcIndex b) const</div><divclass="ttdef"><b>Definition:</b><ahref="linear__assignment_8h_source.html#l01064">linear_assignment.h:1064</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1_linear_sum_assignment_html_adb325b7bb71f0f00df13383ad0b2adae"><divclass="ttname"><ahref="classoperations__research_1_1_linear_sum_assignment.html#adb325b7bb71f0f00df13383ad0b2adae">operations_research::LinearSumAssignment::Graph</a></div><divclass="ttdeci">const GraphType & Graph() const</div><divclass="ttdef"><b>Definition:</b><ahref="linear__assignment_8h_source.html#l00281">linear_assignment.h:281</a></div></div>