<ahref="linear__assignment_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aid="l00001"name="l00001"></a><spanclass="lineno"> 1</span><spanclass="comment">// Copyright 2010-2021 Google LLC</span></div>
<divclass="line"><aid="l00002"name="l00002"></a><spanclass="lineno"> 2</span><spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aid="l00003"name="l00003"></a><spanclass="lineno"> 3</span><spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aid="l00004"name="l00004"></a><spanclass="lineno"> 4</span><spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aid="l00008"name="l00008"></a><spanclass="lineno"> 8</span><spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aid="l00009"name="l00009"></a><spanclass="lineno"> 9</span><spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aid="l00010"name="l00010"></a><spanclass="lineno"> 10</span><spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aid="l00011"name="l00011"></a><spanclass="lineno"> 11</span><spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aid="l00012"name="l00012"></a><spanclass="lineno"> 12</span><spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aid="l00015"name="l00015"></a><spanclass="lineno"> 15</span><spanclass="comment">// An implementation of a cost-scaling push-relabel algorithm for the</span></div>
<divclass="line"><aid="l00016"name="l00016"></a><spanclass="lineno"> 16</span><spanclass="comment">// assignment problem (minimum-cost perfect bipartite matching), from</span></div>
<divclass="line"><aid="l00017"name="l00017"></a><spanclass="lineno"> 17</span><spanclass="comment">// the paper of Goldberg and Kennedy (1995).</span></div>
<divclass="line"><aid="l00020"name="l00020"></a><spanclass="lineno"> 20</span><spanclass="comment">// This implementation finds the minimum-cost perfect assignment in</span></div>
<divclass="line"><aid="l00021"name="l00021"></a><spanclass="lineno"> 21</span><spanclass="comment">// the given graph with integral edge weights set through the</span></div>
<divclass="line"><aid="l00024"name="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"><aid="l00025"name="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"><aid="l00026"name="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"><aid="l00027"name="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"><aid="l00028"name="l00028"></a><spanclass="lineno"> 28</span><spanclass="comment">// factor could be shaved off the running time bound using the technique</span></div>
<divclass="line"><aid="l00029"name="l00029"></a><spanclass="lineno"> 29</span><spanclass="comment">// described in http://dx.doi.org/10.1137/S0895480194281185</span></div>
<divclass="line"><aid="l00030"name="l00030"></a><spanclass="lineno"> 30</span><spanclass="comment">// (see also http://theory.stanford.edu/~robert/papers/glob_upd.ps).</span></div>
<divclass="line"><aid="l00048"name="l00048"></a><spanclass="lineno"> 48</span><spanclass="comment">// const int arc_tail = ... // must be in [0, num_left_nodes)</span></div>
<divclass="line"><aid="l00049"name="l00049"></a><spanclass="lineno"> 49</span><spanclass="comment">// const int arc_head = ... // must be in [num_left_nodes, num_nodes)</span></div>
<divclass="line"><aid="l00054"name="l00054"></a><spanclass="lineno"> 54</span><spanclass="comment">// // Build the StaticGraph. You can skip this step by using a ListGraph<></span></div>
<divclass="line"><aid="l00055"name="l00055"></a><spanclass="lineno"> 55</span><spanclass="comment">// // instead, but then the ComputeAssignment() below will be slower. It is</span></div>
<divclass="line"><aid="l00056"name="l00056"></a><spanclass="lineno"> 56</span><spanclass="comment">// // okay if your graph is small and performance is not critical though.</span></div>
<divclass="line"><aid="l00066"name="l00066"></a><spanclass="lineno"> 66</span><spanclass="comment">// // You can also replace 'arc_costs[arc]' by something like</span></div>
<divclass="line"><aid="l00068"name="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"><aid="l00074"name="l00074"></a><spanclass="lineno"> 74</span><spanclass="comment">// // Retrieve the cost of the optimum assignment.</span></div>
<divclass="line"><aid="l00076"name="l00076"></a><spanclass="lineno"> 76</span><spanclass="comment">// // Retrieve the node-node correspondence of the optimum assignment and the</span></div>
<divclass="line"><aid="l00077"name="l00077"></a><spanclass="lineno"> 77</span><spanclass="comment">// // cost of each node pairing.</span></div>
<divclass="line"><aid="l00085"name="l00085"></a><spanclass="lineno"> 85</span><spanclass="comment">// In the following, we consider a bipartite graph</span></div>
<divclass="line"><aid="l00086"name="l00086"></a><spanclass="lineno"> 86</span><spanclass="comment">// G = (V = X union Y, E subset XxY),</span></div>
<divclass="line"><aid="l00087"name="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"><aid="l00088"name="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"><aid="l00089"name="l00089"></a><spanclass="lineno"> 89</span><spanclass="comment">// graph, and m = |E| denotes the number of arcs in the graph.</span></div>
<divclass="line"><aid="l00091"name="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"><aid="l00092"name="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"><aid="l00093"name="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"><aid="l00094"name="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"><aid="l00095"name="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"><aid="l00096"name="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"><aid="l00097"name="l00097"></a><spanclass="lineno"> 97</span><spanclass="comment">// arcs in M.</span></div>
<divclass="line"><aid="l00099"name="l00099"></a><spanclass="lineno"> 99</span><spanclass="comment">// The assignment problem is to find a perfect matching of minimum</span></div>
<divclass="line"><aid="l00100"name="l00100"></a><spanclass="lineno"> 100</span><spanclass="comment">// cost in the given bipartite graph. The present algorithm reduces</span></div>
<divclass="line"><aid="l00101"name="l00101"></a><spanclass="lineno"> 101</span><spanclass="comment">// the assignment problem to an instance of the minimum-cost flow</span></div>
<divclass="line"><aid="l00102"name="l00102"></a><spanclass="lineno"> 102</span><spanclass="comment">// problem and takes advantage of special properties of the resulting</span></div>
<divclass="line"><aid="l00103"name="l00103"></a><spanclass="lineno"> 103</span><spanclass="comment">// minimum-cost flow problem to solve it efficiently using a</span></div>
<divclass="line"><aid="l00104"name="l00104"></a><spanclass="lineno"> 104</span><spanclass="comment">// push-relabel method. For more information about minimum-cost flow</span></div>
<divclass="line"><aid="l00105"name="l00105"></a><spanclass="lineno"> 105</span><spanclass="comment">// see ortools/graph/min_cost_flow.h</span></div>
<divclass="line"><aid="l00107"name="l00107"></a><spanclass="lineno"> 107</span><spanclass="comment">// The method used here is the cost-scaling approach for the</span></div>
<divclass="line"><aid="l00108"name="l00108"></a><spanclass="lineno"> 108</span><spanclass="comment">// minimum-cost circulation problem as described in [Goldberg and</span></div>
<divclass="line"><aid="l00109"name="l00109"></a><spanclass="lineno"> 109</span><spanclass="comment">// Tarjan] with some technical modifications:</span></div>
<divclass="line"><aid="l00110"name="l00110"></a><spanclass="lineno"> 110</span><spanclass="comment">// 1. For efficiency, we solve a transportation problem instead of</span></div>
<divclass="line"><aid="l00111"name="l00111"></a><spanclass="lineno"> 111</span><spanclass="comment">// minimum-cost circulation. We might revisit this decision if it</span></div>
<divclass="line"><aid="l00112"name="l00112"></a><spanclass="lineno"> 112</span><spanclass="comment">// is important to handle problems in which no perfect matching</span></div>
<divclass="line"><aid="l00114"name="l00114"></a><spanclass="lineno"> 114</span><spanclass="comment">// 2. We use a modified "asymmetric" notion of epsilon-optimality in</span></div>
<divclass="line"><aid="l00115"name="l00115"></a><spanclass="lineno"> 115</span><spanclass="comment">// which left-to-right residual arcs are required to have reduced</span></div>
<divclass="line"><aid="l00116"name="l00116"></a><spanclass="lineno"> 116</span><spanclass="comment">// cost bounded below by zero and right-to-left residual arcs are</span></div>
<divclass="line"><aid="l00117"name="l00117"></a><spanclass="lineno"> 117</span><spanclass="comment">// required to have reduced cost bounded below by -epsilon. For</span></div>
<divclass="line"><aid="l00118"name="l00118"></a><spanclass="lineno"> 118</span><spanclass="comment">// each residual arc direction, the reduced-cost threshold for</span></div>
<divclass="line"><aid="l00119"name="l00119"></a><spanclass="lineno"> 119</span><spanclass="comment">// admissibility is epsilon/2 above the threshold for epsilon</span></div>
<divclass="line"><aid="l00121"name="l00121"></a><spanclass="lineno"> 121</span><spanclass="comment">// 3. We do not limit the applicability of the relabeling operation to</span></div>
<divclass="line"><aid="l00122"name="l00122"></a><spanclass="lineno"> 122</span><spanclass="comment">// nodes with excess. Instead we use the double-push operation</span></div>
<divclass="line"><aid="l00123"name="l00123"></a><spanclass="lineno"> 123</span><spanclass="comment">// (discussed in the Goldberg and Kennedy CSA paper and Kennedy's</span></div>
<divclass="line"><aid="l00124"name="l00124"></a><spanclass="lineno"> 124</span><spanclass="comment">// thesis) which relabels right-side nodes just *after* they have</span></div>
<divclass="line"><aid="l00125"name="l00125"></a><spanclass="lineno"> 125</span><spanclass="comment">// been discharged.</span></div>
<divclass="line"><aid="l00126"name="l00126"></a><spanclass="lineno"> 126</span><spanclass="comment">// The above differences are explained in detail in [Kennedy's thesis]</span></div>
<divclass="line"><aid="l00127"name="l00127"></a><spanclass="lineno"> 127</span><spanclass="comment">// and explained not quite as cleanly in [Goldberg and Kennedy's CSA</span></div>
<divclass="line"><aid="l00128"name="l00128"></a><spanclass="lineno"> 128</span><spanclass="comment">// paper]. But note that the thesis explanation uses a value of</span></div>
<divclass="line"><aid="l00129"name="l00129"></a><spanclass="lineno"> 129</span><spanclass="comment">// epsilon that's double what we use here.</span></div>
<divclass="line"><aid="l00131"name="l00131"></a><spanclass="lineno"> 131</span><spanclass="comment">// Some definitions:</span></div>
<divclass="line"><aid="l00132"name="l00132"></a><spanclass="lineno"> 132</span><spanclass="comment">// Active: A node is called active when it has excess. It is</span></div>
<divclass="line"><aid="l00133"name="l00133"></a><spanclass="lineno"> 133</span><spanclass="comment">// eligible to be pushed from. In this implementation, every active</span></div>
<divclass="line"><aid="l00134"name="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"><aid="l00135"name="l00135"></a><spanclass="lineno"> 135</span><spanclass="comment">// implicitly, so no left-side relabeling is necessary before</span></div>
<divclass="line"><aid="l00136"name="l00136"></a><spanclass="lineno"> 136</span><spanclass="comment">// pushing from an active node. We do, however, need to compute</span></div>
<divclass="line"><aid="l00137"name="l00137"></a><spanclass="lineno"> 137</span><spanclass="comment">// the implications for price changes on the affected right-side</span></div>
<divclass="line"><aid="l00139"name="l00139"></a><spanclass="lineno"> 139</span><spanclass="comment">// Admissible: A residual arc (one that can carry more flow) is</span></div>
<divclass="line"><aid="l00140"name="l00140"></a><spanclass="lineno"> 140</span><spanclass="comment">// called admissible when its reduced cost is small enough. We can</span></div>
<divclass="line"><aid="l00141"name="l00141"></a><spanclass="lineno"> 141</span><spanclass="comment">// push additional flow along such an arc without violating</span></div>
<divclass="line"><aid="l00142"name="l00142"></a><spanclass="lineno"> 142</span><spanclass="comment">// epsilon-optimality. In the case of a left-to-right residual</span></div>
<divclass="line"><aid="l00143"name="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"><aid="l00144"name="l00144"></a><spanclass="lineno"> 144</span><spanclass="comment">// a right-to-left residual arc, the reduced cost must be at</span></div>
<divclass="line"><aid="l00145"name="l00145"></a><spanclass="lineno"> 145</span><spanclass="comment">// most -epsilon/2. The careful reader will note that these thresholds</span></div>
<divclass="line"><aid="l00146"name="l00146"></a><spanclass="lineno"> 146</span><spanclass="comment">// are not used explicitly anywhere in this implementation, and</span></div>
<divclass="line"><aid="l00147"name="l00147"></a><spanclass="lineno"> 147</span><spanclass="comment">// the reason is the implicit pricing of left-side nodes.</span></div>
<divclass="line"><aid="l00148"name="l00148"></a><spanclass="lineno"> 148</span><spanclass="comment">// Reduced cost: Essentially an arc's reduced cost is its</span></div>
<divclass="line"><aid="l00149"name="l00149"></a><spanclass="lineno"> 149</span><spanclass="comment">// complementary slackness. In push-relabel algorithms this is</span></div>
<divclass="line"><aid="l00151"name="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"><aid="l00152"name="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"><aid="l00153"name="l00153"></a><spanclass="lineno"> 153</span><spanclass="comment">// Partial reduced cost: We maintain prices implicitly for left-side</span></div>
<divclass="line"><aid="l00154"name="l00154"></a><spanclass="lineno"> 154</span><spanclass="comment">// nodes in this implementation, so instead of reduced costs we</span></div>
<divclass="line"><aid="l00155"name="l00155"></a><spanclass="lineno"> 155</span><spanclass="comment">// work with partial reduced costs, defined as</span></div>
<divclass="line"><aid="l00158"name="l00158"></a><spanclass="lineno"> 158</span><spanclass="comment">// We check at initialization time for the possibility of arithmetic</span></div>
<divclass="line"><aid="l00159"name="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"><aid="l00160"name="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"><aid="l00161"name="l00161"></a><spanclass="lineno"> 161</span><spanclass="comment">// problem can often be solved even if we warn that overflow is</span></div>
<divclass="line"><aid="l00164"name="l00164"></a><spanclass="lineno"> 164</span><spanclass="comment">// We don't use the interface from</span></div>
<divclass="line"><aid="l00165"name="l00165"></a><spanclass="lineno"> 165</span><spanclass="comment">// operations_research/algorithms/hungarian.h because we want to be</span></div>
<divclass="line"><aid="l00166"name="l00166"></a><spanclass="lineno"> 166</span><spanclass="comment">// able to express sparse problems efficiently.</span></div>
<divclass="line"><aid="l00168"name="l00168"></a><spanclass="lineno"> 168</span><spanclass="comment">// When asked to solve the given assignment problem we return a</span></div>
<divclass="line"><aid="l00169"name="l00169"></a><spanclass="lineno"> 169</span><spanclass="comment">// boolean to indicate whether the given problem was feasible.</span></div>
<divclass="line"><aid="l00172"name="l00172"></a><spanclass="lineno"> 172</span><spanclass="comment">// [ Goldberg and Kennedy's CSA paper ] A. V. Goldberg and R. Kennedy,</span></div>
<divclass="line"><aid="l00173"name="l00173"></a><spanclass="lineno"> 173</span><spanclass="comment">// "An Efficient Cost Scaling Algorithm for the Assignment Problem."</span></div>
<divclass="line"><aid="l00174"name="l00174"></a><spanclass="lineno"> 174</span><spanclass="comment">// Mathematical Programming, Vol. 71, pages 153-178, December 1995.</span></div>
<divclass="line"><aid="l00176"name="l00176"></a><spanclass="lineno"> 176</span><spanclass="comment">// [ Goldberg and Tarjan ] A. V. Goldberg and R. E. Tarjan, "Finding</span></div>
<divclass="line"><aid="l00177"name="l00177"></a><spanclass="lineno"> 177</span><spanclass="comment">// Minimum-Cost Circulations by Successive Approximation." Mathematics</span></div>
<divclass="line"><aid="l00178"name="l00178"></a><spanclass="lineno"> 178</span><spanclass="comment">// of Operations Research, Vol. 15, No. 3, pages 430-466, August 1990.</span></div>
<divclass="line"><aid="l00180"name="l00180"></a><spanclass="lineno"> 180</span><spanclass="comment">// [ Kennedy's thesis ] J. R. Kennedy, Jr., "Solving Unweighted and</span></div>
<divclass="line"><aid="l00181"name="l00181"></a><spanclass="lineno"> 181</span><spanclass="comment">// Weighted Bipartite Matching Problems in Theory and Practice."</span></div>
<divclass="line"><aid="l00182"name="l00182"></a><spanclass="lineno"> 182</span><spanclass="comment">// Stanford University Doctoral Dissertation, Department of Computer</span></div>
<divclass="line"><aid="l00185"name="l00185"></a><spanclass="lineno"> 185</span><spanclass="comment">// [ Burkard et al. ] R. Burkard, M. Dell'Amico, S. Martello, "Assignment</span></div>
<divclass="line"><aid="l00189"name="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"><aid="l00190"name="l00190"></a><spanclass="lineno"> 190</span><spanclass="comment">// Theory, Algorithms, and Applications," Prentice Hall, 1993,</span></div>
<divclass="line"><aid="l00225"name="l00225"></a><spanclass="lineno"> 225</span><spanclass="comment">// This class does not take ownership of its underlying graph.</span></div>
<divclass="line"><aid="l00232"name="l00232"></a><spanclass="lineno"> 232</span><spanclass="comment">// Constructor for the case in which we will build the graph</span></div>
<divclass="line"><aid="l00233"name="l00233"></a><spanclass="lineno"> 233</span><spanclass="comment">// incrementally as we discover arc costs, as might be done with any</span></div>
<divclass="line"><aid="l00234"name="l00234"></a><spanclass="lineno"> 234</span><spanclass="comment">// of the dynamic graph representations such as StarGraph or ForwardStarGraph.</span></div>
<divclass="line"><aid="l00237"name="l00237"></a><spanclass="lineno"> 237</span><spanclass="comment">// Constructor for the case in which the underlying graph cannot be</span></div>
<divclass="line"><aid="l00238"name="l00238"></a><spanclass="lineno"> 238</span><spanclass="comment">// built until after all the arc costs are known, as is the case</span></div>
<divclass="line"><aid="l00239"name="l00239"></a><spanclass="lineno"> 239</span><spanclass="comment">// with ForwardStarStaticGraph. In this case, the graph is passed to</span></div>
<divclass="line"><aid="l00240"name="l00240"></a><spanclass="lineno"> 240</span><spanclass="comment">// us later via the SetGraph() method, below.</span></div>
<divclass="line"><aid="l00245"name="l00245"></a><spanclass="lineno"> 245</span><spanclass="comment">// Sets the graph used by the LinearSumAssignment instance, for use</span></div>
<divclass="line"><aid="l00246"name="l00246"></a><spanclass="lineno"> 246</span><spanclass="comment">// when the graph layout can be determined only after arc costs are</span></div>
<divclass="line"><aid="l00247"name="l00247"></a><spanclass="lineno"> 247</span><spanclass="comment">// set. This happens, for example, when we use a ForwardStarStaticGraph.</span></div>
<divclass="line"><aid="l00253"name="l00253"></a><spanclass="lineno"> 253</span><spanclass="comment">// Sets the cost-scaling divisor, i.e., the amount by which we</span></div>
<divclass="line"><aid="l00254"name="l00254"></a><spanclass="lineno"> 254</span><spanclass="comment">// divide the scaling parameter on each iteration.</span></div>
<divclass="line"><aid="l00257"name="l00257"></a><spanclass="lineno"> 257</span><spanclass="comment">// Returns a permutation cycle handler that can be passed to the</span></div>
<divclass="line"><aid="l00258"name="l00258"></a><spanclass="lineno"> 258</span><spanclass="comment">// TransformToForwardStaticGraph method so that arc costs get</span></div>
<divclass="line"><aid="l00259"name="l00259"></a><spanclass="lineno"> 259</span><spanclass="comment">// permuted along with arcs themselves.</span></div>
<divclass="line"><aid="l00261"name="l00261"></a><spanclass="lineno"> 261</span><spanclass="comment">// Passes ownership of the cycle handler to the caller.</span></div>
<divclass="line"><aid="l00266"name="l00266"></a><spanclass="lineno"> 266</span><spanclass="comment">// Optimizes the layout of the graph for the access pattern our</span></div>
<divclass="line"><aid="l00267"name="l00267"></a><spanclass="lineno"> 267</span><spanclass="comment">// implementation will use.</span></div>
<divclass="line"><aid="l00269"name="l00269"></a><spanclass="lineno"> 269</span><spanclass="comment">// REQUIRES for LinearSumAssignment template instantiation if a call</span></div>
<divclass="line"><aid="l00270"name="l00270"></a><spanclass="lineno"> 270</span><spanclass="comment">// to the OptimizeGraphLayout() method is compiled: GraphType is a</span></div>
<divclass="line"><aid="l00271"name="l00271"></a><spanclass="lineno"> 271</span><spanclass="comment">// dynamic graph, i.e., one that implements the</span></div>
<divclass="line"><aid="l00272"name="l00272"></a><spanclass="lineno"> 272</span><spanclass="comment">// GroupForwardArcsByFunctor() member template method.</span></div>
<divclass="line"><aid="l00274"name="l00274"></a><spanclass="lineno"> 274</span><spanclass="comment">// If analogous optimization is needed for LinearSumAssignment</span></div>
<divclass="line"><aid="l00275"name="l00275"></a><spanclass="lineno"> 275</span><spanclass="comment">// instances based on static graphs, the graph layout should be</span></div>
<divclass="line"><aid="l00276"name="l00276"></a><spanclass="lineno"> 276</span><spanclass="comment">// constructed such that each node's outgoing arcs are sorted by</span></div>
<divclass="line"><aid="l00277"name="l00277"></a><spanclass="lineno"> 277</span><spanclass="comment">// head node index before the</span></div>
<divclass="line"><aid="l00278"name="l00278"></a><spanclass="lineno"> 278</span><spanclass="comment">// LinearSumAssignment<GraphType>::SetGraph() method is called.</span></div>
<divclass="line"><aid="l00284"name="l00284"></a><spanclass="lineno"> 284</span><spanclass="comment">// These handy member functions make the code more compact, and we</span></div>
<divclass="line"><aid="l00285"name="l00285"></a><spanclass="lineno"> 285</span><spanclass="comment">// expose them to clients so that client code that doesn't have</span></div>
<divclass="line"><aid="l00286"name="l00286"></a><spanclass="lineno"> 286</span><spanclass="comment">// direct access to the graph can learn about the optimum assignment</span></div>
<divclass="line"><aid="l00287"name="l00287"></a><spanclass="lineno"> 287</span><spanclass="comment">// once it is computed.</span></div>
<divclass="line"><aid="l00290"name="l00290"></a><spanclass="lineno"> 290</span><spanclass="comment">// Returns the original arc cost for use by a client that's</span></div>
<divclass="line"><aid="l00291"name="l00291"></a><spanclass="lineno"> 291</span><spanclass="comment">// iterating over the optimum assignment.</span></div>
<divclass="line"><aid="l00297"name="l00297"></a><spanclass="lineno"> 297</span><spanclass="comment">// Sets the cost of an arc already present in the given graph.</span></div>
<divclass="line"><aid="l00300"name="l00300"></a><spanclass="lineno"> 300</span><spanclass="comment">// Completes initialization after the problem is fully specified.</span></div>
<divclass="line"><aid="l00301"name="l00301"></a><spanclass="lineno"> 301</span><spanclass="comment">// Returns true if we successfully prove that arithmetic</span></div>
<divclass="line"><aid="l00302"name="l00302"></a><spanclass="lineno"> 302</span><spanclass="comment">// calculations are guaranteed not to overflow. ComputeAssignment()</span></div>
<divclass="line"><aid="l00303"name="l00303"></a><spanclass="lineno"> 303</span><spanclass="comment">// calls this method itself, so only clients that care about</span></div>
<divclass="line"><aid="l00304"name="l00304"></a><spanclass="lineno"> 304</span><spanclass="comment">// obtaining a warning about the possibility of arithmetic precision</span></div>
<divclass="line"><aid="l00305"name="l00305"></a><spanclass="lineno"> 305</span><spanclass="comment">// problems need to call this method explicitly.</span></div>
<divclass="line"><aid="l00307"name="l00307"></a><spanclass="lineno"> 307</span><spanclass="comment">// Separate from ComputeAssignment() for white-box testing and for</span></div>
<divclass="line"><aid="l00308"name="l00308"></a><spanclass="lineno"> 308</span><spanclass="comment">// clients that need to react to the possibility that arithmetic</span></div>
<divclass="line"><aid="l00309"name="l00309"></a><spanclass="lineno"> 309</span><spanclass="comment">// overflow is not ruled out.</span></div>
<divclass="line"><aid="l00314"name="l00314"></a><spanclass="lineno"> 314</span><spanclass="comment">// Computes the optimum assignment. Returns true on success. Return</span></div>
<divclass="line"><aid="l00315"name="l00315"></a><spanclass="lineno"> 315</span><spanclass="comment">// value of false implies the given problem is infeasible.</span></div>
<divclass="line"><aid="l00318"name="l00318"></a><spanclass="lineno"> 318</span><spanclass="comment">// Returns the cost of the minimum-cost perfect matching.</span></div>
<divclass="line"><aid="l00319"name="l00319"></a><spanclass="lineno"> 319</span><spanclass="comment">// Precondition: success_ == true, signifying that we computed the</span></div>
<divclass="line"><aid="l00320"name="l00320"></a><spanclass="lineno"> 320</span><spanclass="comment">// optimum assignment for a feasible problem.</span></div>
<divclass="line"><aid="l00323"name="l00323"></a><spanclass="lineno"> 323</span><spanclass="comment">// Returns the total number of nodes in the given problem.</span></div>
<divclass="line"><aid="l00326"name="l00326"></a><spanclass="lineno"> 326</span><spanclass="comment">// Return a guess that must be true if ultimately we are given a</span></div>
<divclass="line"><aid="l00327"name="l00327"></a><spanclass="lineno"> 327</span><spanclass="comment">// feasible problem to solve.</span></div>
<divclass="line"><aid="l00334"name="l00334"></a><spanclass="lineno"> 334</span><spanclass="comment">// Returns the number of nodes on the left side of the given</span></div>
<divclass="line"><aid="l00338"name="l00338"></a><spanclass="lineno"> 338</span><spanclass="comment">// Returns the arc through which the given node is matched.</span></div>
<divclass="line"><aid="l00344"name="l00344"></a><spanclass="lineno"> 344</span><spanclass="comment">// Returns the cost of the assignment arc incident to the given</span></div>
<divclass="line"><aid="l00350"name="l00350"></a><spanclass="lineno"> 350</span><spanclass="comment">// Returns the node to which the given node is matched.</span></div>
<divclass="line"><aid="l00456"name="l00456"></a><spanclass="lineno"> 456</span><spanclass="comment">// giving the arc along which we will push from a given left-side</span></div>
<divclass="line"><aid="l00457"name="l00457"></a><spanclass="lineno"> 457</span><spanclass="comment">// node and the gap between that arc's partial reduced cost and the</span></div>
<divclass="line"><aid="l00458"name="l00458"></a><spanclass="lineno"> 458</span><spanclass="comment">// reduced cost of the next-best (necessarily residual) arc out of</span></div>
<divclass="line"><aid="l00459"name="l00459"></a><spanclass="lineno"> 459</span><spanclass="comment">// the node. This information helps us efficiently relabel</span></div>
<divclass="line"><aid="l00460"name="l00460"></a><spanclass="lineno"> 460</span><spanclass="comment">// right-side nodes during DoublePush operations.</span></div>
<divclass="line"><aid="l00463"name="l00463"></a><spanclass="lineno"> 463</span><spanclass="comment">// Returns true if and only if the current pseudoflow is</span></div>
<divclass="line"><aid="l00464"name="l00464"></a><spanclass="lineno"> 464</span><spanclass="comment">// epsilon-optimal. To be used in a DCHECK.</span></div>
<divclass="line"><aid="l00471"name="l00471"></a><spanclass="lineno"> 471</span><spanclass="comment">// Calculates the implicit price of the given node.</span></div>
<divclass="line"><aid="l00472"name="l00472"></a><spanclass="lineno"> 472</span><spanclass="comment">// Only for debugging, for use in EpsilonOptimal().</span></div>
<divclass="line"><aid="l00478"name="l00478"></a><spanclass="lineno"> 478</span><spanclass="comment">// Accumulates stats between iterations and reports them if the</span></div>
<divclass="line"><aid="l00479"name="l00479"></a><spanclass="lineno"> 479</span><spanclass="comment">// verbosity level is high enough.</span></div>
<divclass="line"><aid="l00482"name="l00482"></a><spanclass="lineno"> 482</span><spanclass="comment">// Utility function to compute the next error parameter value. This</span></div>
<divclass="line"><aid="l00483"name="l00483"></a><spanclass="lineno"> 483</span><spanclass="comment">// is used to ensure that the same sequence of error parameter</span></div>
<divclass="line"><aid="l00484"name="l00484"></a><spanclass="lineno"> 484</span><spanclass="comment">// values is used for computation of price bounds as is used for</span></div>
<divclass="line"><aid="l00485"name="l00485"></a><spanclass="lineno"> 485</span><spanclass="comment">// computing the optimum assignment.</span></div>
<divclass="line"><aid="l00488"name="l00488"></a><spanclass="lineno"> 488</span><spanclass="comment">// Advances internal state to prepare for the next scaling</span></div>
<divclass="line"><aid="l00489"name="l00489"></a><spanclass="lineno"> 489</span><spanclass="comment">// iteration. Returns false if infeasibility is detected, true</span></div>
<divclass="line"><aid="l00493"name="l00493"></a><spanclass="lineno"> 493</span><spanclass="comment">// Indicates whether the given left_node has positive excess. Called</span></div>
<divclass="line"><aid="l00494"name="l00494"></a><spanclass="lineno"> 494</span><spanclass="comment">// only for nodes on the left side.</span></div>
<divclass="line"><aid="l00497"name="l00497"></a><spanclass="lineno"> 497</span><spanclass="comment">// Indicates whether the given node has nonzero excess. The idea</span></div>
<divclass="line"><aid="l00498"name="l00498"></a><spanclass="lineno"> 498</span><spanclass="comment">// here is the same as the IsActive method above, but that method</span></div>
<divclass="line"><aid="l00499"name="l00499"></a><spanclass="lineno"> 499</span><spanclass="comment">// contains a safety DCHECK() that its argument is a left-side node,</span></div>
<divclass="line"><aid="l00500"name="l00500"></a><spanclass="lineno"> 500</span><spanclass="comment">// while this method is usable for any node.</span></div>
<divclass="line"><aid="l00501"name="l00501"></a><spanclass="lineno"> 501</span><spanclass="comment">// To be used in a DCHECK.</span></div>
<divclass="line"><aid="l00504"name="l00504"></a><spanclass="lineno"> 504</span><spanclass="comment">// Performs the push/relabel work for one scaling iteration.</span></div>
<divclass="line"><aid="l00507"name="l00507"></a><spanclass="lineno"> 507</span><spanclass="comment">// Puts all left-side nodes in the active set in preparation for the</span></div>
<divclass="line"><aid="l00508"name="l00508"></a><spanclass="lineno"> 508</span><spanclass="comment">// first scaling iteration.</span></div>
<divclass="line"><aid="l00511"name="l00511"></a><spanclass="lineno"> 511</span><spanclass="comment">// Saturates all negative-reduced-cost arcs at the beginning of each</span></div>
<divclass="line"><aid="l00512"name="l00512"></a><spanclass="lineno"> 512</span><spanclass="comment">// scaling iteration. Note that according to the asymmetric</span></div>
<divclass="line"><aid="l00513"name="l00513"></a><spanclass="lineno"> 513</span><spanclass="comment">// definition of admissibility, this action is different from</span></div>
<divclass="line"><aid="l00514"name="l00514"></a><spanclass="lineno"> 514</span><spanclass="comment">// saturating all admissible arcs (which we never do). All negative</span></div>
<divclass="line"><aid="l00515"name="l00515"></a><spanclass="lineno"> 515</span><spanclass="comment">// arcs are admissible, but not all admissible arcs are negative. It</span></div>
<divclass="line"><aid="l00516"name="l00516"></a><spanclass="lineno"> 516</span><spanclass="comment">// is alwsys enough to saturate only the negative ones.</span></div>
<divclass="line"><aid="l00519"name="l00519"></a><spanclass="lineno"> 519</span><spanclass="comment">// Performs an optimized sequence of pushing a unit of excess out of</span></div>
<divclass="line"><aid="l00520"name="l00520"></a><spanclass="lineno"> 520</span><spanclass="comment">// the left-side node v and back to another left-side node if no</span></div>
<divclass="line"><aid="l00521"name="l00521"></a><spanclass="lineno"> 521</span><spanclass="comment">// deficit is cancelled with the first push.</span></div>
<divclass="line"><aid="l00524"name="l00524"></a><spanclass="lineno"> 524</span><spanclass="comment">// Returns the partial reduced cost of the given arc.</span></div>
<divclass="line"><aid="l00529"name="l00529"></a><spanclass="lineno"> 529</span><spanclass="comment">// The graph underlying the problem definition we are given. Not</span></div>
<divclass="line"><aid="l00530"name="l00530"></a><spanclass="lineno"> 530</span><spanclass="comment">// owned by *this.</span></div>
<divclass="line"><aid="l00533"name="l00533"></a><spanclass="lineno"> 533</span><spanclass="comment">// The number of nodes on the left side of the graph we are given.</span></div>
<divclass="line"><aid="l00536"name="l00536"></a><spanclass="lineno"> 536</span><spanclass="comment">// A flag indicating, after FinalizeSetup() has run, whether the</span></div>
<divclass="line"><aid="l00537"name="l00537"></a><spanclass="lineno"> 537</span><spanclass="comment">// arc-incidence precondition required by BestArcAndGap() is</span></div>
<divclass="line"><aid="l00538"name="l00538"></a><spanclass="lineno"> 538</span><spanclass="comment">// satisfied by every left-side node. If not, the problem is</span></div>
<divclass="line"><aid="l00542"name="l00542"></a><spanclass="lineno"> 542</span><spanclass="comment">// A flag indicating that an optimal perfect matching has been computed.</span></div>
<divclass="line"><aid="l00545"name="l00545"></a><spanclass="lineno"> 545</span><spanclass="comment">// The value by which we multiply all the arc costs we are given in</span></div>
<divclass="line"><aid="l00546"name="l00546"></a><spanclass="lineno"> 546</span><spanclass="comment">// order to be able to use integer arithmetic in all our</span></div>
<divclass="line"><aid="l00547"name="l00547"></a><spanclass="lineno"> 547</span><spanclass="comment">// computations. In order to establish optimality of the final</span></div>
<divclass="line"><aid="l00548"name="l00548"></a><spanclass="lineno"> 548</span><spanclass="comment">// matching we compute, we need that</span></div>
<divclass="line"><aid="l00555"name="l00555"></a><spanclass="lineno"> 555</span><spanclass="comment">// Minimum value of epsilon. When a flow is epsilon-optimal for</span></div>
<divclass="line"><aid="l00556"name="l00556"></a><spanclass="lineno"> 556</span><spanclass="comment">// epsilon == kMinEpsilon, the flow is optimal.</span></div>
<divclass="line"><aid="l00559"name="l00559"></a><spanclass="lineno"> 559</span><spanclass="comment">// Current value of epsilon, the cost scaling parameter.</span></div>
<divclass="line"><aid="l00562"name="l00562"></a><spanclass="lineno"> 562</span><spanclass="comment">// The following two data members, price_lower_bound_ and</span></div>
<divclass="line"><aid="l00563"name="l00563"></a><spanclass="lineno"> 563</span><spanclass="comment">// slack_relabeling_price_, have to do with bounds on the amount by</span></div>
<divclass="line"><aid="l00564"name="l00564"></a><spanclass="lineno"> 564</span><spanclass="comment">// which node prices can change during execution of the algorithm.</span></div>
<divclass="line"><aid="l00565"name="l00565"></a><spanclass="lineno"> 565</span><spanclass="comment">// We need some detailed discussion of this topic because we violate</span></div>
<divclass="line"><aid="l00566"name="l00566"></a><spanclass="lineno"> 566</span><spanclass="comment">// several simplifying assumptions typically made in the theoretical</span></div>
<divclass="line"><aid="l00567"name="l00567"></a><spanclass="lineno"> 567</span><spanclass="comment">// literature. In particular, we use integer arithmetic, we use a</span></div>
<divclass="line"><aid="l00568"name="l00568"></a><spanclass="lineno"> 568</span><spanclass="comment">// reduction to the transportation problem rather than min-cost</span></div>
<divclass="line"><aid="l00569"name="l00569"></a><spanclass="lineno"> 569</span><spanclass="comment">// circulation, we provide detection of infeasible problems rather</span></div>
<divclass="line"><aid="l00570"name="l00570"></a><spanclass="lineno"> 570</span><spanclass="comment">// than assume feasibility, we detect when our computations might</span></div>
<divclass="line"><aid="l00571"name="l00571"></a><spanclass="lineno"> 571</span><spanclass="comment">// exceed the range of representable cost values, and we use the</span></div>
<divclass="line"><aid="l00572"name="l00572"></a><spanclass="lineno"> 572</span><spanclass="comment">// double-push heuristic which relabels nodes that do not have</span></div>
<divclass="line"><aid="l00575"name="l00575"></a><spanclass="lineno"> 575</span><spanclass="comment">// In the following discussion, we prove the following propositions:</span></div>
<divclass="line"><aid="l00576"name="l00576"></a><spanclass="lineno"> 576</span><spanclass="comment">// Proposition 1. [Fidelity of arithmetic precision guarantee] If</span></div>
<divclass="line"><aid="l00577"name="l00577"></a><spanclass="lineno"> 577</span><spanclass="comment">// FinalizeSetup() returns true, no arithmetic</span></div>
<divclass="line"><aid="l00578"name="l00578"></a><spanclass="lineno"> 578</span><spanclass="comment">// overflow occurs during ComputeAssignment().</span></div>
<divclass="line"><aid="l00579"name="l00579"></a><spanclass="lineno"> 579</span><spanclass="comment">// Proposition 2. [Fidelity of feasibility detection] If no</span></div>
<divclass="line"><aid="l00581"name="l00581"></a><spanclass="lineno"> 581</span><spanclass="comment">// ComputeAssignment(), the return value of</span></div>
<divclass="line"><aid="l00585"name="l00585"></a><spanclass="lineno"> 585</span><spanclass="comment">// We begin with some general discussion.</span></div>
<divclass="line"><aid="l00587"name="l00587"></a><spanclass="lineno"> 587</span><spanclass="comment">// The ideas used to prove our two propositions are essentially</span></div>
<divclass="line"><aid="l00588"name="l00588"></a><spanclass="lineno"> 588</span><spanclass="comment">// those that appear in [Goldberg and Tarjan], but several details</span></div>
<divclass="line"><aid="l00589"name="l00589"></a><spanclass="lineno"> 589</span><spanclass="comment">// are different: [Goldberg and Tarjan] assumes a feasible problem,</span></div>
<divclass="line"><aid="l00590"name="l00590"></a><spanclass="lineno"> 590</span><spanclass="comment">// uses a symmetric notion of epsilon-optimality, considers only</span></div>
<divclass="line"><aid="l00591"name="l00591"></a><spanclass="lineno"> 591</span><spanclass="comment">// nodes with excess eligible for relabeling, and does not treat the</span></div>
<divclass="line"><aid="l00592"name="l00592"></a><spanclass="lineno"> 592</span><spanclass="comment">// question of arithmetic overflow. This implementation, on the</span></div>
<divclass="line"><aid="l00593"name="l00593"></a><spanclass="lineno"> 593</span><spanclass="comment">// other hand, detects and reports infeasible problems, uses</span></div>
<divclass="line"><aid="l00594"name="l00594"></a><spanclass="lineno"> 594</span><spanclass="comment">// asymmetric epsilon-optimality, relabels nodes with no excess in</span></div>
<divclass="line"><aid="l00595"name="l00595"></a><spanclass="lineno"> 595</span><spanclass="comment">// the course of the double-push operation, and gives a reasonably</span></div>
<divclass="line"><aid="l00596"name="l00596"></a><spanclass="lineno"> 596</span><spanclass="comment">// tight guarantee of arithmetic precision. No fundamentally new</span></div>
<divclass="line"><aid="l00597"name="l00597"></a><spanclass="lineno"> 597</span><spanclass="comment">// ideas are involved, but the details are a bit tricky so they are</span></div>
<divclass="line"><aid="l00600"name="l00600"></a><spanclass="lineno"> 600</span><spanclass="comment">// We have two intertwined needs that lead us to compute bounds on</span></div>
<divclass="line"><aid="l00601"name="l00601"></a><spanclass="lineno"> 601</span><spanclass="comment">// the prices nodes can have during the assignment computation, on</span></div>
<divclass="line"><aid="l00602"name="l00602"></a><spanclass="lineno"> 602</span><spanclass="comment">// the assumption that the given problem is feasible:</span></div>
<divclass="line"><aid="l00603"name="l00603"></a><spanclass="lineno"> 603</span><spanclass="comment">// 1. Infeasibility detection: Infeasibility is detected by</span></div>
<divclass="line"><aid="l00604"name="l00604"></a><spanclass="lineno"> 604</span><spanclass="comment">// observing that some node's price has been reduced too much by</span></div>
<divclass="line"><aid="l00605"name="l00605"></a><spanclass="lineno"> 605</span><spanclass="comment">// relabeling operations (see [Goldberg and Tarjan] for the</span></div>
<divclass="line"><aid="l00606"name="l00606"></a><spanclass="lineno"> 606</span><spanclass="comment">// argument -- duplicated in modified form below -- bounding the</span></div>
<divclass="line"><aid="l00607"name="l00607"></a><spanclass="lineno"> 607</span><spanclass="comment">// running time of the push/relabel min-cost flow algorithm for</span></div>
<divclass="line"><aid="l00610"name="l00610"></a><spanclass="lineno"> 610</span><spanclass="comment">// forced: When a left-side node is incident to only one arc a,</span></div>
<divclass="line"><aid="l00611"name="l00611"></a><spanclass="lineno"> 611</span><spanclass="comment">// any feasible solution must include a, and reducing the price</span></div>
<divclass="line"><aid="l00612"name="l00612"></a><spanclass="lineno"> 612</span><spanclass="comment">// of Head(a) by any nonnegative amount preserves epsilon-</span></div>
<divclass="line"><aid="l00613"name="l00613"></a><spanclass="lineno"> 613</span><spanclass="comment">// optimality. Because of this freedom, we'll call this sort of</span></div>
<divclass="line"><aid="l00614"name="l00614"></a><spanclass="lineno"> 614</span><spanclass="comment">// relabeling (i.e., a relabeling of a right-side node that is</span></div>
<divclass="line"><aid="l00615"name="l00615"></a><spanclass="lineno"> 615</span><spanclass="comment">// the only neighbor of the left-side node to which it has been</span></div>
<divclass="line"><aid="l00616"name="l00616"></a><spanclass="lineno"> 616</span><spanclass="comment">// matched in the present double-push operation) a "slack"</span></div>
<divclass="line"><aid="l00617"name="l00617"></a><spanclass="lineno"> 617</span><spanclass="comment">// relabeling. Relabelings that are not slack relabelings are</span></div>
<divclass="line"><aid="l00618"name="l00618"></a><spanclass="lineno"> 618</span><spanclass="comment">// called "confined" relabelings. By relabeling Head(a) to have</span></div>
<divclass="line"><aid="l00619"name="l00619"></a><spanclass="lineno"> 619</span><spanclass="comment">// p(Head(a))=-infinity, we could guarantee that a never becomes</span></div>
<divclass="line"><aid="l00620"name="l00620"></a><spanclass="lineno"> 620</span><spanclass="comment">// unmatched during the current iteration, and this would prevent</span></div>
<divclass="line"><aid="l00621"name="l00621"></a><spanclass="lineno"> 621</span><spanclass="comment">// our wasting time repeatedly unmatching and rematching a. But</span></div>
<divclass="line"><aid="l00622"name="l00622"></a><spanclass="lineno"> 622</span><spanclass="comment">// there are some details we need to handle:</span></div>
<divclass="line"><aid="l00623"name="l00623"></a><spanclass="lineno"> 623</span><spanclass="comment">// a. The CostValue type cannot represent -infinity;</span></div>
<divclass="line"><aid="l00624"name="l00624"></a><spanclass="lineno"> 624</span><spanclass="comment">// b. Low node prices are precisely the signal we use to detect</span></div>
<divclass="line"><aid="l00625"name="l00625"></a><spanclass="lineno"> 625</span><spanclass="comment">// infeasibility (see (1)), so we must be careful not to</span></div>
<divclass="line"><aid="l00626"name="l00626"></a><spanclass="lineno"> 626</span><spanclass="comment">// falsely conclude that the problem is infeasible as a result</span></div>
<divclass="line"><aid="l00627"name="l00627"></a><spanclass="lineno"> 627</span><spanclass="comment">// of the low price we gave Head(a); and</span></div>
<divclass="line"><aid="l00628"name="l00628"></a><spanclass="lineno"> 628</span><spanclass="comment">// c. We need to indicate accurately to the client when our best</span></div>
<divclass="line"><aid="l00629"name="l00629"></a><spanclass="lineno"> 629</span><spanclass="comment">// understanding indicates that we can't rule out arithmetic</span></div>
<divclass="line"><aid="l00630"name="l00630"></a><spanclass="lineno"> 630</span><spanclass="comment">// overflow in our calculations. Most importantly, if we don't</span></div>
<divclass="line"><aid="l00631"name="l00631"></a><spanclass="lineno"> 631</span><spanclass="comment">// warn the client, we must be certain to avoid overflow. This</span></div>
<divclass="line"><aid="l00632"name="l00632"></a><spanclass="lineno"> 632</span><spanclass="comment">// means our slack relabelings must not be so aggressive as to</span></div>
<divclass="line"><aid="l00633"name="l00633"></a><spanclass="lineno"> 633</span><spanclass="comment">// create the possibility of unforeseen overflow. Although we</span></div>
<divclass="line"><aid="l00634"name="l00634"></a><spanclass="lineno"> 634</span><spanclass="comment">// will not achieve this in practice, slack relabelings would</span></div>
<divclass="line"><aid="l00635"name="l00635"></a><spanclass="lineno"> 635</span><spanclass="comment">// ideally not introduce overflow unless overflow was</span></div>
<divclass="line"><aid="l00636"name="l00636"></a><spanclass="lineno"> 636</span><spanclass="comment">// inevitable were even the smallest reasonable price change</span></div>
<divclass="line"><aid="l00637"name="l00637"></a><spanclass="lineno"> 637</span><spanclass="comment">// (== epsilon) used for slack relabelings.</span></div>
<divclass="line"><aid="l00638"name="l00638"></a><spanclass="lineno"> 638</span><spanclass="comment">// Using the analysis below, we choose a finite amount of price</span></div>
<divclass="line"><aid="l00639"name="l00639"></a><spanclass="lineno"> 639</span><spanclass="comment">// change for slack relabelings aggressive enough that we don't</span></div>
<divclass="line"><aid="l00640"name="l00640"></a><spanclass="lineno"> 640</span><spanclass="comment">// waste time doing repeated slack relabelings in a single</span></div>
<divclass="line"><aid="l00641"name="l00641"></a><spanclass="lineno"> 641</span><spanclass="comment">// iteration, yet modest enough that we keep a good handle on</span></div>
<divclass="line"><aid="l00642"name="l00642"></a><spanclass="lineno"> 642</span><spanclass="comment">// arithmetic precision and our ability to detect infeasible</span></div>
<divclass="line"><aid="l00645"name="l00645"></a><spanclass="lineno"> 645</span><spanclass="comment">// To provide faithful detection of infeasibility, a dependable</span></div>
<divclass="line"><aid="l00646"name="l00646"></a><spanclass="lineno"> 646</span><spanclass="comment">// guarantee of arithmetic precision whenever possible, and good</span></div>
<divclass="line"><aid="l00647"name="l00647"></a><spanclass="lineno"> 647</span><spanclass="comment">// performance by aggressively relabeling nodes whose matching is</span></div>
<divclass="line"><aid="l00648"name="l00648"></a><spanclass="lineno"> 648</span><spanclass="comment">// forced, we exploit these facts:</span></div>
<divclass="line"><aid="l00649"name="l00649"></a><spanclass="lineno"> 649</span><spanclass="comment">// 1. Beyond the first iteration, infeasibility detection isn't needed</span></div>
<divclass="line"><aid="l00650"name="l00650"></a><spanclass="lineno"> 650</span><spanclass="comment">// because a problem is feasible in some iteration if and only if</span></div>
<divclass="line"><aid="l00651"name="l00651"></a><spanclass="lineno"> 651</span><spanclass="comment">// it's feasible in all others. Therefore we are free to use an</span></div>
<divclass="line"><aid="l00652"name="l00652"></a><spanclass="lineno"> 652</span><spanclass="comment">// infeasibility detection mechanism that might work in just one</span></div>
<divclass="line"><aid="l00653"name="l00653"></a><spanclass="lineno"> 653</span><spanclass="comment">// iteration and switch it off in all other iterations.</span></div>
<divclass="line"><aid="l00654"name="l00654"></a><spanclass="lineno"> 654</span><spanclass="comment">// 2. When we do a slack relabeling, we must choose the amount of</span></div>
<divclass="line"><aid="l00655"name="l00655"></a><spanclass="lineno"> 655</span><spanclass="comment">// price reduction to use. We choose an amount large enough to</span></div>
<divclass="line"><aid="l00656"name="l00656"></a><spanclass="lineno"> 656</span><spanclass="comment">// guarantee putting the node's matching to rest, yet (although</span></div>
<divclass="line"><aid="l00657"name="l00657"></a><spanclass="lineno"> 657</span><spanclass="comment">// we don't bother to prove this explicitly) small enough that</span></div>
<divclass="line"><aid="l00658"name="l00658"></a><spanclass="lineno"> 658</span><spanclass="comment">// the node's price obeys the overall lower bound that holds if</span></div>
<divclass="line"><aid="l00659"name="l00659"></a><spanclass="lineno"> 659</span><spanclass="comment">// the slack relabeling amount is small.</span></div>
<divclass="line"><aid="l00661"name="l00661"></a><spanclass="lineno"> 661</span><spanclass="comment">// We will establish Propositions (1) and (2) above according to the</span></div>
<divclass="line"><aid="l00662"name="l00662"></a><spanclass="lineno"> 662</span><spanclass="comment">// following steps:</span></div>
<divclass="line"><aid="l00663"name="l00663"></a><spanclass="lineno"> 663</span><spanclass="comment">// First, we prove Lemma 1, which is a modified form of lemma 5.8 of</span></div>
<divclass="line"><aid="l00664"name="l00664"></a><spanclass="lineno"> 664</span><spanclass="comment">// [Goldberg and Tarjan] giving a bound on the difference in price</span></div>
<divclass="line"><aid="l00665"name="l00665"></a><spanclass="lineno"> 665</span><spanclass="comment">// between the end nodes of certain paths in the residual graph.</span></div>
<divclass="line"><aid="l00666"name="l00666"></a><spanclass="lineno"> 666</span><spanclass="comment">// Second, we prove Lemma 2, which is technical lemma to establish</span></div>
<divclass="line"><aid="l00667"name="l00667"></a><spanclass="lineno"> 667</span><spanclass="comment">// reachability of certain "anchor" nodes in the residual graph from</span></div>
<divclass="line"><aid="l00668"name="l00668"></a><spanclass="lineno"> 668</span><spanclass="comment">// any node where a relabeling takes place.</span></div>
<divclass="line"><aid="l00669"name="l00669"></a><spanclass="lineno"> 669</span><spanclass="comment">// Third, we apply the first two lemmas to prove Lemma 3 and Lemma</span></div>
<divclass="line"><aid="l00670"name="l00670"></a><spanclass="lineno"> 670</span><spanclass="comment">// 4, which give two similar bounds that hold whenever the given</span></div>
<divclass="line"><aid="l00671"name="l00671"></a><spanclass="lineno"> 671</span><spanclass="comment">// problem is feasible: (for feasibility detection) a bound on the</span></div>
<divclass="line"><aid="l00672"name="l00672"></a><spanclass="lineno"> 672</span><spanclass="comment">// price of any node we relabel during any iteration (and the first</span></div>
<divclass="line"><aid="l00673"name="l00673"></a><spanclass="lineno"> 673</span><spanclass="comment">// iteration in particular), and (for arithmetic precision) a bound</span></div>
<divclass="line"><aid="l00674"name="l00674"></a><spanclass="lineno"> 674</span><spanclass="comment">// on the price of any node we relabel during the entire algorithm.</span></div>
<divclass="line"><aid="l00676"name="l00676"></a><spanclass="lineno"> 676</span><spanclass="comment">// Finally, we note that if the whole-algorithm price bound can be</span></div>
<divclass="line"><aid="l00677"name="l00677"></a><spanclass="lineno"> 677</span><spanclass="comment">// represented precisely by the CostValue type, arithmetic overflow</span></div>
<divclass="line"><aid="l00678"name="l00678"></a><spanclass="lineno"> 678</span><spanclass="comment">// cannot occur (establishing Proposition 1), and assuming no</span></div>
<divclass="line"><aid="l00679"name="l00679"></a><spanclass="lineno"> 679</span><spanclass="comment">// overflow occurs during the first iteration, any violation of the</span></div>
<divclass="line"><aid="l00683"name="l00683"></a><spanclass="lineno"> 683</span><spanclass="comment">// The statement of Lemma 1 is perhaps easier to understand when the</span></div>
<divclass="line"><aid="l00684"name="l00684"></a><spanclass="lineno"> 684</span><spanclass="comment">// reader knows how it will be used. To wit: In this lemma, f' and</span></div>
<divclass="line"><aid="l00685"name="l00685"></a><spanclass="lineno"> 685</span><spanclass="comment">// e_0 are the flow and error parameter (epsilon) at the beginning</span></div>
<divclass="line"><aid="l00686"name="l00686"></a><spanclass="lineno"> 686</span><spanclass="comment">// of the current iteration, while f and e_1 are the current</span></div>
<divclass="line"><aid="l00687"name="l00687"></a><spanclass="lineno"> 687</span><spanclass="comment">// pseudoflow and error parameter when a relabeling of interest</span></div>
<divclass="line"><aid="l00688"name="l00688"></a><spanclass="lineno"> 688</span><spanclass="comment">// occurs. Without loss of generality, c is the reduced cost</span></div>
<divclass="line"><aid="l00689"name="l00689"></a><spanclass="lineno"> 689</span><spanclass="comment">// function at the beginning of the current iteration and p is the</span></div>
<divclass="line"><aid="l00690"name="l00690"></a><spanclass="lineno"> 690</span><spanclass="comment">// change in prices that has taken place in the current iteration.</span></div>
<divclass="line"><aid="l00692"name="l00692"></a><spanclass="lineno"> 692</span><spanclass="comment">// Lemma 1 (a variant of lemma 5.8 from [Goldberg and Tarjan]): Let</span></div>
<divclass="line"><aid="l00693"name="l00693"></a><spanclass="lineno"> 693</span><spanclass="comment">// f be a pseudoflow and let f' be a flow. Suppose P is a simple</span></div>
<divclass="line"><aid="l00694"name="l00694"></a><spanclass="lineno"> 694</span><spanclass="comment">// path from right-side node v to right-side node w such that P is</span></div>
<divclass="line"><aid="l00695"name="l00695"></a><spanclass="lineno"> 695</span><spanclass="comment">// residual with respect to f and reverse(P) is residual with</span></div>
<divclass="line"><aid="l00696"name="l00696"></a><spanclass="lineno"> 696</span><spanclass="comment">// respect to f'. Further, suppose c is an arc cost function with</span></div>
<divclass="line"><aid="l00697"name="l00697"></a><spanclass="lineno"> 697</span><spanclass="comment">// respect to which f' is e_0-optimal with the zero price function</span></div>
<divclass="line"><aid="l00698"name="l00698"></a><spanclass="lineno"> 698</span><spanclass="comment">// and p is a price function with respect to which f is e_1-optimal</span></div>
<divclass="line"><aid="l00699"name="l00699"></a><spanclass="lineno"> 699</span><spanclass="comment">// with respect to p. Then</span></div>
<divclass="line"><aid="l00702"name="l00702"></a><spanclass="lineno"> 702</span><spanclass="comment">// Proof: We have c_p(P) = p(v) + c(P) - p(w) and hence</span></div>
<divclass="line"><aid="l00704"name="l00704"></a><spanclass="lineno"> 704</span><spanclass="comment">// So we seek a bound on c_p(P) - c(P).</span></div>
<divclass="line"><aid="l00706"name="l00706"></a><spanclass="lineno"> 706</span><spanclass="comment">// Let arc a lie on P, which implies that a is residual with respect</span></div>
<divclass="line"><aid="l00707"name="l00707"></a><spanclass="lineno"> 707</span><spanclass="comment">// to f and reverse(a) is residual with respect to f'.</span></div>
<divclass="line"><aid="l00708"name="l00708"></a><spanclass="lineno"> 708</span><spanclass="comment">// Case 1: a is a forward arc. Then by e_1-optimality of f with</span></div>
<divclass="line"><aid="l00709"name="l00709"></a><spanclass="lineno"> 709</span><spanclass="comment">// respect to p, c_p(a) >= 0 and reverse(a) is residual with</span></div>
<divclass="line"><aid="l00710"name="l00710"></a><spanclass="lineno"> 710</span><spanclass="comment">// respect to f'. By e_0-optimality of f', c(a) <= e_0. So</span></div>
<divclass="line"><aid="l00712"name="l00712"></a><spanclass="lineno"> 712</span><spanclass="comment">// Case 2: a is a reverse arc. Then by e_1-optimality of f with</span></div>
<divclass="line"><aid="l00713"name="l00713"></a><spanclass="lineno"> 713</span><spanclass="comment">// respect to p, c_p(a) >= -e_1 and reverse(a) is residual</span></div>
<divclass="line"><aid="l00714"name="l00714"></a><spanclass="lineno"> 714</span><spanclass="comment">// with respect to f'. By e_0-optimality of f', c(a) <= 0.</span></div>
<divclass="line"><aid="l00717"name="l00717"></a><spanclass="lineno"> 717</span><spanclass="comment">// We assumed v and w are both right-side nodes, so there are at</span></div>
<divclass="line"><aid="l00718"name="l00718"></a><spanclass="lineno"> 718</span><spanclass="comment">// most n - 2 arcs on the path P, of which at most (n-2)/2 are</span></div>
<divclass="line"><aid="l00719"name="l00719"></a><spanclass="lineno"> 719</span><spanclass="comment">// forward arcs and at most (n-2)/2 are reverse arcs, so</span></div>
<divclass="line"><aid="l00723"name="l00723"></a><spanclass="lineno"> 723</span><spanclass="comment">// Some of the rest of our argument is given as a sketch, omitting</span></div>
<divclass="line"><aid="l00724"name="l00724"></a><spanclass="lineno"> 724</span><spanclass="comment">// several details. Also elided here are some minor technical issues</span></div>
<divclass="line"><aid="l00725"name="l00725"></a><spanclass="lineno"> 725</span><spanclass="comment">// related to the first iteration, inasmuch as our arguments assume</span></div>
<divclass="line"><aid="l00726"name="l00726"></a><spanclass="lineno"> 726</span><spanclass="comment">// on the surface a "previous iteration" that doesn't exist in that</span></div>
<divclass="line"><aid="l00727"name="l00727"></a><spanclass="lineno"> 727</span><spanclass="comment">// case. The issues are not substantial, just a bit messy.</span></div>
<divclass="line"><aid="l00729"name="l00729"></a><spanclass="lineno"> 729</span><spanclass="comment">// Lemma 2 is analogous to lemma 5.7 of [Goldberg and Tarjan], where</span></div>
<divclass="line"><aid="l00730"name="l00730"></a><spanclass="lineno"> 730</span><spanclass="comment">// they have only relabelings that take place at nodes with excess</span></div>
<divclass="line"><aid="l00731"name="l00731"></a><spanclass="lineno"> 731</span><spanclass="comment">// while we have only relabelings that take place as part of the</span></div>
<divclass="line"><aid="l00732"name="l00732"></a><spanclass="lineno"> 732</span><spanclass="comment">// double-push operation at nodes without excess.</span></div>
<divclass="line"><aid="l00734"name="l00734"></a><spanclass="lineno"> 734</span><spanclass="comment">// Lemma 2: If the problem is feasible, for any node v with excess,</span></div>
<divclass="line"><aid="l00735"name="l00735"></a><spanclass="lineno"> 735</span><spanclass="comment">// there exists a path P from v to a node w with deficit such that P</span></div>
<divclass="line"><aid="l00736"name="l00736"></a><spanclass="lineno"> 736</span><spanclass="comment">// is residual with respect to the current pseudoflow, and</span></div>
<divclass="line"><aid="l00737"name="l00737"></a><spanclass="lineno"> 737</span><spanclass="comment">// reverse(P) is residual with respect to the flow at the beginning</span></div>
<divclass="line"><aid="l00738"name="l00738"></a><spanclass="lineno"> 738</span><spanclass="comment">// of the current iteration. (Note that such a path exactly</span></div>
<divclass="line"><aid="l00739"name="l00739"></a><spanclass="lineno"> 739</span><spanclass="comment">// satisfies the conditions of Lemma 1.)</span></div>
<divclass="line"><aid="l00741"name="l00741"></a><spanclass="lineno"> 741</span><spanclass="comment">// Let the bound from Lemma 1 with p(w) = 0 be called B(e_0, e_1),</span></div>
<divclass="line"><aid="l00742"name="l00742"></a><spanclass="lineno"> 742</span><spanclass="comment">// and let us say that when a slack relabeling of a node v occurs,</span></div>
<divclass="line"><aid="l00743"name="l00743"></a><spanclass="lineno"> 743</span><spanclass="comment">// we will change the price of v by B(e_0, e_1) such that v tightly</span></div>
<divclass="line"><aid="l00744"name="l00744"></a><spanclass="lineno"> 744</span><spanclass="comment">// satisfies the bound of Lemma 1. Explicitly, we define</span></div>
<divclass="line"><aid="l00747"name="l00747"></a><spanclass="lineno"> 747</span><spanclass="comment">// Lemma 1 and Lemma 2 combine to bound the price change during an</span></div>
<divclass="line"><aid="l00748"name="l00748"></a><spanclass="lineno"> 748</span><spanclass="comment">// iteration for any node with excess. Viewed a different way, Lemma</span></div>
<divclass="line"><aid="l00749"name="l00749"></a><spanclass="lineno"> 749</span><spanclass="comment">// 1 and Lemma 2 tell us that if epsilon-optimality can be preserved</span></div>
<divclass="line"><aid="l00750"name="l00750"></a><spanclass="lineno"> 750</span><spanclass="comment">// by changing the price of a node by B(e_0, e_1), that node will</span></div>
<divclass="line"><aid="l00751"name="l00751"></a><spanclass="lineno"> 751</span><spanclass="comment">// never have excess again during the current iteration unless the</span></div>
<divclass="line"><aid="l00752"name="l00752"></a><spanclass="lineno"> 752</span><spanclass="comment">// problem is infeasible. This insight gives us an approach to</span></div>
<divclass="line"><aid="l00753"name="l00753"></a><spanclass="lineno"> 753</span><spanclass="comment">// detect infeasibility (by observing prices on nodes with excess</span></div>
<divclass="line"><aid="l00754"name="l00754"></a><spanclass="lineno"> 754</span><spanclass="comment">// that violate this bound) and to relabel nodes aggressively enough</span></div>
<divclass="line"><aid="l00755"name="l00755"></a><spanclass="lineno"> 755</span><spanclass="comment">// to avoid unnecessary future work while we also avoid falsely</span></div>
<divclass="line"><aid="l00756"name="l00756"></a><spanclass="lineno"> 756</span><spanclass="comment">// concluding the problem is infeasible.</span></div>
<divclass="line"><aid="l00758"name="l00758"></a><spanclass="lineno"> 758</span><spanclass="comment">// From Lemma 1 and Lemma 2, and taking into account our knowledge</span></div>
<divclass="line"><aid="l00759"name="l00759"></a><spanclass="lineno"> 759</span><spanclass="comment">// of the slack relabeling amount, we have Lemma 3.</span></div>
<divclass="line"><aid="l00761"name="l00761"></a><spanclass="lineno"> 761</span><spanclass="comment">// Lemma 3: During any iteration, if the given problem is feasible</span></div>
<divclass="line"><aid="l00762"name="l00762"></a><spanclass="lineno"> 762</span><spanclass="comment">// the price of any node is reduced by less than</span></div>
<divclass="line"><aid="l00767"name="l00767"></a><spanclass="lineno"> 767</span><spanclass="comment">// In the case where e_0 = e_1 * alpha, we can express the bound</span></div>
<divclass="line"><aid="l00768"name="l00768"></a><spanclass="lineno"> 768</span><spanclass="comment">// just in terms of e_1, the current iteration's value of epsilon_:</span></div>
<divclass="line"><aid="l00770"name="l00770"></a><spanclass="lineno"> 770</span><spanclass="comment">// so we have that p(v) is reduced by less than 2 * B(e_1).</span></div>
<divclass="line"><aid="l00772"name="l00772"></a><spanclass="lineno"> 772</span><spanclass="comment">// Because we use truncating division to compute each iteration's error</span></div>
<divclass="line"><aid="l00773"name="l00773"></a><spanclass="lineno"> 773</span><spanclass="comment">// parameter from that of the previous iteration, it isn't exactly</span></div>
<divclass="line"><aid="l00774"name="l00774"></a><spanclass="lineno"> 774</span><spanclass="comment">// the case that e_0 = e_1 * alpha as we just assumed. To patch this</span></div>
<divclass="line"><aid="l00775"name="l00775"></a><spanclass="lineno"> 775</span><spanclass="comment">// up, we can use the observation that</span></div>
<divclass="line"><aid="l00786"name="l00786"></a><spanclass="lineno"> 786</span><spanclass="comment">// We sum up the bounds for all the iterations to get Lemma 4:</span></div>
<divclass="line"><aid="l00788"name="l00788"></a><spanclass="lineno"> 788</span><spanclass="comment">// Lemma 4: If the given problem is feasible, after k iterations the</span></div>
<divclass="line"><aid="l00789"name="l00789"></a><spanclass="lineno"> 789</span><spanclass="comment">// price of any node is always greater than</span></div>
<divclass="line"><aid="l00792"name="l00792"></a><spanclass="lineno"> 792</span><spanclass="comment">// Proof: Suppose the price decrease of every node in the iteration</span></div>
<divclass="line"><aid="l00793"name="l00793"></a><spanclass="lineno"> 793</span><spanclass="comment">// with epsilon_ == x is bounded by B(x) which is proportional to x</span></div>
<divclass="line"><aid="l00794"name="l00794"></a><spanclass="lineno"> 794</span><spanclass="comment">// (not surprisingly, this will be the same function B() as</span></div>
<divclass="line"><aid="l00795"name="l00795"></a><spanclass="lineno"> 795</span><spanclass="comment">// above). Assume for simplicity that C, the largest cost magnitude,</span></div>
<divclass="line"><aid="l00796"name="l00796"></a><spanclass="lineno"> 796</span><spanclass="comment">// is a power of alpha. Then the price of each node, tallied across</span></div>
<divclass="line"><aid="l00797"name="l00797"></a><spanclass="lineno"> 797</span><spanclass="comment">// all iterations is bounded</span></div>
<divclass="line"><aid="l00801"name="l00801"></a><spanclass="lineno"> 801</span><spanclass="comment">// As above, this needs some patching up to handle the fact that we</span></div>
<divclass="line"><aid="l00802"name="l00802"></a><spanclass="lineno"> 802</span><spanclass="comment">// use truncating arithmetic. We saw that each iteration effectively</span></div>
<divclass="line"><aid="l00803"name="l00803"></a><spanclass="lineno"> 803</span><spanclass="comment">// reduces the price bound by alpha * (n-2), hence if there are k</span></div>
<divclass="line"><aid="l00804"name="l00804"></a><spanclass="lineno"> 804</span><spanclass="comment">// iterations, the bound is</span></div>
<divclass="line"><aid="l00809"name="l00809"></a><spanclass="lineno"> 809</span><spanclass="comment">// The bound of lemma 4 can be used to warn for possible overflow of</span></div>
<divclass="line"><aid="l00810"name="l00810"></a><spanclass="lineno"> 810</span><spanclass="comment">// arithmetic precision. But because it involves the number of</span></div>
<divclass="line"><aid="l00811"name="l00811"></a><spanclass="lineno"> 811</span><spanclass="comment">// iterations, k, we might as well count through the iterations</span></div>
<divclass="line"><aid="l00812"name="l00812"></a><spanclass="lineno"> 812</span><spanclass="comment">// simply adding up the bounds given by Lemma 3 to get a tighter</span></div>
<divclass="line"><aid="l00813"name="l00813"></a><spanclass="lineno"> 813</span><spanclass="comment">// result. This is what the implementation does.</span></div>
<divclass="line"><aid="l00815"name="l00815"></a><spanclass="lineno"> 815</span><spanclass="comment">// A lower bound on the price of any node at any time throughout the</span></div>
<divclass="line"><aid="l00816"name="l00816"></a><spanclass="lineno"> 816</span><spanclass="comment">// computation. A price below this level proves infeasibility; this</span></div>
<divclass="line"><aid="l00817"name="l00817"></a><spanclass="lineno"> 817</span><spanclass="comment">// value is used for feasibility detection. We use this value also</span></div>
<divclass="line"><aid="l00818"name="l00818"></a><spanclass="lineno"> 818</span><spanclass="comment">// to rule out the possibility of arithmetic overflow or warn the</span></div>
<divclass="line"><aid="l00819"name="l00819"></a><spanclass="lineno"> 819</span><spanclass="comment">// client that we have not been able to rule out that possibility.</span></div>
<divclass="line"><aid="l00821"name="l00821"></a><spanclass="lineno"> 821</span><spanclass="comment">// We can use the value implied by Lemma 4 here, but note that that</span></div>
<divclass="line"><aid="l00822"name="l00822"></a><spanclass="lineno"> 822</span><spanclass="comment">// value includes k, the number of iterations. It's plenty fast if</span></div>
<divclass="line"><aid="l00823"name="l00823"></a><spanclass="lineno"> 823</span><spanclass="comment">// we count through the iterations to compute that value, but if</span></div>
<divclass="line"><aid="l00824"name="l00824"></a><spanclass="lineno"> 824</span><spanclass="comment">// we're going to count through the iterations, we might as well use</span></div>
<divclass="line"><aid="l00825"name="l00825"></a><spanclass="lineno"> 825</span><spanclass="comment">// the two-parameter bound from Lemma 3, summing up as we go. This</span></div>
<divclass="line"><aid="l00826"name="l00826"></a><spanclass="lineno"> 826</span><spanclass="comment">// gives us a tighter bound and more comprehensible code.</span></div>
<divclass="line"><aid="l00828"name="l00828"></a><spanclass="lineno"> 828</span><spanclass="comment">// While computing this bound, if we find the value justified by the</span></div>
<divclass="line"><aid="l00829"name="l00829"></a><spanclass="lineno"> 829</span><spanclass="comment">// theory lies outside the representable range of CostValue, we</span></div>
<divclass="line"><aid="l00830"name="l00830"></a><spanclass="lineno"> 830</span><spanclass="comment">// conclude that the given arc costs have magnitudes so large that</span></div>
<divclass="line"><aid="l00831"name="l00831"></a><spanclass="lineno"> 831</span><spanclass="comment">// we cannot guarantee our calculations don't overflow. If the value</span></div>
<divclass="line"><aid="l00832"name="l00832"></a><spanclass="lineno"> 832</span><spanclass="comment">// justified by the theory lies inside the representable range of</span></div>
<divclass="line"><aid="l00833"name="l00833"></a><spanclass="lineno"> 833</span><spanclass="comment">// CostValue, we commit that our calculation will not overflow. This</span></div>
<divclass="line"><aid="l00834"name="l00834"></a><spanclass="lineno"> 834</span><spanclass="comment">// commitment means we need to be careful with the amount by which</span></div>
<divclass="line"><aid="l00835"name="l00835"></a><spanclass="lineno"> 835</span><spanclass="comment">// we relabel right-side nodes that are incident to any node with</span></div>
<divclass="line"><aid="l00836"name="l00836"></a><spanclass="lineno"> 836</span><spanclass="comment">// only one neighbor.</span></div>
<divclass="line"><aid="l00839"name="l00839"></a><spanclass="lineno"> 839</span><spanclass="comment">// A bound on the amount by which a node's price can be reduced</span></div>
<divclass="line"><aid="l00840"name="l00840"></a><spanclass="lineno"> 840</span><spanclass="comment">// during the current iteration, used only for slack</span></div>
<divclass="line"><aid="l00841"name="l00841"></a><spanclass="lineno"> 841</span><spanclass="comment">// relabelings. Where epsilon is the first iteration's error</span></div>
<divclass="line"><aid="l00842"name="l00842"></a><spanclass="lineno"> 842</span><spanclass="comment">// parameter and C is the largest magnitude of an arc cost, we set</span></div>
<divclass="line"><aid="l00846"name="l00846"></a><spanclass="lineno"> 846</span><spanclass="comment">// We could use slack_relabeling_price_ for feasibility detection</span></div>
<divclass="line"><aid="l00847"name="l00847"></a><spanclass="lineno"> 847</span><spanclass="comment">// but the feasibility threshold is double the slack relabeling</span></div>
<divclass="line"><aid="l00848"name="l00848"></a><spanclass="lineno"> 848</span><spanclass="comment">// amount and we judge it not to be worth having to multiply by two</span></div>
<divclass="line"><aid="l00849"name="l00849"></a><spanclass="lineno"> 849</span><spanclass="comment">// gratuitously to check feasibility in each double push</span></div>
<divclass="line"><aid="l00850"name="l00850"></a><spanclass="lineno"> 850</span><spanclass="comment">// operation. Instead we settle for feasibility detection using</span></div>
<divclass="line"><aid="l00851"name="l00851"></a><spanclass="lineno"> 851</span><spanclass="comment">// price_lower_bound_ instead, which is somewhat slower in the</span></div>
<divclass="line"><aid="l00852"name="l00852"></a><spanclass="lineno"> 852</span><spanclass="comment">// infeasible case because more relabelings will be required for</span></div>
<divclass="line"><aid="l00853"name="l00853"></a><spanclass="lineno"> 853</span><spanclass="comment">// some node price to attain the looser bound.</span></div>
<divclass="line"><aid="l00856"name="l00856"></a><spanclass="lineno"> 856</span><spanclass="comment">// Computes the value of the bound on price reduction for an</span></div>
<divclass="line"><aid="l00857"name="l00857"></a><spanclass="lineno"> 857</span><spanclass="comment">// iteration, given the old and new values of epsilon_. Because the</span></div>
<divclass="line"><aid="l00858"name="l00858"></a><spanclass="lineno"> 858</span><spanclass="comment">// expression computed here is used in at least one place where we</span></div>
<divclass="line"><aid="l00859"name="l00859"></a><spanclass="lineno"> 859</span><spanclass="comment">// want an additional factor in the denominator, we take that factor</span></div>
<divclass="line"><aid="l00860"name="l00860"></a><spanclass="lineno"> 860</span><spanclass="comment">// as an argument. If extra_divisor == 1, this function computes of</span></div>
<divclass="line"><aid="l00861"name="l00861"></a><spanclass="lineno"> 861</span><spanclass="comment">// the function B() discussed above.</span></div>
<divclass="line"><aid="l00863"name="l00863"></a><spanclass="lineno"> 863</span><spanclass="comment">// Avoids overflow in computing the bound, and sets *in_range =</span></div>
<divclass="line"><aid="l00864"name="l00864"></a><spanclass="lineno"> 864</span><spanclass="comment">// false if the value of the bound doesn't fit in CostValue.</span></div>
<divclass="line"><aid="l00868"name="l00868"></a><spanclass="lineno"> 868</span><spanclass="keyword">const</span><aclass="code hl_typedef"href="namespaceoperations__research.html#a1d1a935ab48f768867fc7e8607ca97b4">CostValue</a> n = graph_->num_nodes();</div>
<divclass="line"><aid="l00869"name="l00869"></a><spanclass="lineno"> 869</span><spanclass="comment">// We work in double-precision floating point to determine whether</span></div>
<divclass="line"><aid="l00870"name="l00870"></a><spanclass="lineno"> 870</span><spanclass="comment">// we'll overflow the integral CostValue type's range of</span></div>
<divclass="line"><aid="l00871"name="l00871"></a><spanclass="lineno"> 871</span><spanclass="comment">// representation. Switching between integer and double is a</span></div>
<divclass="line"><aid="l00872"name="l00872"></a><spanclass="lineno"> 872</span><spanclass="comment">// rather expensive operation, but we do this only twice per</span></div>
<divclass="line"><aid="l00873"name="l00873"></a><spanclass="lineno"> 873</span><spanclass="comment">// scaling iteration, so we can afford it rather than resort to</span></div>
<divclass="line"><aid="l00874"name="l00874"></a><spanclass="lineno"> 874</span><spanclass="comment">// complex and subtle tricks within the bounds of integer</span></div>
<divclass="line"><aid="l00877"name="l00877"></a><spanclass="lineno"> 877</span><spanclass="comment">// You will want to read the comments above about</span></div>
<divclass="line"><aid="l00878"name="l00878"></a><spanclass="lineno"> 878</span><spanclass="comment">// price_lower_bound_ and slack_relabeling_price_, and have a</span></div>
<divclass="line"><aid="l00880"name="l00880"></a><spanclass="lineno"> 880</span><spanclass="keyword">const</span><spanclass="keywordtype">double</span> result =</div>
<divclass="line"><aid="l00881"name="l00881"></a><spanclass="lineno"> 881</span><spanclass="keyword">static_cast<</span><spanclass="keywordtype">double</span><spanclass="keyword">></span>(std::max<CostValue>(1, n / 2 - 1)) *</div>
<divclass="line"><aid="l00890"name="l00890"></a><spanclass="lineno"> 890</span><spanclass="comment">// Don't touch *in_range; other computations could already have</span></div>
<divclass="line"><aid="l00891"name="l00891"></a><spanclass="lineno"> 891</span><spanclass="comment">// set it to false and we don't want to overwrite that result.</span></div>
<divclass="line"><aid="l00896"name="l00896"></a><spanclass="lineno"> 896</span><spanclass="comment">// A scaled record of the largest arc-cost magnitude we've been</span></div>
<divclass="line"><aid="l00897"name="l00897"></a><spanclass="lineno"> 897</span><spanclass="comment">// given during problem setup. This is used to set the initial value</span></div>
<divclass="line"><aid="l00898"name="l00898"></a><spanclass="lineno"> 898</span><spanclass="comment">// of epsilon_, which in turn is used not only as the error</span></div>
<divclass="line"><aid="l00899"name="l00899"></a><spanclass="lineno"> 899</span><spanclass="comment">// parameter but also to determine whether we risk arithmetic</span></div>
<divclass="line"><aid="l00900"name="l00900"></a><spanclass="lineno"> 900</span><spanclass="comment">// overflow during the algorithm.</span></div>
<divclass="line"><aid="l00902"name="l00902"></a><spanclass="lineno"> 902</span><spanclass="comment">// Note: Our treatment of arithmetic overflow assumes the following</span></div>
<divclass="line"><aid="l00903"name="l00903"></a><spanclass="lineno"> 903</span><spanclass="comment">// property of CostValue:</span></div>
<divclass="line"><aid="l00904"name="l00904"></a><spanclass="lineno"> 904</span><spanclass="comment">// -std::numeric_limits<CostValue>::max() is a representable</span></div>
<divclass="line"><aid="l00906"name="l00906"></a><spanclass="lineno"> 906</span><spanclass="comment">// That property is satisfied if CostValue uses a two's-complement</span></div>
<divclass="line"><aid="l00910"name="l00910"></a><spanclass="lineno"> 910</span><spanclass="comment">// The total excess in the graph. Given our asymmetric definition of</span></div>
<divclass="line"><aid="l00911"name="l00911"></a><spanclass="lineno"> 911</span><spanclass="comment">// epsilon-optimality and our use of the double-push operation, this</span></div>
<divclass="line"><aid="l00912"name="l00912"></a><spanclass="lineno"> 912</span><spanclass="comment">// equals the number of unmatched left-side nodes.</span></div>
<divclass="line"><aid="l00915"name="l00915"></a><spanclass="lineno"> 915</span><spanclass="comment">// Indexed by node index, the price_ values are maintained only for</span></div>
<divclass="line"><aid="l00918"name="l00918"></a><spanclass="lineno"> 918</span><spanclass="comment">// Note: We use a ZVector to only allocate a vector of size num_left_nodes_</span></div>
<divclass="line"><aid="l00919"name="l00919"></a><spanclass="lineno"> 919</span><spanclass="comment">// instead of 2*num_left_nodes_ since the right-side node indices start at</span></div>
<divclass="line"><aid="l00923"name="l00923"></a><spanclass="lineno"> 923</span><spanclass="comment">// Indexed by left-side node index, the matched_arc_ array gives the</span></div>
<divclass="line"><aid="l00924"name="l00924"></a><spanclass="lineno"> 924</span><spanclass="comment">// arc index of the arc matching any given left-side node, or</span></div>
<divclass="line"><aid="l00925"name="l00925"></a><spanclass="lineno"> 925</span><spanclass="comment">// GraphType::kNilArc if the node is unmatched.</span></div>
<divclass="line"><aid="l00928"name="l00928"></a><spanclass="lineno"> 928</span><spanclass="comment">// Indexed by right-side node index, the matched_node_ array gives</span></div>
<divclass="line"><aid="l00929"name="l00929"></a><spanclass="lineno"> 929</span><spanclass="comment">// the node index of the left-side node matching any given</span></div>
<divclass="line"><aid="l00930"name="l00930"></a><spanclass="lineno"> 930</span><spanclass="comment">// right-side node, or GraphType::kNilNode if the right-side node is</span></div>
<divclass="line"><aid="l00933"name="l00933"></a><spanclass="lineno"> 933</span><spanclass="comment">// Note: We use a ZVector for the same reason as for price_.</span></div>
<divclass="line"><aid="l00936"name="l00936"></a><spanclass="lineno"> 936</span><spanclass="comment">// The array of arc costs as given in the problem definition, except</span></div>
<divclass="line"><aid="l00937"name="l00937"></a><spanclass="lineno"> 937</span><spanclass="comment">// that they are scaled up by the number of nodes in the graph so we</span></div>
<divclass="line"><aid="l00938"name="l00938"></a><spanclass="lineno"> 938</span><spanclass="comment">// can use integer arithmetic throughout.</span></div>
<divclass="line"><aid="l00941"name="l00941"></a><spanclass="lineno"> 941</span><spanclass="comment">// The container of active nodes (i.e., unmatched nodes). This can</span></div>
<divclass="line"><aid="l00942"name="l00942"></a><spanclass="lineno"> 942</span><spanclass="comment">// be switched easily between ActiveNodeStack and ActiveNodeQueue</span></div>
<divclass="line"><aid="l00943"name="l00943"></a><spanclass="lineno"> 943</span><spanclass="comment">// for experimentation.</span></div>
<divclass="line"><aid="l00946"name="l00946"></a><spanclass="lineno"> 946</span><spanclass="comment">// Statistics giving the overall numbers of various operations the</span></div>
<divclass="line"><aid="l00950"name="l00950"></a><spanclass="lineno"> 950</span><spanclass="comment">// Statistics giving the numbers of various operations the algorithm</span></div>
<divclass="line"><aid="l00951"name="l00951"></a><spanclass="lineno"> 951</span><spanclass="comment">// has performed in the current iteration.</span></div>
<divclass="line"><aid="l01052"name="l01052"></a><spanclass="lineno"> 1052</span><spanclass="comment">// Logically this class should be defined inside OptimizeGraphLayout,</span></div>
<divclass="line"><aid="l01053"name="l01053"></a><spanclass="lineno"> 1053</span><spanclass="comment">// but compilation fails if we do that because C++98 doesn't allow</span></div>
<divclass="line"><aid="l01054"name="l01054"></a><spanclass="lineno"> 1054</span><spanclass="comment">// instantiation of member templates with function-scoped types as</span></div>
<divclass="line"><aid="l01055"name="l01055"></a><spanclass="lineno"> 1055</span><spanclass="comment">// template parameters, which in turn is because those function-scoped</span></div>
<divclass="line"><aid="l01062"name="l01062"></a><spanclass="lineno"> 1062</span><spanclass="comment">// Says ArcIndex a is less than ArcIndex b if arc a's tail is less</span></div>
<divclass="line"><aid="l01063"name="l01063"></a><spanclass="lineno"> 1063</span><spanclass="comment">// than arc b's tail. If their tails are equal, orders according to</span></div>
<divclass="line"><aid="l01075"name="l01075"></a><spanclass="lineno"> 1075</span><spanclass="comment">// Copy and assign are allowed; they have to be for STL to work</span></div>
<divclass="line"><aid="l01076"name="l01076"></a><spanclass="lineno"> 1076</span><spanclass="comment">// with this functor, although it seems like a bug for STL to be</span></div>
<divclass="line"><aid="l01077"name="l01077"></a><spanclass="lineno"> 1077</span><spanclass="comment">// written that way.</span></div>
<divclass="line"><aid="l01080"name="l01080"></a><spanclass="lineno"> 1080</span><spanclass="comment">// Passes ownership of the cycle handler to the caller.</span></div>
<divclass="line"><aid="l01090"name="l01090"></a><spanclass="lineno"> 1090</span><spanclass="comment">// The graph argument is only to give us a non-const-qualified</span></div>
<divclass="line"><aid="l01091"name="l01091"></a><spanclass="lineno"> 1091</span><spanclass="comment">// handle on the graph we already have. Any different graph is</span></div>
<divclass="line"><aid="l01117"name="l01117"></a><spanclass="lineno"> 1117</span><spanclass="comment">// For today we always return true; in the future updating epsilon</span></div>
<divclass="line"><aid="l01118"name="l01118"></a><spanclass="lineno"> 1118</span><spanclass="comment">// in sophisticated ways could conceivably detect infeasibility</span></div>
<divclass="line"><aid="l01119"name="l01119"></a><spanclass="lineno"> 1119</span><spanclass="comment">// before the first iteration of Refine().</span></div>
<divclass="line"><aid="l01123"name="l01123"></a><spanclass="lineno"> 1123</span><spanclass="comment">// For production code that checks whether a left-side node is active.</span></div>
<divclass="line"><aid="l01131"name="l01131"></a><spanclass="lineno"> 1131</span><spanclass="comment">// Only for debugging. Separate from the production IsActive() method</span></div>
<divclass="line"><aid="l01132"name="l01132"></a><spanclass="lineno"> 1132</span><spanclass="comment">// so that method can assert that its argument is a left-side node,</span></div>
<divclass="line"><aid="l01133"name="l01133"></a><spanclass="lineno"> 1133</span><spanclass="comment">// while for debugging we need to be able to test any node.</span></div>
<divclass="line"><aid="l01156"name="l01156"></a><spanclass="lineno"> 1156</span><spanclass="comment">// There exists a price function such that the admissible arcs at the</span></div>
<divclass="line"><aid="l01157"name="l01157"></a><spanclass="lineno"> 1157</span><spanclass="comment">// beginning of an iteration are exactly the reverse arcs of all</span></div>
<divclass="line"><aid="l01158"name="l01158"></a><spanclass="lineno"> 1158</span><spanclass="comment">// matching arcs. Saturating all admissible arcs with respect to that</span></div>
<divclass="line"><aid="l01159"name="l01159"></a><spanclass="lineno"> 1159</span><spanclass="comment">// price function therefore means simply unmatching every matched</span></div>
<divclass="line"><aid="l01162"name="l01162"></a><spanclass="lineno"> 1162</span><spanclass="comment">// In the future we will price out arcs, which will reduce the set of</span></div>
<divclass="line"><aid="l01163"name="l01163"></a><spanclass="lineno"> 1163</span><spanclass="comment">// nodes we unmatch here. If a matching arc is priced out, we will not</span></div>
<divclass="line"><aid="l01164"name="l01164"></a><spanclass="lineno"> 1164</span><spanclass="comment">// unmatch its endpoints since that element of the matching is</span></div>
<divclass="line"><aid="l01165"name="l01165"></a><spanclass="lineno"> 1165</span><spanclass="comment">// guaranteed not to change.</span></div>
<divclass="line"><aid="l01173"name="l01173"></a><spanclass="lineno"> 1173</span><spanclass="comment">// This can happen in the first iteration when nothing is</span></div>
<divclass="line"><aid="l01177"name="l01177"></a><spanclass="lineno"> 1177</span><spanclass="comment">// We're about to create a unit of excess by unmatching these nodes.</span></div>
<divclass="line"><aid="l01186"name="l01186"></a><spanclass="lineno"> 1186</span><spanclass="comment">// Returns true for success, false for infeasible.</span></div>
<divclass="line"><aid="l01191"name="l01191"></a><spanclass="lineno"> 1191</span><<<spanclass="stringliteral">"must be active (unmatched)!"</span>;</div>
<divclass="line"><aid="l01194"name="l01194"></a><spanclass="lineno"> 1194</span><spanclass="keyword">const</span><aclass="code hl_typedef"href="namespaceoperations__research.html#a1d1a935ab48f768867fc7e8607ca97b4">CostValue</a> gap = summary.second;</div>
<divclass="line"><aid="l01195"name="l01195"></a><spanclass="lineno"> 1195</span><spanclass="comment">// Now we have the best arc incident to source, i.e., the one with</span></div>
<divclass="line"><aid="l01196"name="l01196"></a><spanclass="lineno"> 1196</span><spanclass="comment">// minimum reduced cost. Match that arc, unmatching its head if</span></div>
<divclass="line"><aid="l01204"name="l01204"></a><spanclass="lineno"> 1204</span><spanclass="comment">// Unmatch new_mate from its current mate, pushing the unit of</span></div>
<divclass="line"><aid="l01205"name="l01205"></a><spanclass="lineno"> 1205</span><spanclass="comment">// flow back to a node on the left side as a unit of excess.</span></div>
<divclass="line"><aid="l01211"name="l01211"></a><spanclass="lineno"> 1211</span><spanclass="comment">// We are about to increase the cardinality of the matching.</span></div>
<divclass="line"><aid="l01230"name="l01230"></a><spanclass="lineno"> 1230</span><spanclass="comment">// Get an active node (i.e., one with excess == 1) and discharge</span></div>
<divclass="line"><aid="l01231"name="l01231"></a><spanclass="lineno"> 1231</span><spanclass="comment">// it using DoublePush.</span></div>
<divclass="line"><aid="l01236"name="l01236"></a><spanclass="lineno"> 1236</span><spanclass="comment">// If infeasibility is detected after the first iteration, we</span></div>
<divclass="line"><aid="l01237"name="l01237"></a><spanclass="lineno"> 1237</span><spanclass="comment">// have a bug. We don't crash production code in this case but</span></div>
<divclass="line"><aid="l01238"name="l01238"></a><spanclass="lineno"> 1238</span><spanclass="comment">// we know we're returning a wrong answer so we we leave a</span></div>
<divclass="line"><aid="l01239"name="l01239"></a><spanclass="lineno"> 1239</span><spanclass="comment">// message in the logs to increase our hope of chasing down the</span></div>
<divclass="line"><aid="l01242"name="l01242"></a><spanclass="lineno"> 1242</span><<<spanclass="stringliteral">"Infeasibility detection triggered after first iteration found "</span></div>
<divclass="line"><aid="l01252"name="l01252"></a><spanclass="lineno"> 1252</span><spanclass="comment">// Computes best_arc, the minimum reduced-cost arc incident to</span></div>
<divclass="line"><aid="l01253"name="l01253"></a><spanclass="lineno"> 1253</span><spanclass="comment">// left_node and admissibility_gap, the amount by which the reduced</span></div>
<divclass="line"><aid="l01254"name="l01254"></a><spanclass="lineno"> 1254</span><spanclass="comment">// cost of best_arc must be increased to make it equal in reduced cost</span></div>
<divclass="line"><aid="l01255"name="l01255"></a><spanclass="lineno"> 1255</span><spanclass="comment">// to another residual arc incident to left_node.</span></div>
<divclass="line"><aid="l01257"name="l01257"></a><spanclass="lineno"> 1257</span><spanclass="comment">// Precondition: left_node is unmatched and has at least one incident</span></div>
<divclass="line"><aid="l01258"name="l01258"></a><spanclass="lineno"> 1258</span><spanclass="comment">// arc. This allows us to simplify the code. The debug-only</span></div>
<divclass="line"><aid="l01259"name="l01259"></a><spanclass="lineno"> 1259</span><spanclass="comment">// counterpart to this routine is LinearSumAssignment::ImplicitPrice()</span></div>
<divclass="line"><aid="l01260"name="l01260"></a><spanclass="lineno"> 1260</span><spanclass="comment">// and it assumes there is an incident arc but does not assume the</span></div>
<divclass="line"><aid="l01261"name="l01261"></a><spanclass="lineno"> 1261</span><spanclass="comment">// node is unmatched. The condition that each left node has at least</span></div>
<divclass="line"><aid="l01262"name="l01262"></a><spanclass="lineno"> 1262</span><spanclass="comment">// one incident arc is explicitly computed during FinalizeSetup().</span></div>
<divclass="line"><aid="l01264"name="l01264"></a><spanclass="lineno"> 1264</span><spanclass="comment">// This function is large enough that our suggestion that the compiler</span></div>
<divclass="line"><aid="l01265"name="l01265"></a><spanclass="lineno"> 1265</span><spanclass="comment">// inline it might be pointless.</span></div>
<divclass="line"><aid="l01270"name="l01270"></a><spanclass="lineno"> 1270</span><<<spanclass="stringliteral">"Node "</span><< left_node <<<spanclass="stringliteral">" must be active (unmatched)!"</span>;</div>
<divclass="line"><aid="l01275"name="l01275"></a><spanclass="lineno"> 1275</span><spanclass="comment">// We choose second_min_partial_reduced_cost so that in the case of</span></div>
<divclass="line"><aid="l01276"name="l01276"></a><spanclass="lineno"> 1276</span><spanclass="comment">// the largest possible gap (which results from a left-side node</span></div>
<divclass="line"><aid="l01277"name="l01277"></a><spanclass="lineno"> 1277</span><spanclass="comment">// with only a single incident residual arc), the corresponding</span></div>
<divclass="line"><aid="l01278"name="l01278"></a><spanclass="lineno"> 1278</span><spanclass="comment">// right-side node will be relabeled by an amount that exactly</span></div>
<divclass="line"><aid="l01304"name="l01304"></a><spanclass="lineno"> 1304</span><spanclass="comment">// Requires the precondition, explicitly computed in FinalizeSetup(),</span></div>
<divclass="line"><aid="l01305"name="l01305"></a><spanclass="lineno"> 1305</span><spanclass="comment">// that every left-side node has at least one incident arc.</span></div>
<divclass="line"><aid="l01312"name="l01312"></a><spanclass="lineno"> 1312</span><spanclass="comment">// We must not execute this method if left_node has no incident arc.</span></div>
<divclass="line"><aid="l01323"name="l01323"></a><spanclass="lineno"> 1323</span><spanclass="comment">// Only one arc is incident to left_node, and the node is</span></div>
<divclass="line"><aid="l01324"name="l01324"></a><spanclass="lineno"> 1324</span><spanclass="comment">// currently matched along that arc, which must be the case in any</span></div>
<divclass="line"><aid="l01325"name="l01325"></a><spanclass="lineno"> 1325</span><spanclass="comment">// feasible solution. Therefore we implicitly price this node so</span></div>
<divclass="line"><aid="l01326"name="l01326"></a><spanclass="lineno"> 1326</span><spanclass="comment">// low that we will never consider unmatching it.</span></div>
<divclass="line"><aid="l01358"name="l01358"></a><spanclass="lineno"> 1358</span><spanclass="comment">// Get the implicit price of left_node and make sure the reduced</span></div>
<divclass="line"><aid="l01359"name="l01359"></a><spanclass="lineno"> 1359</span><spanclass="comment">// costs of left_node's incident arcs are in bounds.</span></div>
<divclass="line"><aid="l01365"name="l01365"></a><spanclass="lineno"> 1365</span><spanclass="comment">// Note the asymmetric definition of epsilon-optimality that we</span></div>
<divclass="line"><aid="l01366"name="l01366"></a><spanclass="lineno"> 1366</span><spanclass="comment">// use because it means we can saturate all admissible arcs in</span></div>
<divclass="line"><aid="l01367"name="l01367"></a><spanclass="lineno"> 1367</span><spanclass="comment">// the beginning of Refine() just by unmatching all matched</span></div>
<divclass="line"><aid="l01370"name="l01370"></a><spanclass="lineno"> 1370</span><spanclass="comment">// The reverse arc is residual. Epsilon-optimality requires</span></div>
<divclass="line"><aid="l01371"name="l01371"></a><spanclass="lineno"> 1371</span><spanclass="comment">// that the reduced cost of the forward arc be at most</span></div>
<divclass="line"><aid="l01377"name="l01377"></a><spanclass="lineno"> 1377</span><spanclass="comment">// The forward arc is residual. Epsilon-optimality requires</span></div>
<divclass="line"><aid="l01378"name="l01378"></a><spanclass="lineno"> 1378</span><spanclass="comment">// that the reduced cost of the forward arc be at least zero.</span></div>
<divclass="line"><aid="l01391"name="l01391"></a><spanclass="lineno"> 1391</span><spanclass="comment">// epsilon_ must be greater than kMinEpsilon so that in the case</span></div>
<divclass="line"><aid="l01392"name="l01392"></a><spanclass="lineno"> 1392</span><spanclass="comment">// where the largest arc cost is zero, we still do a Refine()</span></div>
<divclass="line"><aid="l01434"name="l01434"></a><spanclass="lineno"> 1434</span> LOG(WARNING) <<<spanclass="stringliteral">"Price change bound exceeds range of representable "</span></div>
<divclass="line"><aid="l01435"name="l01435"></a><spanclass="lineno"> 1435</span><<<spanclass="stringliteral">"costs; arithmetic overflow is not ruled out and "</span></div>
<divclass="line"><aid="l01436"name="l01436"></a><spanclass="lineno"> 1436</span><<<spanclass="stringliteral">"infeasibility might go undetected."</span>;</div>
<divclass="line"><aid="l01453"name="l01453"></a><spanclass="lineno"> 1453</span><spanclass="comment">// Note: FinalizeSetup() might have been called already by white-box</span></div>
<divclass="line"><aid="l01454"name="l01454"></a><spanclass="lineno"> 1454</span><spanclass="comment">// test code or by a client that wants to react to the possibility</span></div>
<divclass="line"><aid="l01455"name="l01455"></a><spanclass="lineno"> 1455</span><spanclass="comment">// of overflow before solving the given problem, but FinalizeSetup()</span></div>
<divclass="line"><aid="l01456"name="l01456"></a><spanclass="lineno"> 1456</span><spanclass="comment">// is idempotent and reasonably fast, so we call it unconditionally</span></div>
<divclass="line"><aid="l01475"name="l01475"></a><spanclass="lineno"> 1475</span><spanclass="comment">// It is illegal to call this method unless we successfully computed</span></div>
<divclass="line"><aid="l01476"name="l01476"></a><spanclass="lineno"> 1476</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#l01065">linear_assignment.h:1065</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1_linear_sum_assignment_html_a6c98ee1246919ef8b61e5bc400982f49"><divclass="ttname"><ahref="classoperations__research_1_1_linear_sum_assignment.html#a6c98ee1246919ef8b61e5bc400982f49">operations_research::LinearSumAssignment::Graph</a></div><divclass="ttdeci">const GraphType & Graph() const</div><divclass="ttdef"><b>Definition:</b><ahref="linear__assignment_8h_source.html#l00282">linear_assignment.h:282</a></div></div>