<ahref="cuts_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="l00034"name="l00034"></a><spanclass="lineno"> 34</span><spanclass="comment">// A "cut" generator on a set of IntegerVariable.</span></div>
<divclass="line"><aid="l00036"name="l00036"></a><spanclass="lineno"> 36</span><spanclass="comment">// The generate_cuts() function will usually be called with the current LP</span></div>
<divclass="line"><aid="l00037"name="l00037"></a><spanclass="lineno"> 37</span><spanclass="comment">// optimal solution (but should work for any lp_values). Note that a</span></div>
<divclass="line"><aid="l00039"name="l00039"></a><spanclass="lineno"> 39</span><spanclass="comment">// - Only look at the lp_values positions that corresponds to its 'vars' or</span></div>
<divclass="line"><aid="l00040"name="l00040"></a><spanclass="lineno"> 40</span><spanclass="comment">// their negation.</span></div>
<divclass="line"><aid="l00041"name="l00041"></a><spanclass="lineno"> 41</span><spanclass="comment">// - Only add cuts in term of the same variables or their negation.</span></div>
<divclass="line"><aid="l00050"name="l00050"></a><spanclass="lineno"> 50</span><spanclass="comment">// Given an upper-bounded linear relation (sum terms <= ub), this algorithm</span></div>
<divclass="line"><aid="l00051"name="l00051"></a><spanclass="lineno"> 51</span><spanclass="comment">// inspects the integer variable appearing in the sum and try to replace each of</span></div>
<divclass="line"><aid="l00052"name="l00052"></a><spanclass="lineno"> 52</span><spanclass="comment">// them by a tight lower bound (>= coeff * binary + lb) using the implied bound</span></div>
<divclass="line"><aid="l00053"name="l00053"></a><spanclass="lineno"> 53</span><spanclass="comment">// repository. By tight, we mean that it will take the same value under the</span></div>
<divclass="line"><aid="l00054"name="l00054"></a><spanclass="lineno"> 54</span><spanclass="comment">// current LP solution.</span></div>
<divclass="line"><aid="l00056"name="l00056"></a><spanclass="lineno"> 56</span><spanclass="comment">// We use a class to reuse memory of the tmp terms.</span></div>
<divclass="line"><aid="l00059"name="l00059"></a><spanclass="lineno"> 59</span><spanclass="comment">// We will only replace IntegerVariable appearing in lp_vars_.</span></div>
<divclass="line"><aid="l00067"name="l00067"></a><spanclass="lineno"> 67</span><spanclass="comment">// See if some of the implied bounds equation are violated and add them to</span></div>
<divclass="line"><aid="l00068"name="l00068"></a><spanclass="lineno"> 68</span><spanclass="comment">// the IB cut pool if it is the case.</span></div>
<divclass="line"><aid="l00070"name="l00070"></a><spanclass="lineno"> 70</span><spanclass="comment">// Important: This must be called before we process any constraints with a</span></div>
<divclass="line"><aid="l00071"name="l00071"></a><spanclass="lineno"> 71</span><spanclass="comment">// different lp_values or level zero bounds.</span></div>
<divclass="line"><aid="l00075"name="l00075"></a><spanclass="lineno"> 75</span><spanclass="comment">// Processes and updates the given cut.</span></div>
<divclass="line"><aid="l00080"name="l00080"></a><spanclass="lineno"> 80</span><spanclass="comment">// Same as ProcessUpperBoundedConstraint() but instead of just using</span></div>
<divclass="line"><aid="l00081"name="l00081"></a><spanclass="lineno"> 81</span><spanclass="comment">// var >= coeff * binary + lb we use var == slack + coeff * binary + lb where</span></div>
<divclass="line"><aid="l00082"name="l00082"></a><spanclass="lineno"> 82</span><spanclass="comment">// slack is a new temporary variable that we create.</span></div>
<divclass="line"><aid="l00084"name="l00084"></a><spanclass="lineno"> 84</span><spanclass="comment">// The new slack will be such that slack_infos[(slack - first_slack) / 2]</span></div>
<divclass="line"><aid="l00085"name="l00085"></a><spanclass="lineno"> 85</span><spanclass="comment">// contains its definition so that we can properly handle it in the cut</span></div>
<divclass="line"><aid="l00086"name="l00086"></a><spanclass="lineno"> 86</span><spanclass="comment">// generation and substitute it back later.</span></div>
<divclass="line"><aid="l00088"name="l00088"></a><spanclass="lineno"> 88</span><spanclass="comment">// This slack is equal to sum of terms + offset.</span></div>
<divclass="line"><aid="l00092"name="l00092"></a><spanclass="lineno"> 92</span><spanclass="comment">// The slack bounds and current lp_value.</span></div>
<divclass="line"><aid="l00104"name="l00104"></a><spanclass="lineno"> 104</span><spanclass="comment">// Substituting back the slack created by the function above should give</span></div>
<divclass="line"><aid="l00105"name="l00105"></a><spanclass="lineno"> 105</span><spanclass="comment">// exactly the same cut as the original one.</span></div>
<divclass="line"><aid="l00111"name="l00111"></a><spanclass="lineno"> 111</span><spanclass="comment">// Add a new variable that could be used in the new cuts.</span></div>
<divclass="line"><aid="l00112"name="l00112"></a><spanclass="lineno"> 112</span><spanclass="comment">// Note that the cache must be computed to take this into account.</span></div>
<divclass="line"><aid="l00115"name="l00115"></a><spanclass="lineno"> 115</span><spanclass="comment">// Once RecomputeCacheAndSeparateSomeImpliedBoundCuts() has been called,</span></div>
<divclass="line"><aid="l00116"name="l00116"></a><spanclass="lineno"> 116</span><spanclass="comment">// we can get the best implied bound for each variables.</span></div>
<divclass="line"><aid="l00126"name="l00126"></a><spanclass="lineno"> 126</span><spanclass="comment">// As we compute the best implied bounds for each variable, we add violated</span></div>
<divclass="line"><aid="l00144"name="l00144"></a><spanclass="lineno"> 144</span><spanclass="comment">// Temporary memory used by ProcessUpperBoundedConstraint().</span></div>
<divclass="line"><aid="l00148"name="l00148"></a><spanclass="lineno"> 148</span><spanclass="comment">// Visible for testing. Returns a function f on integers such that:</span></div>
<divclass="line"><aid="l00149"name="l00149"></a><spanclass="lineno"> 149</span><spanclass="comment">// - f is non-decreasing.</span></div>
<divclass="line"><aid="l00150"name="l00150"></a><spanclass="lineno"> 150</span><spanclass="comment">// - f is super-additive: f(a) + f(b) <= f(a + b)</span></div>
<divclass="line"><aid="l00152"name="l00152"></a><spanclass="lineno"> 152</span><spanclass="comment">// - For all x, f(x * divisor) = x * f(divisor)</span></div>
<divclass="line"><aid="l00153"name="l00153"></a><spanclass="lineno"> 153</span><spanclass="comment">// - For all x, f(x * divisor + remainder) = x * f(divisor)</span></div>
<divclass="line"><aid="l00159"name="l00159"></a><spanclass="lineno"> 159</span><spanclass="comment">// This is used in IntegerRoundingCut() and is responsible for "strengthening"</span></div>
<divclass="line"><aid="l00160"name="l00160"></a><spanclass="lineno"> 160</span><spanclass="comment">// the cut. Just taking f(x) = x / divisor result in the non-strengthened cut</span></div>
<divclass="line"><aid="l00161"name="l00161"></a><spanclass="lineno"> 161</span><spanclass="comment">// and using any function that stricly dominate this one is better.</span></div>
<divclass="line"><aid="l00164"name="l00164"></a><spanclass="lineno"> 164</span><spanclass="comment">// - We first scale by a factor t so that rhs_remainder >= divisor / 2.</span></div>
<divclass="line"><aid="l00165"name="l00165"></a><spanclass="lineno"> 165</span><spanclass="comment">// - Then, if max_scaling == 2, we use the function described</span></div>
<divclass="line"><aid="l00166"name="l00166"></a><spanclass="lineno"> 166</span><spanclass="comment">// in "Strenghtening Chvatal-Gomory cuts and Gomory fractional cuts", Adam N.</span></div>
<divclass="line"><aid="l00167"name="l00167"></a><spanclass="lineno"> 167</span><spanclass="comment">// Letchfrod, Andrea Lodi.</span></div>
<divclass="line"><aid="l00168"name="l00168"></a><spanclass="lineno"> 168</span><spanclass="comment">// - Otherwise, we use a generalization of this which is a discretized version</span></div>
<divclass="line"><aid="l00169"name="l00169"></a><spanclass="lineno"> 169</span><spanclass="comment">// of the classical MIR rounding function that only take the value of the</span></div>
<divclass="line"><aid="l00170"name="l00170"></a><spanclass="lineno"> 170</span><spanclass="comment">// form "an_integer / max_scaling". As max_scaling goes to infinity, this</span></div>
<divclass="line"><aid="l00171"name="l00171"></a><spanclass="lineno"> 171</span><spanclass="comment">// converge to the real-valued MIR function.</span></div>
<divclass="line"><aid="l00173"name="l00173"></a><spanclass="lineno"> 173</span><spanclass="comment">// Note that for each value of max_scaling we will get a different function.</span></div>
<divclass="line"><aid="l00174"name="l00174"></a><spanclass="lineno"> 174</span><spanclass="comment">// And that there is no dominance relation between any of these functions. So</span></div>
<divclass="line"><aid="l00175"name="l00175"></a><spanclass="lineno"> 175</span><spanclass="comment">// it could be nice to try to generate a cut using different values of</span></div>
<divclass="line"><aid="l00183"name="l00183"></a><spanclass="lineno"> 183</span><spanclass="comment">// Given an upper bounded linear constraint, this function tries to transform it</span></div>
<divclass="line"><aid="l00184"name="l00184"></a><spanclass="lineno"> 184</span><spanclass="comment">// to a valid cut that violate the given LP solution using integer rounding.</span></div>
<divclass="line"><aid="l00185"name="l00185"></a><spanclass="lineno"> 185</span><spanclass="comment">// Note that the returned cut might not always violate the LP solution, in which</span></div>
<divclass="line"><aid="l00186"name="l00186"></a><spanclass="lineno"> 186</span><spanclass="comment">// case it can be discarded.</span></div>
<divclass="line"><aid="l00188"name="l00188"></a><spanclass="lineno"> 188</span><spanclass="comment">// What this does is basically take the integer division of the constraint by an</span></div>
<divclass="line"><aid="l00189"name="l00189"></a><spanclass="lineno"> 189</span><spanclass="comment">// integer. If the coefficients where doubles, this would be the same as scaling</span></div>
<divclass="line"><aid="l00190"name="l00190"></a><spanclass="lineno"> 190</span><spanclass="comment">// the constraint and then rounding. We choose the coefficient of the most</span></div>
<divclass="line"><aid="l00191"name="l00191"></a><spanclass="lineno"> 191</span><spanclass="comment">// fractional variable (rescaled by its coefficient) as the divisor, but there</span></div>
<divclass="line"><aid="l00192"name="l00192"></a><spanclass="lineno"> 192</span><spanclass="comment">// are other possible alternatives.</span></div>
<divclass="line"><aid="l00194"name="l00194"></a><spanclass="lineno"> 194</span><spanclass="comment">// Note that if the constraint is tight under the given lp solution, and if</span></div>
<divclass="line"><aid="l00195"name="l00195"></a><spanclass="lineno"> 195</span><spanclass="comment">// there is a unique variable not at one of its bounds and fractional, then we</span></div>
<divclass="line"><aid="l00196"name="l00196"></a><spanclass="lineno"> 196</span><spanclass="comment">// are guaranteed to generate a cut that violate the current LP solution. This</span></div>
<divclass="line"><aid="l00197"name="l00197"></a><spanclass="lineno"> 197</span><spanclass="comment">// should be the case for Chvatal-Gomory base constraints modulo our loss of</span></div>
<divclass="line"><aid="l00198"name="l00198"></a><spanclass="lineno"> 198</span><spanclass="comment">// precision while doing exact integer computations.</span></div>
<divclass="line"><aid="l00201"name="l00201"></a><spanclass="lineno"> 201</span><spanclass="comment">// - We assumes that the given initial constraint is tight using the given lp</span></div>
<divclass="line"><aid="l00202"name="l00202"></a><spanclass="lineno"> 202</span><spanclass="comment">// values. This could be relaxed, but for now it should always be the case, so</span></div>
<divclass="line"><aid="l00203"name="l00203"></a><spanclass="lineno"> 203</span><spanclass="comment">// we log a message and abort if not, to ease debugging.</span></div>
<divclass="line"><aid="l00204"name="l00204"></a><spanclass="lineno"> 204</span><spanclass="comment">// - The IntegerVariable of the cuts are not used here. We assumes that the</span></div>
<divclass="line"><aid="l00205"name="l00205"></a><spanclass="lineno"> 205</span><spanclass="comment">// first three vectors are in one to one correspondence with the initial order</span></div>
<divclass="line"><aid="l00206"name="l00206"></a><spanclass="lineno"> 206</span><spanclass="comment">// of the variable in the cut.</span></div>
<divclass="line"><aid="l00208"name="l00208"></a><spanclass="lineno"> 208</span><spanclass="comment">// TODO(user): There is a bunch of heuristic involved here, and we could spend</span></div>
<divclass="line"><aid="l00209"name="l00209"></a><spanclass="lineno"> 209</span><spanclass="comment">// more effort tunning them. In particular, one can try many heuristics and keep</span></div>
<divclass="line"><aid="l00210"name="l00210"></a><spanclass="lineno"> 210</span><spanclass="comment">// the best looking cut (or more than one). This is not on the critical code</span></div>
<divclass="line"><aid="l00211"name="l00211"></a><spanclass="lineno"> 211</span><spanclass="comment">// path, so we can spend more effort in finding good cuts.</span></div>
<divclass="line"><aid="l00222"name="l00222"></a><spanclass="lineno"> 222</span><spanclass="comment">// Returns the number of implied bound lifted Booleans in the last</span></div>
<divclass="line"><aid="l00223"name="l00223"></a><spanclass="lineno"> 223</span><spanclass="comment">// ComputeCut() call. Useful for investigation.</span></div>
<divclass="line"><aid="l00227"name="l00227"></a><spanclass="lineno"> 227</span><spanclass="comment">// The helper is just here to reuse the memory for these vectors.</span></div>
<divclass="line"><aid="l00246"name="l00246"></a><spanclass="lineno"> 246</span><spanclass="comment">// Try to find a cut with a knapsack heuristic.</span></div>
<divclass="line"><aid="l00247"name="l00247"></a><spanclass="lineno"> 247</span><spanclass="comment">// If this returns true, you can get the cut via cut().</span></div>
<divclass="line"><aid="l00253"name="l00253"></a><spanclass="lineno"> 253</span><spanclass="comment">// If successful, info about the last generated cut.</span></div>
<divclass="line"><aid="l00257"name="l00257"></a><spanclass="lineno"> 257</span><spanclass="comment">// Single line of text that we append to the cut log line.</span></div>
<divclass="line"><aid="l00264"name="l00264"></a><spanclass="lineno"> 264</span> IntegerValue positive_coeff; <spanclass="comment">// abs(coeff in original constraint).</span></div>
<divclass="line"><aid="l00274"name="l00274"></a><spanclass="lineno"> 274</span><spanclass="comment">// If a variable is away from its upper bound by more than value 1.0, then it</span></div>
<divclass="line"><aid="l00275"name="l00275"></a><spanclass="lineno"> 275</span><spanclass="comment">// cannot be part of a cover that will violate the lp solution. This method</span></div>
<divclass="line"><aid="l00276"name="l00276"></a><spanclass="lineno"> 276</span><spanclass="comment">// returns a reduced constraint by removing such variables from the given</span></div>
<divclass="line"><aid="l00283"name="l00283"></a><spanclass="lineno"> 283</span><spanclass="comment">// Returns true if sum of all the variables in the given constraint is less than</span></div>
<divclass="line"><aid="l00284"name="l00284"></a><spanclass="lineno"> 284</span><spanclass="comment">// or equal to constraint upper bound. This method assumes that all the</span></div>
<divclass="line"><aid="l00285"name="l00285"></a><spanclass="lineno"> 285</span><spanclass="comment">// coefficients are non negative.</span></div>
<divclass="line"><aid="l00289"name="l00289"></a><spanclass="lineno"> 289</span><spanclass="comment">// If the left variables in lp solution satisfies following inequality, we prove</span></div>
<divclass="line"><aid="l00290"name="l00290"></a><spanclass="lineno"> 290</span><spanclass="comment">// that there does not exist any knapsack cut which is violated by the solution.</span></div>
<divclass="line"><aid="l00291"name="l00291"></a><spanclass="lineno"> 291</span><spanclass="comment">// Let |Cmin| = smallest possible cover size.</span></div>
<divclass="line"><aid="l00292"name="l00292"></a><spanclass="lineno"> 292</span><spanclass="comment">// Let S = smallest (var_ub - lp_values[var]) first |Cmin| variables.</span></div>
<divclass="line"><aid="l00293"name="l00293"></a><spanclass="lineno"> 293</span><spanclass="comment">// Let cut lower bound = sum_(var in S)(var_ub - lp_values[var])</span></div>
<divclass="line"><aid="l00294"name="l00294"></a><spanclass="lineno"> 294</span><spanclass="comment">// For any cover,</span></div>
<divclass="line"><aid="l00295"name="l00295"></a><spanclass="lineno"> 295</span><spanclass="comment">// If cut lower bound >= 1</span></div>
<divclass="line"><aid="l00296"name="l00296"></a><spanclass="lineno"> 296</span><spanclass="comment">// ==> sum_(var in S)(var_ub - lp_values[var]) >= 1</span></div>
<divclass="line"><aid="l00297"name="l00297"></a><spanclass="lineno"> 297</span><spanclass="comment">// ==> sum_(var in cover)(var_ub - lp_values[var]) >= 1</span></div>
<divclass="line"><aid="l00298"name="l00298"></a><spanclass="lineno"> 298</span><spanclass="comment">// ==> The solution already satisfies cover. Since this is true for all covers,</span></div>
<divclass="line"><aid="l00299"name="l00299"></a><spanclass="lineno"> 299</span><spanclass="comment">// this method returns false in such cases.</span></div>
<divclass="line"><aid="l00300"name="l00300"></a><spanclass="lineno"> 300</span><spanclass="comment">// This method assumes that the constraint is preprocessed and has only non</span></div>
<divclass="line"><aid="l00307"name="l00307"></a><spanclass="lineno"> 307</span><spanclass="comment">// Struct to help compute upper bound for knapsack instance.</span></div>
<divclass="line"><aid="l00316"name="l00316"></a><spanclass="lineno"> 316</span><spanclass="comment">// Gets upper bound on profit for knapsack instance by solving the linear</span></div>
<divclass="line"><aid="l00320"name="l00320"></a><spanclass="lineno"> 320</span><spanclass="comment">// Returns true if the linear relaxation upper bound for the knapsack instance</span></div>
<divclass="line"><aid="l00321"name="l00321"></a><spanclass="lineno"> 321</span><spanclass="comment">// shows that this constraint cannot be used to form a cut. This method assumes</span></div>
<divclass="line"><aid="l00322"name="l00322"></a><spanclass="lineno"> 322</span><spanclass="comment">// that all the coefficients are non negative.</span></div>
<divclass="line"><aid="l00328"name="l00328"></a><spanclass="lineno"> 328</span><spanclass="comment">// Returns true if the given constraint passes all the filters described above.</span></div>
<divclass="line"><aid="l00329"name="l00329"></a><spanclass="lineno"> 329</span><spanclass="comment">// This method assumes that the constraint is preprocessed and has only non</span></div>
<divclass="line"><aid="l00336"name="l00336"></a><spanclass="lineno"> 336</span><spanclass="comment">// Converts the given constraint into canonical knapsack form (described</span></div>
<divclass="line"><aid="l00337"name="l00337"></a><spanclass="lineno"> 337</span><spanclass="comment">// below) and adds it to 'knapsack_constraints'.</span></div>
<divclass="line"><aid="l00339"name="l00339"></a><spanclass="lineno"> 339</span><spanclass="comment">// - Constraint has finite upper bound.</span></div>
<divclass="line"><aid="l00340"name="l00340"></a><spanclass="lineno"> 340</span><spanclass="comment">// - All coefficients are positive.</span></div>
<divclass="line"><aid="l00341"name="l00341"></a><spanclass="lineno"> 341</span><spanclass="comment">// For constraint with finite lower bound, this method also adds the negation of</span></div>
<divclass="line"><aid="l00342"name="l00342"></a><spanclass="lineno"> 342</span><spanclass="comment">// the given constraint after converting it to canonical knapsack form.</span></div>
<divclass="line"><aid="l00347"name="l00347"></a><spanclass="lineno"> 347</span><spanclass="comment">// Returns true if the cut is lifted. Lifting procedure is described below.</span></div>
<divclass="line"><aid="l00349"name="l00349"></a><spanclass="lineno"> 349</span><spanclass="comment">// First we decide a lifting sequence for the binary variables which are not</span></div>
<divclass="line"><aid="l00350"name="l00350"></a><spanclass="lineno"> 350</span><spanclass="comment">// already in cut. We lift the cut for each lifting candidate one by one.</span></div>
<divclass="line"><aid="l00352"name="l00352"></a><spanclass="lineno"> 352</span><spanclass="comment">// Given the original constraint where the lifting candidate is fixed to one, we</span></div>
<divclass="line"><aid="l00353"name="l00353"></a><spanclass="lineno"> 353</span><spanclass="comment">// compute the maximum value the cut can take and still be feasible using a</span></div>
<divclass="line"><aid="l00354"name="l00354"></a><spanclass="lineno"> 354</span><spanclass="comment">// knapsack problem. We can then lift the variable in the cut using the</span></div>
<divclass="line"><aid="l00355"name="l00355"></a><spanclass="lineno"> 355</span><spanclass="comment">// difference between the cut upper bound and this maximum value.</span></div>
<divclass="line"><aid="l00363"name="l00363"></a><spanclass="lineno"> 363</span><spanclass="comment">// A cut generator that creates knpasack cover cuts.</span></div>
<divclass="line"><aid="l00367"name="l00367"></a><spanclass="lineno"> 367</span><spanclass="comment">// where x_i are integer variables with upper bound u_i, a cover of size k is a</span></div>
<divclass="line"><aid="l00368"name="l00368"></a><spanclass="lineno"> 368</span><spanclass="comment">// subset C of {1 , .. , n} such that \sum_{c \in C}(a_c * u_c) > b.</span></div>
<divclass="line"><aid="l00370"name="l00370"></a><spanclass="lineno"> 370</span><spanclass="comment">// A knapsack cover cut is a constraint of the form</span></div>
<divclass="line"><aid="l00372"name="l00372"></a><spanclass="lineno"> 372</span><spanclass="comment">// which is equivalent to \sum_{c \in C}(x_c) <= \sum_{c \in C}(u_c) - 1.</span></div>
<divclass="line"><aid="l00373"name="l00373"></a><spanclass="lineno"> 373</span><spanclass="comment">// In other words, in a feasible solution, at least some of the variables do</span></div>
<divclass="line"><aid="l00374"name="l00374"></a><spanclass="lineno"> 374</span><spanclass="comment">// not take their maximum value.</span></div>
<divclass="line"><aid="l00376"name="l00376"></a><spanclass="lineno"> 376</span><spanclass="comment">// If all x_i are binary variables then the cover cut becomes</span></div>
<divclass="line"><aid="l00379"name="l00379"></a><spanclass="lineno"> 379</span><spanclass="comment">// The major difficulty for generating Knapsack cover cuts is finding a minimal</span></div>
<divclass="line"><aid="l00380"name="l00380"></a><spanclass="lineno"> 380</span><spanclass="comment">// cover set C that cut a given floating point solution. There are many ways to</span></div>
<divclass="line"><aid="l00381"name="l00381"></a><spanclass="lineno"> 381</span><spanclass="comment">// heuristically generate the cover but the following method that uses a</span></div>
<divclass="line"><aid="l00382"name="l00382"></a><spanclass="lineno"> 382</span><spanclass="comment">// solution of the LP relaxation of the constraint works the best.</span></div>
<divclass="line"><aid="l00384"name="l00384"></a><spanclass="lineno"> 384</span><spanclass="comment">// Look at a given linear relaxation solution for the integer problem x'</span></div>
<divclass="line"><aid="l00385"name="l00385"></a><spanclass="lineno"> 385</span><spanclass="comment">// and try to solve the following knapsack problem:</span></div>
<divclass="line"><aid="l00387"name="l00387"></a><spanclass="lineno"> 387</span><spanclass="comment">// such that \sum_{i=1..n}(a_i * u_i * z_i) > b,</span></div>
<divclass="line"><aid="l00388"name="l00388"></a><spanclass="lineno"> 388</span><spanclass="comment">// where z_i is a binary decision variable and x_i' are values of the variables</span></div>
<divclass="line"><aid="l00389"name="l00389"></a><spanclass="lineno"> 389</span><spanclass="comment">// in the given relaxation solution x'. If the objective of the optimal solution</span></div>
<divclass="line"><aid="l00390"name="l00390"></a><spanclass="lineno"> 390</span><spanclass="comment">// of this problem is less than 1, this algorithm does not generate any cuts.</span></div>
<divclass="line"><aid="l00391"name="l00391"></a><spanclass="lineno"> 391</span><spanclass="comment">// Otherwise, it adds a knapsack cover cut in the form</span></div>
<divclass="line"><aid="l00393"name="l00393"></a><spanclass="lineno"> 393</span><spanclass="comment">// where z_i' is the value of z_i in the optimal solution of the above</span></div>
<divclass="line"><aid="l00394"name="l00394"></a><spanclass="lineno"> 394</span><spanclass="comment">// problem and cb is the upper bound for the cut constraint. Note that the above</span></div>
<divclass="line"><aid="l00395"name="l00395"></a><spanclass="lineno"> 395</span><spanclass="comment">// problem can be converted into a standard kanpsack form by replacing z_i by 1</span></div>
<divclass="line"><aid="l00396"name="l00396"></a><spanclass="lineno"> 396</span><spanclass="comment">// - y_i. In that case the problem becomes</span></div>
<divclass="line"><aid="l00401"name="l00401"></a><spanclass="lineno"> 401</span><spanclass="comment">// Solving this knapsack instance would help us find the smallest cover with</span></div>
<divclass="line"><aid="l00402"name="l00402"></a><spanclass="lineno"> 402</span><spanclass="comment">// maximum LP violation.</span></div>
<divclass="line"><aid="l00405"name="l00405"></a><spanclass="lineno"> 405</span><spanclass="comment">// Let lambda = \sum_{c \in C}(a_c * u_c) - b and max_coeff = \max_{c</span></div>
<divclass="line"><aid="l00406"name="l00406"></a><spanclass="lineno"> 406</span><spanclass="comment">// \in C}(a_c), then cut can be strengthened as</span></div>
<divclass="line"><aid="l00409"name="l00409"></a><spanclass="lineno"> 409</span><spanclass="comment">// For further information about knapsack cover cuts see</span></div>
<divclass="line"><aid="l00410"name="l00410"></a><spanclass="lineno"> 410</span><spanclass="comment">// A. Atamtürk, Cover and Pack Inequalities for (Mixed) Integer Programming</span></div>
<divclass="line"><aid="l00411"name="l00411"></a><spanclass="lineno"> 411</span><spanclass="comment">// Annals of Operations Research Volume 139, Issue 1 , pp 21-38, 2005.</span></div>
<divclass="line"><aid="l00417"name="l00417"></a><spanclass="lineno"> 417</span><spanclass="comment">// A cut generator for z = x * y (x and y >= 0).</span></div>
<divclass="line"><aid="l00424"name="l00424"></a><spanclass="lineno"> 424</span><spanclass="comment">// A cut generator for y = x ^ 2 (x >= 0).</span></div>
<divclass="line"><aid="l00425"name="l00425"></a><spanclass="lineno"> 425</span><spanclass="comment">// It will dynamically add a linear inequality to push y closer to the parabola.</span></div>
<divclass="line"><aid="l00426"name="l00426"></a><spanclass="lineno"> 426</span>CutGenerator <aclass="code hl_function"href="namespaceoperations__research_1_1sat.html#a91e92ebb8d6c8bd62ae597625f443427">CreateSquareCutGenerator</a>(AffineExpression y, AffineExpression x,</div>
<divclass="line"><aid="l00429"name="l00429"></a><spanclass="lineno"> 429</span><spanclass="comment">// A cut generator for all_diff(xi). Let the united domain of all xi be D. Sum</span></div>
<divclass="line"><aid="l00430"name="l00430"></a><spanclass="lineno"> 430</span><spanclass="comment">// of any k-sized subset of xi need to be greater or equal to the sum of</span></div>
<divclass="line"><aid="l00431"name="l00431"></a><spanclass="lineno"> 431</span><spanclass="comment">// smallest k values in D and lesser or equal to the sum of largest k values in</span></div>
<divclass="line"><aid="l00432"name="l00432"></a><spanclass="lineno"> 432</span><spanclass="comment">// D. The cut generator first sorts the variables based on LP values and adds</span></div>
<divclass="line"><aid="l00433"name="l00433"></a><spanclass="lineno"> 433</span><spanclass="comment">// cuts of the form described above if they are violated by lp solution. Note</span></div>
<divclass="line"><aid="l00434"name="l00434"></a><spanclass="lineno"> 434</span><spanclass="comment">// that all the fixed variables are ignored while generating cuts.</span></div>
<divclass="line"><aid="l00438"name="l00438"></a><spanclass="lineno"> 438</span><spanclass="comment">// Consider the Lin Max constraint with d expressions and n variables in the</span></div>
<divclass="line"><aid="l00439"name="l00439"></a><spanclass="lineno"> 439</span><spanclass="comment">// form: target = max {exprs[k] = Sum (wki * xi + bk)}. k in {1,..,d}.</span></div>
<divclass="line"><aid="l00440"name="l00440"></a><spanclass="lineno"> 440</span><spanclass="comment">// Li = lower bound of xi</span></div>
<divclass="line"><aid="l00441"name="l00441"></a><spanclass="lineno"> 441</span><spanclass="comment">// Ui = upper bound of xi.</span></div>
<divclass="line"><aid="l00442"name="l00442"></a><spanclass="lineno"> 442</span><spanclass="comment">// Let zk be in {0,1} for all k in {1,..,d}.</span></div>
<divclass="line"><aid="l00443"name="l00443"></a><spanclass="lineno"> 443</span><spanclass="comment">// The target = exprs[k] when zk = 1.</span></div>
<divclass="line"><aid="l00445"name="l00445"></a><spanclass="lineno"> 445</span><spanclass="comment">// The following is a valid linearization for Lin Max.</span></div>
<divclass="line"><aid="l00446"name="l00446"></a><spanclass="lineno"> 446</span><spanclass="comment">// target >= exprs[k], for all k in {1,..,d}</span></div>
<divclass="line"><aid="l00447"name="l00447"></a><spanclass="lineno"> 447</span><spanclass="comment">// target <= Sum (wli * xi) + Sum((Nlk + bk) * zk), for all l in {1,..,d}</span></div>
<divclass="line"><aid="l00448"name="l00448"></a><spanclass="lineno"> 448</span><spanclass="comment">// Where Nlk is a large number defined as:</span></div>
<divclass="line"><aid="l00450"name="l00450"></a><spanclass="lineno"> 450</span><spanclass="comment">// = Sum (max corner difference for variable i, target expr l, max expr k)</span></div>
<divclass="line"><aid="l00452"name="l00452"></a><spanclass="lineno"> 452</span><spanclass="comment">// Consider a partition of variables xi into set {1,..,d} as I.</span></div>
<divclass="line"><aid="l00453"name="l00453"></a><spanclass="lineno"> 453</span><spanclass="comment">// i.e. I(i) = j means xi is mapped to jth index.</span></div>
<divclass="line"><aid="l00454"name="l00454"></a><spanclass="lineno"> 454</span><spanclass="comment">// The following inequality is valid and sharp cut for the lin max constraint</span></div>
<divclass="line"><aid="l00455"name="l00455"></a><spanclass="lineno"> 455</span><spanclass="comment">// described above.</span></div>
<divclass="line"><aid="l00461"name="l00461"></a><spanclass="lineno"> 461</span><spanclass="comment">// = max corner difference for variable i,</span></div>
<divclass="line"><aid="l00462"name="l00462"></a><spanclass="lineno"> 462</span><spanclass="comment">// target expr I(i), max expr k.</span></div>
<divclass="line"><aid="l00464"name="l00464"></a><spanclass="lineno"> 464</span><spanclass="comment">// For detailed proof of validity, refer</span></div>
<divclass="line"><aid="l00465"name="l00465"></a><spanclass="lineno"> 465</span><spanclass="comment">// Reference: "Strong mixed-integer programming formulations for trained neural</span></div>
<divclass="line"><aid="l00466"name="l00466"></a><spanclass="lineno"> 466</span><spanclass="comment">// networks" by Ross Anderson et. (https://arxiv.org/pdf/1811.01988.pdf).</span></div>
<divclass="line"><aid="l00468"name="l00468"></a><spanclass="lineno"> 468</span><spanclass="comment">// In the cut generator, we compute the most violated partition I by computing</span></div>
<divclass="line"><aid="l00469"name="l00469"></a><spanclass="lineno"> 469</span><spanclass="comment">// the rhs value (wI(i)i * lp_value(xi) + Sum(k=1..d)(MPlusCoefficient_ki * zk))</span></div>
<divclass="line"><aid="l00470"name="l00470"></a><spanclass="lineno"> 470</span><spanclass="comment">// for each variable for each partition index. We choose the partition index</span></div>
<divclass="line"><aid="l00471"name="l00471"></a><spanclass="lineno"> 471</span><spanclass="comment">// that gives lowest rhs value for a given variable.</span></div>
<divclass="line"><aid="l00473"name="l00473"></a><spanclass="lineno"> 473</span><spanclass="comment">// Note: This cut generator requires all expressions to contain only positive</span></div>
<divclass="line"><aid="l00479"name="l00479"></a><spanclass="lineno"> 479</span><spanclass="comment">// Helper for the affine max constraint.</span></div>
<divclass="line"><aid="l00485"name="l00485"></a><spanclass="lineno"> 485</span><spanclass="comment">// By definition, the Max of affine functions is convex. The linear polytope is</span></div>
<divclass="line"><aid="l00486"name="l00486"></a><spanclass="lineno"> 486</span><spanclass="comment">// bounded by all affine functions on the bottom, and by a single hyperplane</span></div>
<divclass="line"><aid="l00487"name="l00487"></a><spanclass="lineno"> 487</span><spanclass="comment">// that join the two points at the extreme of the var domain, and their y-values</span></div>
<divclass="line"><aid="l00488"name="l00488"></a><spanclass="lineno"> 488</span><spanclass="comment">// of the max of the affine functions.</span></div>
<divclass="line"><aid="l00494"name="l00494"></a><spanclass="lineno"> 494</span><spanclass="comment">// Extracts the variables that have a Literal view from base variables and</span></div>
<divclass="line"><aid="l00495"name="l00495"></a><spanclass="lineno"> 495</span><spanclass="comment">// create a generator that will returns constraint of the form "at_most_one"</span></div>
<divclass="line"><aid="l00496"name="l00496"></a><spanclass="lineno"> 496</span><spanclass="comment">// between such literals.</span></div>
<divclass="ttc"id="aclassoperations__research_1_1_time_limit_html"><divclass="ttname"><ahref="classoperations__research_1_1_time_limit.html">operations_research::TimeLimit</a></div><divclass="ttdoc">A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...</div><divclass="ttdef"><b>Definition:</b><ahref="time__limit_8h_source.html#l00106">time_limit.h:106</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_cover_cut_helper_html_a4dbdfea287fc5d8f740860d985499645"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_cover_cut_helper.html#a4dbdfea287fc5d8f740860d985499645">operations_research::sat::CoverCutHelper::cut</a></div><divclass="ttdeci">const LinearConstraint & cut() const</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8h_source.html#l00255">cuts.h:255</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_implied_bounds_processor_html_a25ce3a542ac1e183148844cb649069fd"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_implied_bounds_processor.html#a25ce3a542ac1e183148844cb649069fd">operations_research::sat::ImpliedBoundsProcessor::IbCutPool</a></div><divclass="ttdeci">TopNCuts & IbCutPool()</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8h_source.html#l00128">cuts.h:128</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_1_1sat_html_a86a16fa3180f4ebc8ac36c16a2b49fac"><divclass="ttname"><ahref="namespaceoperations__research_1_1sat.html#a86a16fa3180f4ebc8ac36c16a2b49fac">operations_research::sat::CreatePositiveMultiplicationCutGenerator</a></div><divclass="ttdeci">CutGenerator CreatePositiveMultiplicationCutGenerator(AffineExpression z, AffineExpression x, AffineExpression y, int linearization_level, Model *model)</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8cc_source.html#l01348">cuts.cc:1348</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_1_1sat_html_a88fabb0f851ff07d459b8be401162601"><divclass="ttname"><ahref="namespaceoperations__research_1_1sat.html#a88fabb0f851ff07d459b8be401162601">operations_research::sat::BuildMaxAffineUpConstraint</a></div><divclass="ttdeci">LinearConstraint BuildMaxAffineUpConstraint(const LinearExpression &target, IntegerVariable var, const std::vector< std::pair< IntegerValue, IntegerValue >>&affines, Model *model)</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8cc_source.html#l02054">cuts.cc:2054</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_1_1sat_html_a91e92ebb8d6c8bd62ae597625f443427"><divclass="ttname"><ahref="namespaceoperations__research_1_1sat.html#a91e92ebb8d6c8bd62ae597625f443427">operations_research::sat::CreateSquareCutGenerator</a></div><divclass="ttdeci">CutGenerator CreateSquareCutGenerator(AffineExpression y, AffineExpression x, int linearization_level, Model *model)</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8cc_source.html#l01437">cuts.cc:1437</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_1_1sat_html_ab782d6f91aefca5ee81c3b622e862875"><divclass="ttname"><ahref="namespaceoperations__research_1_1sat.html#ab782d6f91aefca5ee81c3b622e862875">operations_research::sat::CreateMaxAffineCutGenerator</a></div><divclass="ttdeci">CutGenerator CreateMaxAffineCutGenerator(LinearExpression target, IntegerVariable var, std::vector< std::pair< IntegerValue, IntegerValue >> affines, const std::string cut_name, Model *model)</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8cc_source.html#l02090">cuts.cc:2090</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_1_1sat_html_adf176ac81e34e8fd124d823ee0033f1a"><divclass="ttname"><ahref="namespaceoperations__research_1_1sat.html#adf176ac81e34e8fd124d823ee0033f1a">operations_research::sat::CreateCliqueCutGenerator</a></div><divclass="ttdeci">CutGenerator CreateCliqueCutGenerator(const std::vector< IntegerVariable >&base_variables, Model *model)</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8cc_source.html#l02112">cuts.cc:2112</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_html"><divclass="ttname"><ahref="namespaceoperations__research.html">operations_research</a></div><divclass="ttdoc">Collection of objects used to extend the Constraint Solver library.</div><divclass="ttdef"><b>Definition:</b><ahref="dense__doubly__linked__list_8h_source.html#l00021">dense_doubly_linked_list.h:21</a></div></div>