<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="l00039"name="l00039"></a><spanclass="lineno"> 39</span><spanclass="comment">// A "cut" generator on a set of IntegerVariable.</span></div>
<divclass="line"><aid="l00041"name="l00041"></a><spanclass="lineno"> 41</span><spanclass="comment">// The generate_cuts() function will usually be called with the current LP</span></div>
<divclass="line"><aid="l00042"name="l00042"></a><spanclass="lineno"> 42</span><spanclass="comment">// optimal solution (but should work for any lp_values). Note that a</span></div>
<divclass="line"><aid="l00044"name="l00044"></a><spanclass="lineno"> 44</span><spanclass="comment">// - Only look at the lp_values positions that corresponds to its 'vars' or</span></div>
<divclass="line"><aid="l00045"name="l00045"></a><spanclass="lineno"> 45</span><spanclass="comment">// their negation.</span></div>
<divclass="line"><aid="l00046"name="l00046"></a><spanclass="lineno"> 46</span><spanclass="comment">// - Only add cuts in term of the same variables or their negation.</span></div>
<divclass="line"><aid="l00055"name="l00055"></a><spanclass="lineno"> 55</span><spanclass="comment">// Given an upper-bounded linear relation (sum terms <= ub), this algorithm</span></div>
<divclass="line"><aid="l00056"name="l00056"></a><spanclass="lineno"> 56</span><spanclass="comment">// inspects the integer variable appearing in the sum and try to replace each of</span></div>
<divclass="line"><aid="l00057"name="l00057"></a><spanclass="lineno"> 57</span><spanclass="comment">// them by a tight lower bound (>= coeff * binary + lb) using the implied bound</span></div>
<divclass="line"><aid="l00058"name="l00058"></a><spanclass="lineno"> 58</span><spanclass="comment">// repository. By tight, we mean that it will take the same value under the</span></div>
<divclass="line"><aid="l00059"name="l00059"></a><spanclass="lineno"> 59</span><spanclass="comment">// current LP solution.</span></div>
<divclass="line"><aid="l00061"name="l00061"></a><spanclass="lineno"> 61</span><spanclass="comment">// We use a class to reuse memory of the tmp terms.</span></div>
<divclass="line"><aid="l00064"name="l00064"></a><spanclass="lineno"> 64</span><spanclass="comment">// We will only replace IntegerVariable appearing in lp_vars_.</span></div>
<divclass="line"><aid="l00072"name="l00072"></a><spanclass="lineno"> 72</span><spanclass="comment">// See if some of the implied bounds equation are violated and add them to</span></div>
<divclass="line"><aid="l00073"name="l00073"></a><spanclass="lineno"> 73</span><spanclass="comment">// the IB cut pool if it is the case.</span></div>
<divclass="line"><aid="l00075"name="l00075"></a><spanclass="lineno"> 75</span><spanclass="comment">// Important: This must be called before we process any constraints with a</span></div>
<divclass="line"><aid="l00076"name="l00076"></a><spanclass="lineno"> 76</span><spanclass="comment">// different lp_values or level zero bounds.</span></div>
<divclass="line"><aid="l00080"name="l00080"></a><spanclass="lineno"> 80</span><spanclass="comment">// Processes and updates the given cut.</span></div>
<divclass="line"><aid="l00085"name="l00085"></a><spanclass="lineno"> 85</span><spanclass="comment">// Same as ProcessUpperBoundedConstraint() but instead of just using</span></div>
<divclass="line"><aid="l00086"name="l00086"></a><spanclass="lineno"> 86</span><spanclass="comment">// var >= coeff * binary + lb we use var == slack + coeff * binary + lb where</span></div>
<divclass="line"><aid="l00087"name="l00087"></a><spanclass="lineno"> 87</span><spanclass="comment">// slack is a new temporary variable that we create.</span></div>
<divclass="line"><aid="l00089"name="l00089"></a><spanclass="lineno"> 89</span><spanclass="comment">// The new slack will be such that slack_infos[(slack - first_slack) / 2]</span></div>
<divclass="line"><aid="l00090"name="l00090"></a><spanclass="lineno"> 90</span><spanclass="comment">// contains its definition so that we can properly handle it in the cut</span></div>
<divclass="line"><aid="l00091"name="l00091"></a><spanclass="lineno"> 91</span><spanclass="comment">// generation and substitute it back later.</span></div>
<divclass="line"><aid="l00093"name="l00093"></a><spanclass="lineno"> 93</span><spanclass="comment">// This slack is equal to sum of terms + offset.</span></div>
<divclass="line"><aid="l00097"name="l00097"></a><spanclass="lineno"> 97</span><spanclass="comment">// The slack bounds and current lp_value.</span></div>
<divclass="line"><aid="l00109"name="l00109"></a><spanclass="lineno"> 109</span><spanclass="comment">// Substituting back the slack created by the function above should give</span></div>
<divclass="line"><aid="l00110"name="l00110"></a><spanclass="lineno"> 110</span><spanclass="comment">// exactly the same cut as the original one.</span></div>
<divclass="line"><aid="l00116"name="l00116"></a><spanclass="lineno"> 116</span><spanclass="comment">// Add a new variable that could be used in the new cuts.</span></div>
<divclass="line"><aid="l00117"name="l00117"></a><spanclass="lineno"> 117</span><spanclass="comment">// Note that the cache must be computed to take this into account.</span></div>
<divclass="line"><aid="l00120"name="l00120"></a><spanclass="lineno"> 120</span><spanclass="comment">// Once RecomputeCacheAndSeparateSomeImpliedBoundCuts() has been called,</span></div>
<divclass="line"><aid="l00121"name="l00121"></a><spanclass="lineno"> 121</span><spanclass="comment">// we can get the best implied bound for each variables.</span></div>
<divclass="line"><aid="l00131"name="l00131"></a><spanclass="lineno"> 131</span><spanclass="comment">// As we compute the best implied bounds for each variable, we add violated</span></div>
<divclass="line"><aid="l00149"name="l00149"></a><spanclass="lineno"> 149</span><spanclass="comment">// Temporary memory used by ProcessUpperBoundedConstraint().</span></div>
<divclass="line"><aid="l00153"name="l00153"></a><spanclass="lineno"> 153</span><spanclass="comment">// Visible for testing. Returns a function f on integers such that:</span></div>
<divclass="line"><aid="l00154"name="l00154"></a><spanclass="lineno"> 154</span><spanclass="comment">// - f is non-decreasing.</span></div>
<divclass="line"><aid="l00155"name="l00155"></a><spanclass="lineno"> 155</span><spanclass="comment">// - f is super-additive: f(a) + f(b) <= f(a + b)</span></div>
<divclass="line"><aid="l00157"name="l00157"></a><spanclass="lineno"> 157</span><spanclass="comment">// - For all x, f(x * divisor) = x * f(divisor)</span></div>
<divclass="line"><aid="l00158"name="l00158"></a><spanclass="lineno"> 158</span><spanclass="comment">// - For all x, f(x * divisor + remainder) = x * f(divisor)</span></div>
<divclass="line"><aid="l00164"name="l00164"></a><spanclass="lineno"> 164</span><spanclass="comment">// This is used in IntegerRoundingCut() and is responsible for "strengthening"</span></div>
<divclass="line"><aid="l00165"name="l00165"></a><spanclass="lineno"> 165</span><spanclass="comment">// the cut. Just taking f(x) = x / divisor result in the non-strengthened cut</span></div>
<divclass="line"><aid="l00166"name="l00166"></a><spanclass="lineno"> 166</span><spanclass="comment">// and using any function that stricly dominate this one is better.</span></div>
<divclass="line"><aid="l00169"name="l00169"></a><spanclass="lineno"> 169</span><spanclass="comment">// - We first scale by a factor t so that rhs_remainder >= divisor / 2.</span></div>
<divclass="line"><aid="l00170"name="l00170"></a><spanclass="lineno"> 170</span><spanclass="comment">// - Then, if max_scaling == 2, we use the function described</span></div>
<divclass="line"><aid="l00171"name="l00171"></a><spanclass="lineno"> 171</span><spanclass="comment">// in "Strenghtening Chvatal-Gomory cuts and Gomory fractional cuts", Adam N.</span></div>
<divclass="line"><aid="l00172"name="l00172"></a><spanclass="lineno"> 172</span><spanclass="comment">// Letchfrod, Andrea Lodi.</span></div>
<divclass="line"><aid="l00173"name="l00173"></a><spanclass="lineno"> 173</span><spanclass="comment">// - Otherwise, we use a generalization of this which is a discretized version</span></div>
<divclass="line"><aid="l00174"name="l00174"></a><spanclass="lineno"> 174</span><spanclass="comment">// of the classical MIR rounding function that only take the value of the</span></div>
<divclass="line"><aid="l00175"name="l00175"></a><spanclass="lineno"> 175</span><spanclass="comment">// form "an_integer / max_scaling". As max_scaling goes to infinity, this</span></div>
<divclass="line"><aid="l00176"name="l00176"></a><spanclass="lineno"> 176</span><spanclass="comment">// converge to the real-valued MIR function.</span></div>
<divclass="line"><aid="l00178"name="l00178"></a><spanclass="lineno"> 178</span><spanclass="comment">// Note that for each value of max_scaling we will get a different function.</span></div>
<divclass="line"><aid="l00179"name="l00179"></a><spanclass="lineno"> 179</span><spanclass="comment">// And that there is no dominance relation between any of these functions. So</span></div>
<divclass="line"><aid="l00180"name="l00180"></a><spanclass="lineno"> 180</span><spanclass="comment">// it could be nice to try to generate a cut using different values of</span></div>
<divclass="line"><aid="l00188"name="l00188"></a><spanclass="lineno"> 188</span><spanclass="comment">// Given an upper bounded linear constraint, this function tries to transform it</span></div>
<divclass="line"><aid="l00189"name="l00189"></a><spanclass="lineno"> 189</span><spanclass="comment">// to a valid cut that violate the given LP solution using integer rounding.</span></div>
<divclass="line"><aid="l00190"name="l00190"></a><spanclass="lineno"> 190</span><spanclass="comment">// Note that the returned cut might not always violate the LP solution, in which</span></div>
<divclass="line"><aid="l00191"name="l00191"></a><spanclass="lineno"> 191</span><spanclass="comment">// case it can be discarded.</span></div>
<divclass="line"><aid="l00193"name="l00193"></a><spanclass="lineno"> 193</span><spanclass="comment">// What this does is basically take the integer division of the constraint by an</span></div>
<divclass="line"><aid="l00194"name="l00194"></a><spanclass="lineno"> 194</span><spanclass="comment">// integer. If the coefficients where doubles, this would be the same as scaling</span></div>
<divclass="line"><aid="l00195"name="l00195"></a><spanclass="lineno"> 195</span><spanclass="comment">// the constraint and then rounding. We choose the coefficient of the most</span></div>
<divclass="line"><aid="l00196"name="l00196"></a><spanclass="lineno"> 196</span><spanclass="comment">// fractional variable (rescaled by its coefficient) as the divisor, but there</span></div>
<divclass="line"><aid="l00197"name="l00197"></a><spanclass="lineno"> 197</span><spanclass="comment">// are other possible alternatives.</span></div>
<divclass="line"><aid="l00199"name="l00199"></a><spanclass="lineno"> 199</span><spanclass="comment">// Note that if the constraint is tight under the given lp solution, and if</span></div>
<divclass="line"><aid="l00200"name="l00200"></a><spanclass="lineno"> 200</span><spanclass="comment">// there is a unique variable not at one of its bounds and fractional, then we</span></div>
<divclass="line"><aid="l00201"name="l00201"></a><spanclass="lineno"> 201</span><spanclass="comment">// are guaranteed to generate a cut that violate the current LP solution. This</span></div>
<divclass="line"><aid="l00202"name="l00202"></a><spanclass="lineno"> 202</span><spanclass="comment">// should be the case for Chvatal-Gomory base constraints modulo our loss of</span></div>
<divclass="line"><aid="l00203"name="l00203"></a><spanclass="lineno"> 203</span><spanclass="comment">// precision while doing exact integer computations.</span></div>
<divclass="line"><aid="l00206"name="l00206"></a><spanclass="lineno"> 206</span><spanclass="comment">// - We assumes that the given initial constraint is tight using the given lp</span></div>
<divclass="line"><aid="l00207"name="l00207"></a><spanclass="lineno"> 207</span><spanclass="comment">// values. This could be relaxed, but for now it should always be the case, so</span></div>
<divclass="line"><aid="l00208"name="l00208"></a><spanclass="lineno"> 208</span><spanclass="comment">// we log a message and abort if not, to ease debugging.</span></div>
<divclass="line"><aid="l00209"name="l00209"></a><spanclass="lineno"> 209</span><spanclass="comment">// - The IntegerVariable of the cuts are not used here. We assumes that the</span></div>
<divclass="line"><aid="l00210"name="l00210"></a><spanclass="lineno"> 210</span><spanclass="comment">// first three vectors are in one to one correspondence with the initial order</span></div>
<divclass="line"><aid="l00211"name="l00211"></a><spanclass="lineno"> 211</span><spanclass="comment">// of the variable in the cut.</span></div>
<divclass="line"><aid="l00213"name="l00213"></a><spanclass="lineno"> 213</span><spanclass="comment">// TODO(user): There is a bunch of heuristic involved here, and we could spend</span></div>
<divclass="line"><aid="l00214"name="l00214"></a><spanclass="lineno"> 214</span><spanclass="comment">// more effort tunning them. In particular, one can try many heuristics and keep</span></div>
<divclass="line"><aid="l00215"name="l00215"></a><spanclass="lineno"> 215</span><spanclass="comment">// the best looking cut (or more than one). This is not on the critical code</span></div>
<divclass="line"><aid="l00216"name="l00216"></a><spanclass="lineno"> 216</span><spanclass="comment">// path, so we can spend more effort in finding good cuts.</span></div>
<divclass="line"><aid="l00227"name="l00227"></a><spanclass="lineno"> 227</span><spanclass="comment">// Returns the number of implied bound lifted Booleans in the last</span></div>
<divclass="line"><aid="l00228"name="l00228"></a><spanclass="lineno"> 228</span><spanclass="comment">// ComputeCut() call. Useful for investigation.</span></div>
<divclass="line"><aid="l00232"name="l00232"></a><spanclass="lineno"> 232</span><spanclass="comment">// The helper is just here to reuse the memory for these vectors.</span></div>
<divclass="line"><aid="l00251"name="l00251"></a><spanclass="lineno"> 251</span><spanclass="comment">// Try to find a cut with a knapsack heuristic.</span></div>
<divclass="line"><aid="l00252"name="l00252"></a><spanclass="lineno"> 252</span><spanclass="comment">// If this returns true, you can get the cut via cut().</span></div>
<divclass="line"><aid="l00258"name="l00258"></a><spanclass="lineno"> 258</span><spanclass="comment">// If successful, info about the last generated cut.</span></div>
<divclass="line"><aid="l00262"name="l00262"></a><spanclass="lineno"> 262</span><spanclass="comment">// Single line of text that we append to the cut log line.</span></div>
<divclass="line"><aid="l00269"name="l00269"></a><spanclass="lineno"> 269</span> IntegerValue positive_coeff; <spanclass="comment">// abs(coeff in original constraint).</span></div>
<divclass="line"><aid="l00279"name="l00279"></a><spanclass="lineno"> 279</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="l00280"name="l00280"></a><spanclass="lineno"> 280</span><spanclass="comment">// cannot be part of a cover that will violate the lp solution. This method</span></div>
<divclass="line"><aid="l00281"name="l00281"></a><spanclass="lineno"> 281</span><spanclass="comment">// returns a reduced constraint by removing such variables from the given</span></div>
<divclass="line"><aid="l00288"name="l00288"></a><spanclass="lineno"> 288</span><spanclass="comment">// Returns true if sum of all the variables in the given constraint is less than</span></div>
<divclass="line"><aid="l00289"name="l00289"></a><spanclass="lineno"> 289</span><spanclass="comment">// or equal to constraint upper bound. This method assumes that all the</span></div>
<divclass="line"><aid="l00290"name="l00290"></a><spanclass="lineno"> 290</span><spanclass="comment">// coefficients are non negative.</span></div>
<divclass="line"><aid="l00294"name="l00294"></a><spanclass="lineno"> 294</span><spanclass="comment">// If the left variables in lp solution satisfies following inequality, we prove</span></div>
<divclass="line"><aid="l00295"name="l00295"></a><spanclass="lineno"> 295</span><spanclass="comment">// that there does not exist any knapsack cut which is violated by the solution.</span></div>
<divclass="line"><aid="l00296"name="l00296"></a><spanclass="lineno"> 296</span><spanclass="comment">// Let |Cmin| = smallest possible cover size.</span></div>
<divclass="line"><aid="l00297"name="l00297"></a><spanclass="lineno"> 297</span><spanclass="comment">// Let S = smallest (var_ub - lp_values[var]) first |Cmin| variables.</span></div>
<divclass="line"><aid="l00298"name="l00298"></a><spanclass="lineno"> 298</span><spanclass="comment">// Let cut lower bound = sum_(var in S)(var_ub - lp_values[var])</span></div>
<divclass="line"><aid="l00299"name="l00299"></a><spanclass="lineno"> 299</span><spanclass="comment">// For any cover,</span></div>
<divclass="line"><aid="l00300"name="l00300"></a><spanclass="lineno"> 300</span><spanclass="comment">// If cut lower bound >= 1</span></div>
<divclass="line"><aid="l00301"name="l00301"></a><spanclass="lineno"> 301</span><spanclass="comment">// ==> sum_(var in S)(var_ub - lp_values[var]) >= 1</span></div>
<divclass="line"><aid="l00302"name="l00302"></a><spanclass="lineno"> 302</span><spanclass="comment">// ==> sum_(var in cover)(var_ub - lp_values[var]) >= 1</span></div>
<divclass="line"><aid="l00303"name="l00303"></a><spanclass="lineno"> 303</span><spanclass="comment">// ==> The solution already satisfies cover. Since this is true for all covers,</span></div>
<divclass="line"><aid="l00304"name="l00304"></a><spanclass="lineno"> 304</span><spanclass="comment">// this method returns false in such cases.</span></div>
<divclass="line"><aid="l00305"name="l00305"></a><spanclass="lineno"> 305</span><spanclass="comment">// This method assumes that the constraint is preprocessed and has only non</span></div>
<divclass="line"><aid="l00312"name="l00312"></a><spanclass="lineno"> 312</span><spanclass="comment">// Struct to help compute upper bound for knapsack instance.</span></div>
<divclass="line"><aid="l00321"name="l00321"></a><spanclass="lineno"> 321</span><spanclass="comment">// Gets upper bound on profit for knapsack instance by solving the linear</span></div>
<divclass="line"><aid="l00325"name="l00325"></a><spanclass="lineno"> 325</span><spanclass="comment">// Returns true if the linear relaxation upper bound for the knapsack instance</span></div>
<divclass="line"><aid="l00326"name="l00326"></a><spanclass="lineno"> 326</span><spanclass="comment">// shows that this constraint cannot be used to form a cut. This method assumes</span></div>
<divclass="line"><aid="l00327"name="l00327"></a><spanclass="lineno"> 327</span><spanclass="comment">// that all the coefficients are non negative.</span></div>
<divclass="line"><aid="l00333"name="l00333"></a><spanclass="lineno"> 333</span><spanclass="comment">// Returns true if the given constraint passes all the filters described above.</span></div>
<divclass="line"><aid="l00334"name="l00334"></a><spanclass="lineno"> 334</span><spanclass="comment">// This method assumes that the constraint is preprocessed and has only non</span></div>
<divclass="line"><aid="l00341"name="l00341"></a><spanclass="lineno"> 341</span><spanclass="comment">// Converts the given constraint into canonical knapsack form (described</span></div>
<divclass="line"><aid="l00342"name="l00342"></a><spanclass="lineno"> 342</span><spanclass="comment">// below) and adds it to 'knapsack_constraints'.</span></div>
<divclass="line"><aid="l00344"name="l00344"></a><spanclass="lineno"> 344</span><spanclass="comment">// - Constraint has finite upper bound.</span></div>
<divclass="line"><aid="l00345"name="l00345"></a><spanclass="lineno"> 345</span><spanclass="comment">// - All coefficients are positive.</span></div>
<divclass="line"><aid="l00346"name="l00346"></a><spanclass="lineno"> 346</span><spanclass="comment">// For constraint with finite lower bound, this method also adds the negation of</span></div>
<divclass="line"><aid="l00347"name="l00347"></a><spanclass="lineno"> 347</span><spanclass="comment">// the given constraint after converting it to canonical knapsack form.</span></div>
<divclass="line"><aid="l00352"name="l00352"></a><spanclass="lineno"> 352</span><spanclass="comment">// Returns true if the cut is lifted. Lifting procedure is described below.</span></div>
<divclass="line"><aid="l00354"name="l00354"></a><spanclass="lineno"> 354</span><spanclass="comment">// First we decide a lifting sequence for the binary variables which are not</span></div>
<divclass="line"><aid="l00355"name="l00355"></a><spanclass="lineno"> 355</span><spanclass="comment">// already in cut. We lift the cut for each lifting candidate one by one.</span></div>
<divclass="line"><aid="l00357"name="l00357"></a><spanclass="lineno"> 357</span><spanclass="comment">// Given the original constraint where the lifting candidate is fixed to one, we</span></div>
<divclass="line"><aid="l00358"name="l00358"></a><spanclass="lineno"> 358</span><spanclass="comment">// compute the maximum value the cut can take and still be feasible using a</span></div>
<divclass="line"><aid="l00359"name="l00359"></a><spanclass="lineno"> 359</span><spanclass="comment">// knapsack problem. We can then lift the variable in the cut using the</span></div>
<divclass="line"><aid="l00360"name="l00360"></a><spanclass="lineno"> 360</span><spanclass="comment">// difference between the cut upper bound and this maximum value.</span></div>
<divclass="line"><aid="l00368"name="l00368"></a><spanclass="lineno"> 368</span><spanclass="comment">// A cut generator that creates knpasack cover cuts.</span></div>
<divclass="line"><aid="l00372"name="l00372"></a><spanclass="lineno"> 372</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="l00373"name="l00373"></a><spanclass="lineno"> 373</span><spanclass="comment">// subset C of {1 , .. , n} such that \sum_{c \in C}(a_c * u_c) > b.</span></div>
<divclass="line"><aid="l00375"name="l00375"></a><spanclass="lineno"> 375</span><spanclass="comment">// A knapsack cover cut is a constraint of the form</span></div>
<divclass="line"><aid="l00377"name="l00377"></a><spanclass="lineno"> 377</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="l00378"name="l00378"></a><spanclass="lineno"> 378</span><spanclass="comment">// In other words, in a feasible solution, at least some of the variables do</span></div>
<divclass="line"><aid="l00379"name="l00379"></a><spanclass="lineno"> 379</span><spanclass="comment">// not take their maximum value.</span></div>
<divclass="line"><aid="l00381"name="l00381"></a><spanclass="lineno"> 381</span><spanclass="comment">// If all x_i are binary variables then the cover cut becomes</span></div>
<divclass="line"><aid="l00384"name="l00384"></a><spanclass="lineno"> 384</span><spanclass="comment">// The major difficulty for generating Knapsack cover cuts is finding a minimal</span></div>
<divclass="line"><aid="l00385"name="l00385"></a><spanclass="lineno"> 385</span><spanclass="comment">// cover set C that cut a given floating point solution. There are many ways to</span></div>
<divclass="line"><aid="l00386"name="l00386"></a><spanclass="lineno"> 386</span><spanclass="comment">// heuristically generate the cover but the following method that uses a</span></div>
<divclass="line"><aid="l00387"name="l00387"></a><spanclass="lineno"> 387</span><spanclass="comment">// solution of the LP relaxation of the constraint works the best.</span></div>
<divclass="line"><aid="l00389"name="l00389"></a><spanclass="lineno"> 389</span><spanclass="comment">// Look at a given linear relaxation solution for the integer problem x'</span></div>
<divclass="line"><aid="l00390"name="l00390"></a><spanclass="lineno"> 390</span><spanclass="comment">// and try to solve the following knapsack problem:</span></div>
<divclass="line"><aid="l00392"name="l00392"></a><spanclass="lineno"> 392</span><spanclass="comment">// such that \sum_{i=1..n}(a_i * u_i * z_i) > b,</span></div>
<divclass="line"><aid="l00393"name="l00393"></a><spanclass="lineno"> 393</span><spanclass="comment">// where z_i is a binary decision variable and x_i' are values of the variables</span></div>
<divclass="line"><aid="l00394"name="l00394"></a><spanclass="lineno"> 394</span><spanclass="comment">// in the given relaxation solution x'. If the objective of the optimal solution</span></div>
<divclass="line"><aid="l00395"name="l00395"></a><spanclass="lineno"> 395</span><spanclass="comment">// of this problem is less than 1, this algorithm does not generate any cuts.</span></div>
<divclass="line"><aid="l00396"name="l00396"></a><spanclass="lineno"> 396</span><spanclass="comment">// Otherwise, it adds a knapsack cover cut in the form</span></div>
<divclass="line"><aid="l00398"name="l00398"></a><spanclass="lineno"> 398</span><spanclass="comment">// where z_i' is the value of z_i in the optimal solution of the above</span></div>
<divclass="line"><aid="l00399"name="l00399"></a><spanclass="lineno"> 399</span><spanclass="comment">// problem and cb is the upper bound for the cut constraint. Note that the above</span></div>
<divclass="line"><aid="l00400"name="l00400"></a><spanclass="lineno"> 400</span><spanclass="comment">// problem can be converted into a standard kanpsack form by replacing z_i by 1</span></div>
<divclass="line"><aid="l00401"name="l00401"></a><spanclass="lineno"> 401</span><spanclass="comment">// - y_i. In that case the problem becomes</span></div>
<divclass="line"><aid="l00406"name="l00406"></a><spanclass="lineno"> 406</span><spanclass="comment">// Solving this knapsack instance would help us find the smallest cover with</span></div>
<divclass="line"><aid="l00407"name="l00407"></a><spanclass="lineno"> 407</span><spanclass="comment">// maximum LP violation.</span></div>
<divclass="line"><aid="l00410"name="l00410"></a><spanclass="lineno"> 410</span><spanclass="comment">// Let lambda = \sum_{c \in C}(a_c * u_c) - b and max_coeff = \max_{c</span></div>
<divclass="line"><aid="l00411"name="l00411"></a><spanclass="lineno"> 411</span><spanclass="comment">// \in C}(a_c), then cut can be strengthened as</span></div>
<divclass="line"><aid="l00414"name="l00414"></a><spanclass="lineno"> 414</span><spanclass="comment">// For further information about knapsack cover cuts see</span></div>
<divclass="line"><aid="l00415"name="l00415"></a><spanclass="lineno"> 415</span><spanclass="comment">// A. Atamtürk, Cover and Pack Inequalities for (Mixed) Integer Programming</span></div>
<divclass="line"><aid="l00416"name="l00416"></a><spanclass="lineno"> 416</span><spanclass="comment">// Annals of Operations Research Volume 139, Issue 1 , pp 21-38, 2005.</span></div>
<divclass="line"><aid="l00422"name="l00422"></a><spanclass="lineno"> 422</span><spanclass="comment">// A cut generator for z = x * y (x and y >= 0).</span></div>
<divclass="line"><aid="l00429"name="l00429"></a><spanclass="lineno"> 429</span><spanclass="comment">// A cut generator for y = x ^ 2 (x >= 0).</span></div>
<divclass="line"><aid="l00430"name="l00430"></a><spanclass="lineno"> 430</span><spanclass="comment">// It will dynamically add a linear inequality to push y closer to the parabola.</span></div>
<divclass="line"><aid="l00431"name="l00431"></a><spanclass="lineno"> 431</span>CutGenerator <aclass="code hl_function"href="namespaceoperations__research_1_1sat.html#a91e92ebb8d6c8bd62ae597625f443427">CreateSquareCutGenerator</a>(AffineExpression y, AffineExpression x,</div>
<divclass="line"><aid="l00434"name="l00434"></a><spanclass="lineno"> 434</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="l00435"name="l00435"></a><spanclass="lineno"> 435</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="l00436"name="l00436"></a><spanclass="lineno"> 436</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="l00437"name="l00437"></a><spanclass="lineno"> 437</span><spanclass="comment">// D. The cut generator first sorts the variables based on LP values and adds</span></div>
<divclass="line"><aid="l00438"name="l00438"></a><spanclass="lineno"> 438</span><spanclass="comment">// cuts of the form described above if they are violated by lp solution. Note</span></div>
<divclass="line"><aid="l00439"name="l00439"></a><spanclass="lineno"> 439</span><spanclass="comment">// that all the fixed variables are ignored while generating cuts.</span></div>
<divclass="line"><aid="l00443"name="l00443"></a><spanclass="lineno"> 443</span><spanclass="comment">// Consider the Lin Max constraint with d expressions and n variables in the</span></div>
<divclass="line"><aid="l00444"name="l00444"></a><spanclass="lineno"> 444</span><spanclass="comment">// form: target = max {exprs[k] = Sum (wki * xi + bk)}. k in {1,..,d}.</span></div>
<divclass="line"><aid="l00445"name="l00445"></a><spanclass="lineno"> 445</span><spanclass="comment">// Li = lower bound of xi</span></div>
<divclass="line"><aid="l00446"name="l00446"></a><spanclass="lineno"> 446</span><spanclass="comment">// Ui = upper bound of xi.</span></div>
<divclass="line"><aid="l00447"name="l00447"></a><spanclass="lineno"> 447</span><spanclass="comment">// Let zk be in {0,1} for all k in {1,..,d}.</span></div>
<divclass="line"><aid="l00448"name="l00448"></a><spanclass="lineno"> 448</span><spanclass="comment">// The target = exprs[k] when zk = 1.</span></div>
<divclass="line"><aid="l00450"name="l00450"></a><spanclass="lineno"> 450</span><spanclass="comment">// The following is a valid linearization for Lin Max.</span></div>
<divclass="line"><aid="l00451"name="l00451"></a><spanclass="lineno"> 451</span><spanclass="comment">// target >= exprs[k], for all k in {1,..,d}</span></div>
<divclass="line"><aid="l00452"name="l00452"></a><spanclass="lineno"> 452</span><spanclass="comment">// target <= Sum (wli * xi) + Sum((Nlk + bk) * zk), for all l in {1,..,d}</span></div>
<divclass="line"><aid="l00453"name="l00453"></a><spanclass="lineno"> 453</span><spanclass="comment">// Where Nlk is a large number defined as:</span></div>
<divclass="line"><aid="l00455"name="l00455"></a><spanclass="lineno"> 455</span><spanclass="comment">// = Sum (max corner difference for variable i, target expr l, max expr k)</span></div>
<divclass="line"><aid="l00457"name="l00457"></a><spanclass="lineno"> 457</span><spanclass="comment">// Consider a partition of variables xi into set {1,..,d} as I.</span></div>
<divclass="line"><aid="l00458"name="l00458"></a><spanclass="lineno"> 458</span><spanclass="comment">// i.e. I(i) = j means xi is mapped to jth index.</span></div>
<divclass="line"><aid="l00459"name="l00459"></a><spanclass="lineno"> 459</span><spanclass="comment">// The following inequality is valid and sharp cut for the lin max constraint</span></div>
<divclass="line"><aid="l00460"name="l00460"></a><spanclass="lineno"> 460</span><spanclass="comment">// described above.</span></div>
<divclass="line"><aid="l00466"name="l00466"></a><spanclass="lineno"> 466</span><spanclass="comment">// = max corner difference for variable i,</span></div>
<divclass="line"><aid="l00467"name="l00467"></a><spanclass="lineno"> 467</span><spanclass="comment">// target expr I(i), max expr k.</span></div>
<divclass="line"><aid="l00469"name="l00469"></a><spanclass="lineno"> 469</span><spanclass="comment">// For detailed proof of validity, refer</span></div>
<divclass="line"><aid="l00470"name="l00470"></a><spanclass="lineno"> 470</span><spanclass="comment">// Reference: "Strong mixed-integer programming formulations for trained neural</span></div>
<divclass="line"><aid="l00471"name="l00471"></a><spanclass="lineno"> 471</span><spanclass="comment">// networks" by Ross Anderson et. (https://arxiv.org/pdf/1811.01988.pdf).</span></div>
<divclass="line"><aid="l00473"name="l00473"></a><spanclass="lineno"> 473</span><spanclass="comment">// In the cut generator, we compute the most violated partition I by computing</span></div>
<divclass="line"><aid="l00474"name="l00474"></a><spanclass="lineno"> 474</span><spanclass="comment">// the rhs value (wI(i)i * lp_value(xi) + Sum(k=1..d)(MPlusCoefficient_ki * zk))</span></div>
<divclass="line"><aid="l00475"name="l00475"></a><spanclass="lineno"> 475</span><spanclass="comment">// for each variable for each partition index. We choose the partition index</span></div>
<divclass="line"><aid="l00476"name="l00476"></a><spanclass="lineno"> 476</span><spanclass="comment">// that gives lowest rhs value for a given variable.</span></div>
<divclass="line"><aid="l00478"name="l00478"></a><spanclass="lineno"> 478</span><spanclass="comment">// Note: This cut generator requires all expressions to contain only positive</span></div>
<divclass="line"><aid="l00484"name="l00484"></a><spanclass="lineno"> 484</span><spanclass="comment">// Helper for the affine max constraint.</span></div>
<divclass="line"><aid="l00490"name="l00490"></a><spanclass="lineno"> 490</span><spanclass="comment">// By definition, the Max of affine functions is convex. The linear polytope is</span></div>
<divclass="line"><aid="l00491"name="l00491"></a><spanclass="lineno"> 491</span><spanclass="comment">// bounded by all affine functions on the bottom, and by a single hyperplane</span></div>
<divclass="line"><aid="l00492"name="l00492"></a><spanclass="lineno"> 492</span><spanclass="comment">// that join the two points at the extreme of the var domain, and their y-values</span></div>
<divclass="line"><aid="l00493"name="l00493"></a><spanclass="lineno"> 493</span><spanclass="comment">// of the max of the affine functions.</span></div>
<divclass="line"><aid="l00499"name="l00499"></a><spanclass="lineno"> 499</span><spanclass="comment">// Extracts the variables that have a Literal view from base variables and</span></div>
<divclass="line"><aid="l00500"name="l00500"></a><spanclass="lineno"> 500</span><spanclass="comment">// create a generator that will returns constraint of the form "at_most_one"</span></div>
<divclass="line"><aid="l00501"name="l00501"></a><spanclass="lineno"> 501</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#l00260">cuts.h:260</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#l00133">cuts.h:133</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#l01358">cuts.cc:1358</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#l02069">cuts.cc:2069</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#l01452">cuts.cc:1452</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#l02105">cuts.cc:2105</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>