<ahref="cuts_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aname="l00001"></a><spanclass="lineno"> 1</span> <spanclass="comment">// Copyright 2010-2021 Google LLC</span></div>
<divclass="line"><aname="l00002"></a><spanclass="lineno"> 2</span> <spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aname="l00003"></a><spanclass="lineno"> 3</span> <spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aname="l00004"></a><spanclass="lineno"> 4</span> <spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aname="l00008"></a><spanclass="lineno"> 8</span> <spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aname="l00009"></a><spanclass="lineno"> 9</span> <spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aname="l00010"></a><spanclass="lineno"> 10</span> <spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aname="l00011"></a><spanclass="lineno"> 11</span> <spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aname="l00012"></a><spanclass="lineno"> 12</span> <spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aname="l00033"></a><spanclass="lineno"> 33</span> <spanclass="comment">// A "cut" generator on a set of IntegerVariable.</span></div>
<divclass="line"><aname="l00035"></a><spanclass="lineno"> 35</span> <spanclass="comment">// The generate_cuts() function will usually be called with the current LP</span></div>
<divclass="line"><aname="l00036"></a><spanclass="lineno"> 36</span> <spanclass="comment">// optimal solution (but should work for any lp_values). Note that a</span></div>
<divclass="line"><aname="l00038"></a><spanclass="lineno"> 38</span> <spanclass="comment">// - Only look at the lp_values positions that corresponds to its 'vars' or</span></div>
<divclass="line"><aname="l00039"></a><spanclass="lineno"> 39</span> <spanclass="comment">// their negation.</span></div>
<divclass="line"><aname="l00040"></a><spanclass="lineno"> 40</span> <spanclass="comment">// - Only add cuts in term of the same variables or their negation.</span></div>
<divclass="line"><aname="l00049"></a><spanclass="lineno"> 49</span> <spanclass="comment">// Given an upper-bounded linear relation (sum terms <= ub), this algorithm</span></div>
<divclass="line"><aname="l00050"></a><spanclass="lineno"> 50</span> <spanclass="comment">// inspects the integer variable appearing in the sum and try to replace each of</span></div>
<divclass="line"><aname="l00051"></a><spanclass="lineno"> 51</span> <spanclass="comment">// them by a tight lower bound (>= coeff * binary + lb) using the implied bound</span></div>
<divclass="line"><aname="l00052"></a><spanclass="lineno"> 52</span> <spanclass="comment">// repository. By tight, we mean that it will take the same value under the</span></div>
<divclass="line"><aname="l00053"></a><spanclass="lineno"> 53</span> <spanclass="comment">// current LP solution.</span></div>
<divclass="line"><aname="l00055"></a><spanclass="lineno"> 55</span> <spanclass="comment">// We use a class to reuse memory of the tmp terms.</span></div>
<divclass="line"><aname="l00058"></a><spanclass="lineno"> 58</span> <spanclass="comment">// We will only replace IntegerVariable appearing in lp_vars_.</span></div>
<divclass="line"><aname="l00071"></a><spanclass="lineno"> 71</span> <spanclass="comment">// Same as ProcessUpperBoundedConstraint() but instead of just using</span></div>
<divclass="line"><aname="l00072"></a><spanclass="lineno"> 72</span> <spanclass="comment">// var >= coeff * binary + lb we use var == slack + coeff * binary + lb where</span></div>
<divclass="line"><aname="l00073"></a><spanclass="lineno"> 73</span> <spanclass="comment">// slack is a new temporary variable that we create.</span></div>
<divclass="line"><aname="l00075"></a><spanclass="lineno"> 75</span> <spanclass="comment">// The new slack will be such that slack_infos[(slack - first_slack) / 2]</span></div>
<divclass="line"><aname="l00076"></a><spanclass="lineno"> 76</span> <spanclass="comment">// contains its definition so that we can properly handle it in the cut</span></div>
<divclass="line"><aname="l00077"></a><spanclass="lineno"> 77</span> <spanclass="comment">// generation and substitute it back later.</span></div>
<divclass="line"><aname="l00079"></a><spanclass="lineno"> 79</span> <spanclass="comment">// This slack is equal to sum of terms + offset.</span></div>
<divclass="line"><aname="l00093"></a><spanclass="lineno"> 93</span> <spanclass="comment">// See if some of the implied bounds equation are violated and add them to</span></div>
<divclass="line"><aname="l00094"></a><spanclass="lineno"> 94</span> <spanclass="comment">// the IB cut pool if it is the case.</span></div>
<divclass="line"><aname="l00100"></a><spanclass="lineno"> 100</span> <spanclass="comment">// Substituting back the slack created by the function above should give</span></div>
<divclass="line"><aname="l00101"></a><spanclass="lineno"> 101</span> <spanclass="comment">// exactly the same cut as the original one.</span></div>
<divclass="line"><aname="l00107"></a><spanclass="lineno"> 107</span> <spanclass="comment">// Add a new variable that could be used in the new cuts.</span></div>
<divclass="line"><aname="l00110"></a><spanclass="lineno"> 110</span> <spanclass="comment">// Must be called before we process any constraints with a different</span></div>
<divclass="line"><aname="l00111"></a><spanclass="lineno"> 111</span> <spanclass="comment">// lp_values or level zero bounds.</span></div>
<divclass="line"><aname="l00123"></a><spanclass="lineno"> 123</span> <spanclass="comment">// As we compute the best implied bounds for each variable, we add violated</span></div>
<divclass="line"><aname="l00141"></a><spanclass="lineno"> 141</span> <spanclass="comment">// Temporary memory used by ProcessUpperBoundedConstraint().</span></div>
<divclass="line"><aname="l00145"></a><spanclass="lineno"> 145</span> <spanclass="comment">// Visible for testing. Returns a function f on integers such that:</span></div>
<divclass="line"><aname="l00146"></a><spanclass="lineno"> 146</span> <spanclass="comment">// - f is non-decreasing.</span></div>
<divclass="line"><aname="l00147"></a><spanclass="lineno"> 147</span> <spanclass="comment">// - f is super-additive: f(a) + f(b) <= f(a + b)</span></div>
<divclass="line"><aname="l00149"></a><spanclass="lineno"> 149</span> <spanclass="comment">// - For all x, f(x * divisor) = x * f(divisor)</span></div>
<divclass="line"><aname="l00150"></a><spanclass="lineno"> 150</span> <spanclass="comment">// - For all x, f(x * divisor + remainder) = x * f(divisor)</span></div>
<divclass="line"><aname="l00156"></a><spanclass="lineno"> 156</span> <spanclass="comment">// This is used in IntegerRoundingCut() and is responsible for "strengthening"</span></div>
<divclass="line"><aname="l00157"></a><spanclass="lineno"> 157</span> <spanclass="comment">// the cut. Just taking f(x) = x / divisor result in the non-strengthened cut</span></div>
<divclass="line"><aname="l00158"></a><spanclass="lineno"> 158</span> <spanclass="comment">// and using any function that stricly dominate this one is better.</span></div>
<divclass="line"><aname="l00161"></a><spanclass="lineno"> 161</span> <spanclass="comment">// - We first scale by a factor t so that rhs_remainder >= divisor / 2.</span></div>
<divclass="line"><aname="l00162"></a><spanclass="lineno"> 162</span> <spanclass="comment">// - Then, if max_scaling == 2, we use the function described</span></div>
<divclass="line"><aname="l00163"></a><spanclass="lineno"> 163</span> <spanclass="comment">// in "Strenghtening Chvatal-Gomory cuts and Gomory fractional cuts", Adam N.</span></div>
<divclass="line"><aname="l00164"></a><spanclass="lineno"> 164</span> <spanclass="comment">// Letchfrod, Andrea Lodi.</span></div>
<divclass="line"><aname="l00165"></a><spanclass="lineno"> 165</span> <spanclass="comment">// - Otherwise, we use a generalization of this which is a discretized version</span></div>
<divclass="line"><aname="l00166"></a><spanclass="lineno"> 166</span> <spanclass="comment">// of the classical MIR rounding function that only take the value of the</span></div>
<divclass="line"><aname="l00167"></a><spanclass="lineno"> 167</span> <spanclass="comment">// form "an_integer / max_scaling". As max_scaling goes to infinity, this</span></div>
<divclass="line"><aname="l00168"></a><spanclass="lineno"> 168</span> <spanclass="comment">// converge to the real-valued MIR function.</span></div>
<divclass="line"><aname="l00170"></a><spanclass="lineno"> 170</span> <spanclass="comment">// Note that for each value of max_scaling we will get a different function.</span></div>
<divclass="line"><aname="l00171"></a><spanclass="lineno"> 171</span> <spanclass="comment">// And that there is no dominance relation between any of these functions. So</span></div>
<divclass="line"><aname="l00172"></a><spanclass="lineno"> 172</span> <spanclass="comment">// it could be nice to try to generate a cut using different values of</span></div>
<divclass="line"><aname="l00180"></a><spanclass="lineno"> 180</span> <spanclass="comment">// Given an upper bounded linear constraint, this function tries to transform it</span></div>
<divclass="line"><aname="l00181"></a><spanclass="lineno"> 181</span> <spanclass="comment">// to a valid cut that violate the given LP solution using integer rounding.</span></div>
<divclass="line"><aname="l00182"></a><spanclass="lineno"> 182</span> <spanclass="comment">// Note that the returned cut might not always violate the LP solution, in which</span></div>
<divclass="line"><aname="l00183"></a><spanclass="lineno"> 183</span> <spanclass="comment">// case it can be discarded.</span></div>
<divclass="line"><aname="l00185"></a><spanclass="lineno"> 185</span> <spanclass="comment">// What this does is basically take the integer division of the constraint by an</span></div>
<divclass="line"><aname="l00186"></a><spanclass="lineno"> 186</span> <spanclass="comment">// integer. If the coefficients where doubles, this would be the same as scaling</span></div>
<divclass="line"><aname="l00187"></a><spanclass="lineno"> 187</span> <spanclass="comment">// the constraint and then rounding. We choose the coefficient of the most</span></div>
<divclass="line"><aname="l00188"></a><spanclass="lineno"> 188</span> <spanclass="comment">// fractional variable (rescaled by its coefficient) as the divisor, but there</span></div>
<divclass="line"><aname="l00189"></a><spanclass="lineno"> 189</span> <spanclass="comment">// are other possible alternatives.</span></div>
<divclass="line"><aname="l00191"></a><spanclass="lineno"> 191</span> <spanclass="comment">// Note that if the constraint is tight under the given lp solution, and if</span></div>
<divclass="line"><aname="l00192"></a><spanclass="lineno"> 192</span> <spanclass="comment">// there is a unique variable not at one of its bounds and fractional, then we</span></div>
<divclass="line"><aname="l00193"></a><spanclass="lineno"> 193</span> <spanclass="comment">// are guaranteed to generate a cut that violate the current LP solution. This</span></div>
<divclass="line"><aname="l00194"></a><spanclass="lineno"> 194</span> <spanclass="comment">// should be the case for Chvatal-Gomory base constraints modulo our loss of</span></div>
<divclass="line"><aname="l00195"></a><spanclass="lineno"> 195</span> <spanclass="comment">// precision while doing exact integer computations.</span></div>
<divclass="line"><aname="l00198"></a><spanclass="lineno"> 198</span> <spanclass="comment">// - We assumes that the given initial constraint is tight using the given lp</span></div>
<divclass="line"><aname="l00199"></a><spanclass="lineno"> 199</span> <spanclass="comment">// values. This could be relaxed, but for now it should always be the case, so</span></div>
<divclass="line"><aname="l00200"></a><spanclass="lineno"> 200</span> <spanclass="comment">// we log a message and abort if not, to ease debugging.</span></div>
<divclass="line"><aname="l00201"></a><spanclass="lineno"> 201</span> <spanclass="comment">// - The IntegerVariable of the cuts are not used here. We assumes that the</span></div>
<divclass="line"><aname="l00202"></a><spanclass="lineno"> 202</span> <spanclass="comment">// first three vectors are in one to one correspondence with the initial order</span></div>
<divclass="line"><aname="l00203"></a><spanclass="lineno"> 203</span> <spanclass="comment">// of the variable in the cut.</span></div>
<divclass="line"><aname="l00205"></a><spanclass="lineno"> 205</span> <spanclass="comment">// TODO(user): There is a bunch of heuristic involved here, and we could spend</span></div>
<divclass="line"><aname="l00206"></a><spanclass="lineno"> 206</span> <spanclass="comment">// more effort tunning them. In particular, one can try many heuristics and keep</span></div>
<divclass="line"><aname="l00207"></a><spanclass="lineno"> 207</span> <spanclass="comment">// the best looking cut (or more than one). This is not on the critical code</span></div>
<divclass="line"><aname="l00208"></a><spanclass="lineno"> 208</span> <spanclass="comment">// path, so we can spend more effort in finding good cuts.</span></div>
<divclass="line"><aname="l00219"></a><spanclass="lineno"> 219</span> <spanclass="comment">// Returns the number of implied bound lifted Booleans in the last</span></div>
<divclass="line"><aname="l00220"></a><spanclass="lineno"> 220</span> <spanclass="comment">// ComputeCut() call. Useful for investigation.</span></div>
<divclass="line"><aname="l00224"></a><spanclass="lineno"> 224</span> <spanclass="comment">// The helper is just here to reuse the memory for these vectors.</span></div>
<divclass="line"><aname="l00243"></a><spanclass="lineno"> 243</span> <spanclass="comment">// Try to find a cut with a knapsack heuristic.</span></div>
<divclass="line"><aname="l00244"></a><spanclass="lineno"> 244</span> <spanclass="comment">// If this returns true, you can get the cut via cut().</span></div>
<divclass="line"><aname="l00250"></a><spanclass="lineno"> 250</span> <spanclass="comment">// If successful, info about the last generated cut.</span></div>
<divclass="line"><aname="l00254"></a><spanclass="lineno"> 254</span> <spanclass="comment">// Single line of text that we append to the cut log line.</span></div>
<divclass="line"><aname="l00261"></a><spanclass="lineno"> 261</span>  IntegerValue positive_coeff; <spanclass="comment">// abs(coeff in original constraint).</span></div>
<divclass="line"><aname="l00271"></a><spanclass="lineno"> 271</span> <spanclass="comment">// If a variable is away from its upper bound by more than value 1.0, then it</span></div>
<divclass="line"><aname="l00272"></a><spanclass="lineno"> 272</span> <spanclass="comment">// cannot be part of a cover that will violate the lp solution. This method</span></div>
<divclass="line"><aname="l00273"></a><spanclass="lineno"> 273</span> <spanclass="comment">// returns a reduced constraint by removing such variables from the given</span></div>
<divclass="line"><aname="l00280"></a><spanclass="lineno"> 280</span> <spanclass="comment">// Returns true if sum of all the variables in the given constraint is less than</span></div>
<divclass="line"><aname="l00281"></a><spanclass="lineno"> 281</span> <spanclass="comment">// or equal to constraint upper bound. This method assumes that all the</span></div>
<divclass="line"><aname="l00282"></a><spanclass="lineno"> 282</span> <spanclass="comment">// coefficients are non negative.</span></div>
<divclass="line"><aname="l00286"></a><spanclass="lineno"> 286</span> <spanclass="comment">// If the left variables in lp solution satisfies following inequality, we prove</span></div>
<divclass="line"><aname="l00287"></a><spanclass="lineno"> 287</span> <spanclass="comment">// that there does not exist any knapsack cut which is violated by the solution.</span></div>
<divclass="line"><aname="l00288"></a><spanclass="lineno"> 288</span> <spanclass="comment">// Let |Cmin| = smallest possible cover size.</span></div>
<divclass="line"><aname="l00289"></a><spanclass="lineno"> 289</span> <spanclass="comment">// Let S = smallest (var_ub - lp_values[var]) first |Cmin| variables.</span></div>
<divclass="line"><aname="l00290"></a><spanclass="lineno"> 290</span> <spanclass="comment">// Let cut lower bound = sum_(var in S)(var_ub - lp_values[var])</span></div>
<divclass="line"><aname="l00291"></a><spanclass="lineno"> 291</span> <spanclass="comment">// For any cover,</span></div>
<divclass="line"><aname="l00292"></a><spanclass="lineno"> 292</span> <spanclass="comment">// If cut lower bound >= 1</span></div>
<divclass="line"><aname="l00293"></a><spanclass="lineno"> 293</span> <spanclass="comment">// ==> sum_(var in S)(var_ub - lp_values[var]) >= 1</span></div>
<divclass="line"><aname="l00294"></a><spanclass="lineno"> 294</span> <spanclass="comment">// ==> sum_(var in cover)(var_ub - lp_values[var]) >= 1</span></div>
<divclass="line"><aname="l00295"></a><spanclass="lineno"> 295</span> <spanclass="comment">// ==> The solution already satisfies cover. Since this is true for all covers,</span></div>
<divclass="line"><aname="l00296"></a><spanclass="lineno"> 296</span> <spanclass="comment">// this method returns false in such cases.</span></div>
<divclass="line"><aname="l00297"></a><spanclass="lineno"> 297</span> <spanclass="comment">// This method assumes that the constraint is preprocessed and has only non</span></div>
<divclass="line"><aname="l00304"></a><spanclass="lineno"> 304</span> <spanclass="comment">// Struct to help compute upper bound for knapsack instance.</span></div>
<divclass="line"><aname="l00313"></a><spanclass="lineno"> 313</span> <spanclass="comment">// Gets upper bound on profit for knapsack instance by solving the linear</span></div>
<divclass="line"><aname="l00317"></a><spanclass="lineno"> 317</span> <spanclass="comment">// Returns true if the linear relaxation upper bound for the knapsack instance</span></div>
<divclass="line"><aname="l00318"></a><spanclass="lineno"> 318</span> <spanclass="comment">// shows that this constraint cannot be used to form a cut. This method assumes</span></div>
<divclass="line"><aname="l00319"></a><spanclass="lineno"> 319</span> <spanclass="comment">// that all the coefficients are non negative.</span></div>
<divclass="line"><aname="l00325"></a><spanclass="lineno"> 325</span> <spanclass="comment">// Returns true if the given constraint passes all the filters described above.</span></div>
<divclass="line"><aname="l00326"></a><spanclass="lineno"> 326</span> <spanclass="comment">// This method assumes that the constraint is preprocessed and has only non</span></div>
<divclass="line"><aname="l00333"></a><spanclass="lineno"> 333</span> <spanclass="comment">// Converts the given constraint into canonical knapsack form (described</span></div>
<divclass="line"><aname="l00334"></a><spanclass="lineno"> 334</span> <spanclass="comment">// below) and adds it to 'knapsack_constraints'.</span></div>
<divclass="line"><aname="l00336"></a><spanclass="lineno"> 336</span> <spanclass="comment">// - Constraint has finite upper bound.</span></div>
<divclass="line"><aname="l00337"></a><spanclass="lineno"> 337</span> <spanclass="comment">// - All coefficients are positive.</span></div>
<divclass="line"><aname="l00338"></a><spanclass="lineno"> 338</span> <spanclass="comment">// For constraint with finite lower bound, this method also adds the negation of</span></div>
<divclass="line"><aname="l00339"></a><spanclass="lineno"> 339</span> <spanclass="comment">// the given constraint after converting it to canonical knapsack form.</span></div>
<divclass="line"><aname="l00344"></a><spanclass="lineno"> 344</span> <spanclass="comment">// Returns true if the cut is lifted. Lifting procedure is described below.</span></div>
<divclass="line"><aname="l00346"></a><spanclass="lineno"> 346</span> <spanclass="comment">// First we decide a lifting sequence for the binary variables which are not</span></div>
<divclass="line"><aname="l00347"></a><spanclass="lineno"> 347</span> <spanclass="comment">// already in cut. We lift the cut for each lifting candidate one by one.</span></div>
<divclass="line"><aname="l00349"></a><spanclass="lineno"> 349</span> <spanclass="comment">// Given the original constraint where the lifting candidate is fixed to one, we</span></div>
<divclass="line"><aname="l00350"></a><spanclass="lineno"> 350</span> <spanclass="comment">// compute the maximum value the cut can take and still be feasible using a</span></div>
<divclass="line"><aname="l00351"></a><spanclass="lineno"> 351</span> <spanclass="comment">// knapsack problem. We can then lift the variable in the cut using the</span></div>
<divclass="line"><aname="l00352"></a><spanclass="lineno"> 352</span> <spanclass="comment">// difference between the cut upper bound and this maximum value.</span></div>
<divclass="line"><aname="l00360"></a><spanclass="lineno"> 360</span> <spanclass="comment">// A cut generator that creates knpasack cover cuts.</span></div>
<divclass="line"><aname="l00364"></a><spanclass="lineno"> 364</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"><aname="l00365"></a><spanclass="lineno"> 365</span> <spanclass="comment">// subset C of {1 , .. , n} such that \sum_{c \in C}(a_c * u_c) > b.</span></div>
<divclass="line"><aname="l00367"></a><spanclass="lineno"> 367</span> <spanclass="comment">// A knapsack cover cut is a constraint of the form</span></div>
<divclass="line"><aname="l00369"></a><spanclass="lineno"> 369</span> <spanclass="comment">// which is equivalent to \sum_{c \in C}(x_c) <= \sum_{c \in C}(u_c) - 1.</span></div>
<divclass="line"><aname="l00370"></a><spanclass="lineno"> 370</span> <spanclass="comment">// In other words, in a feasible solution, at least some of the variables do</span></div>
<divclass="line"><aname="l00371"></a><spanclass="lineno"> 371</span> <spanclass="comment">// not take their maximum value.</span></div>
<divclass="line"><aname="l00373"></a><spanclass="lineno"> 373</span> <spanclass="comment">// If all x_i are binary variables then the cover cut becomes</span></div>
<divclass="line"><aname="l00376"></a><spanclass="lineno"> 376</span> <spanclass="comment">// The major difficulty for generating Knapsack cover cuts is finding a minimal</span></div>
<divclass="line"><aname="l00377"></a><spanclass="lineno"> 377</span> <spanclass="comment">// cover set C that cut a given floating point solution. There are many ways to</span></div>
<divclass="line"><aname="l00378"></a><spanclass="lineno"> 378</span> <spanclass="comment">// heuristically generate the cover but the following method that uses a</span></div>
<divclass="line"><aname="l00379"></a><spanclass="lineno"> 379</span> <spanclass="comment">// solution of the LP relaxation of the constraint works the best.</span></div>
<divclass="line"><aname="l00381"></a><spanclass="lineno"> 381</span> <spanclass="comment">// Look at a given linear relaxation solution for the integer problem x'</span></div>
<divclass="line"><aname="l00382"></a><spanclass="lineno"> 382</span> <spanclass="comment">// and try to solve the following knapsack problem:</span></div>
<divclass="line"><aname="l00384"></a><spanclass="lineno"> 384</span> <spanclass="comment">// such that \sum_{i=1..n}(a_i * u_i * z_i) > b,</span></div>
<divclass="line"><aname="l00385"></a><spanclass="lineno"> 385</span> <spanclass="comment">// where z_i is a binary decision variable and x_i' are values of the variables</span></div>
<divclass="line"><aname="l00386"></a><spanclass="lineno"> 386</span> <spanclass="comment">// in the given relaxation solution x'. If the objective of the optimal solution</span></div>
<divclass="line"><aname="l00387"></a><spanclass="lineno"> 387</span> <spanclass="comment">// of this problem is less than 1, this algorithm does not generate any cuts.</span></div>
<divclass="line"><aname="l00388"></a><spanclass="lineno"> 388</span> <spanclass="comment">// Otherwise, it adds a knapsack cover cut in the form</span></div>
<divclass="line"><aname="l00390"></a><spanclass="lineno"> 390</span> <spanclass="comment">// where z_i' is the value of z_i in the optimal solution of the above</span></div>
<divclass="line"><aname="l00391"></a><spanclass="lineno"> 391</span> <spanclass="comment">// problem and cb is the upper bound for the cut constraint. Note that the above</span></div>
<divclass="line"><aname="l00392"></a><spanclass="lineno"> 392</span> <spanclass="comment">// problem can be converted into a standard kanpsack form by replacing z_i by 1</span></div>
<divclass="line"><aname="l00393"></a><spanclass="lineno"> 393</span> <spanclass="comment">// - y_i. In that case the problem becomes</span></div>
<divclass="line"><aname="l00398"></a><spanclass="lineno"> 398</span> <spanclass="comment">// Solving this knapsack instance would help us find the smallest cover with</span></div>
<divclass="line"><aname="l00399"></a><spanclass="lineno"> 399</span> <spanclass="comment">// maximum LP violation.</span></div>
<divclass="line"><aname="l00402"></a><spanclass="lineno"> 402</span> <spanclass="comment">// Let lambda = \sum_{c \in C}(a_c * u_c) - b and max_coeff = \max_{c</span></div>
<divclass="line"><aname="l00403"></a><spanclass="lineno"> 403</span> <spanclass="comment">// \in C}(a_c), then cut can be strengthened as</span></div>
<divclass="line"><aname="l00406"></a><spanclass="lineno"> 406</span> <spanclass="comment">// For further information about knapsack cover cuts see</span></div>
<divclass="line"><aname="l00407"></a><spanclass="lineno"> 407</span> <spanclass="comment">// A. Atamtürk, Cover and Pack Inequalities for (Mixed) Integer Programming</span></div>
<divclass="line"><aname="l00408"></a><spanclass="lineno"> 408</span> <spanclass="comment">// Annals of Operations Research Volume 139, Issue 1 , pp 21-38, 2005.</span></div>
<divclass="line"><aname="l00414"></a><spanclass="lineno"> 414</span> <spanclass="comment">// A cut generator for z = x * y (x and y >= 0).</span></div>
<divclass="line"><aname="l00420"></a><spanclass="lineno"> 420</span> <spanclass="comment">// A cut generator for y = x ^ 2 (x >= 0).</span></div>
<divclass="line"><aname="l00421"></a><spanclass="lineno"> 421</span> <spanclass="comment">// It will dynamically add a linear inequality to push y closer to the parabola.</span></div>
<divclass="line"><aname="l00422"></a><spanclass="lineno"> 422</span> CutGenerator <aclass="code"href="namespaceoperations__research_1_1sat.html#a562723a1a137cee8f869c1d7eb9641b0">CreateSquareCutGenerator</a>(IntegerVariable y, IntegerVariable x,</div>
<divclass="line"><aname="l00425"></a><spanclass="lineno"> 425</span> <spanclass="comment">// A cut generator for all_diff(xi). Let the united domain of all xi be D. Sum</span></div>
<divclass="line"><aname="l00426"></a><spanclass="lineno"> 426</span> <spanclass="comment">// of any k-sized subset of xi need to be greater or equal to the sum of</span></div>
<divclass="line"><aname="l00427"></a><spanclass="lineno"> 427</span> <spanclass="comment">// smallest k values in D and lesser or equal to the sum of largest k values in</span></div>
<divclass="line"><aname="l00428"></a><spanclass="lineno"> 428</span> <spanclass="comment">// D. The cut generator first sorts the variables based on LP values and adds</span></div>
<divclass="line"><aname="l00429"></a><spanclass="lineno"> 429</span> <spanclass="comment">// cuts of the form described above if they are violated by lp solution. Note</span></div>
<divclass="line"><aname="l00430"></a><spanclass="lineno"> 430</span> <spanclass="comment">// that all the fixed variables are ignored while generating cuts.</span></div>
<divclass="line"><aname="l00434"></a><spanclass="lineno"> 434</span> <spanclass="comment">// Consider the Lin Max constraint with d expressions and n variables in the</span></div>
<divclass="line"><aname="l00435"></a><spanclass="lineno"> 435</span> <spanclass="comment">// form: target = max {exprs[k] = Sum (wki * xi + bk)}. k in {1,..,d}.</span></div>
<divclass="line"><aname="l00436"></a><spanclass="lineno"> 436</span> <spanclass="comment">// Li = lower bound of xi</span></div>
<divclass="line"><aname="l00437"></a><spanclass="lineno"> 437</span> <spanclass="comment">// Ui = upper bound of xi.</span></div>
<divclass="line"><aname="l00438"></a><spanclass="lineno"> 438</span> <spanclass="comment">// Let zk be in {0,1} for all k in {1,..,d}.</span></div>
<divclass="line"><aname="l00439"></a><spanclass="lineno"> 439</span> <spanclass="comment">// The target = exprs[k] when zk = 1.</span></div>
<divclass="line"><aname="l00441"></a><spanclass="lineno"> 441</span> <spanclass="comment">// The following is a valid linearization for Lin Max.</span></div>
<divclass="line"><aname="l00442"></a><spanclass="lineno"> 442</span> <spanclass="comment">// target >= exprs[k], for all k in {1,..,d}</span></div>
<divclass="line"><aname="l00443"></a><spanclass="lineno"> 443</span> <spanclass="comment">// target <= Sum (wli * xi) + Sum((Nlk + bk) * zk), for all l in {1,..,d}</span></div>
<divclass="line"><aname="l00444"></a><spanclass="lineno"> 444</span> <spanclass="comment">// Where Nlk is a large number defined as:</span></div>
<divclass="line"><aname="l00446"></a><spanclass="lineno"> 446</span> <spanclass="comment">// = Sum (max corner difference for variable i, target expr l, max expr k)</span></div>
<divclass="line"><aname="l00448"></a><spanclass="lineno"> 448</span> <spanclass="comment">// Consider a partition of variables xi into set {1,..,d} as I.</span></div>
<divclass="line"><aname="l00449"></a><spanclass="lineno"> 449</span> <spanclass="comment">// i.e. I(i) = j means xi is mapped to jth index.</span></div>
<divclass="line"><aname="l00450"></a><spanclass="lineno"> 450</span> <spanclass="comment">// The following inequality is valid and sharp cut for the lin max constraint</span></div>
<divclass="line"><aname="l00451"></a><spanclass="lineno"> 451</span> <spanclass="comment">// described above.</span></div>
<divclass="line"><aname="l00460"></a><spanclass="lineno"> 460</span> <spanclass="comment">// For detailed proof of validity, refer</span></div>
<divclass="line"><aname="l00461"></a><spanclass="lineno"> 461</span> <spanclass="comment">// Reference: "Strong mixed-integer programming formulations for trained neural</span></div>
<divclass="line"><aname="l00462"></a><spanclass="lineno"> 462</span> <spanclass="comment">// networks" by Ross Anderson et. (https://arxiv.org/pdf/1811.01988.pdf).</span></div>
<divclass="line"><aname="l00464"></a><spanclass="lineno"> 464</span> <spanclass="comment">// In the cut generator, we compute the most violated partition I by computing</span></div>
<divclass="line"><aname="l00465"></a><spanclass="lineno"> 465</span> <spanclass="comment">// the rhs value (wI(i)i * lp_value(xi) + Sum(k=1..d)(MPlusCoefficient_ki * zk))</span></div>
<divclass="line"><aname="l00466"></a><spanclass="lineno"> 466</span> <spanclass="comment">// for each variable for each partition index. We choose the partition index</span></div>
<divclass="line"><aname="l00467"></a><spanclass="lineno"> 467</span> <spanclass="comment">// that gives lowest rhs value for a given variable.</span></div>
<divclass="line"><aname="l00469"></a><spanclass="lineno"> 469</span> <spanclass="comment">// Note: This cut generator requires all expressions to contain only positive</span></div>
<divclass="line"><aname="l00475"></a><spanclass="lineno"> 475</span> <spanclass="comment">// For a given set of intervals and demands, we compute the maximum energy of</span></div>
<divclass="line"><aname="l00476"></a><spanclass="lineno"> 476</span> <spanclass="comment">// each task and make sure it is less than the span of the intervals * its</span></div>
<divclass="line"><aname="l00479"></a><spanclass="lineno"> 479</span> <spanclass="comment">// If an interval is optional, it contributes</span></div>
<divclass="line"><aname="l00483"></a><spanclass="lineno"> 483</span> <spanclass="comment">// If an interval is performed, it contributes either min_demand * size or</span></div>
<divclass="line"><aname="l00484"></a><spanclass="lineno"> 484</span> <spanclass="comment">// demand * min_size. We choose the most violated formulation.</span></div>
<divclass="line"><aname="l00486"></a><spanclass="lineno"> 486</span> <spanclass="comment">// The maximum energy is capacity * span of intervals at level 0.</span></div>
<divclass="line"><aname="l00492"></a><spanclass="lineno"> 492</span> <spanclass="comment">// For a given set of intervals and demands, we first compute the mandatory part</span></div>
<divclass="line"><aname="l00493"></a><spanclass="lineno"> 493</span> <spanclass="comment">// of the interval as [start_max , end_min]. We use this to calculate mandatory</span></div>
<divclass="line"><aname="l00494"></a><spanclass="lineno"> 494</span> <spanclass="comment">// demands for each start_max time points for eligible intervals.</span></div>
<divclass="line"><aname="l00495"></a><spanclass="lineno"> 495</span> <spanclass="comment">// Since the sum of these mandatory demands must be smaller or equal to the</span></div>
<divclass="line"><aname="l00496"></a><spanclass="lineno"> 496</span> <spanclass="comment">// capacity, we create a cut representing that.</span></div>
<divclass="line"><aname="l00498"></a><spanclass="lineno"> 498</span> <spanclass="comment">// If an interval is optional, it contributes min_demand * presence_literal</span></div>
<divclass="line"><aname="l00499"></a><spanclass="lineno"> 499</span> <spanclass="comment">// amount of demand to the mandatory demands sum. So the final cut is generated</span></div>
<divclass="line"><aname="l00500"></a><spanclass="lineno"> 500</span> <spanclass="comment">// as follows:</span></div>
<divclass="line"><aname="l00501"></a><spanclass="lineno"> 501</span> <spanclass="comment">// sum(demands of always present intervals)</span></div>
<divclass="line"><aname="l00508"></a><spanclass="lineno"> 508</span> <spanclass="comment">// For a given set of intervals, we first compute the min and max of all</span></div>
<divclass="line"><aname="l00509"></a><spanclass="lineno"> 509</span> <spanclass="comment">// intervals. Then we create a cut that indicates that all intervals must fit</span></div>
<divclass="line"><aname="l00510"></a><spanclass="lineno"> 510</span> <spanclass="comment">// in that span.</span></div>
<divclass="line"><aname="l00512"></a><spanclass="lineno"> 512</span> <spanclass="comment">// If an interval is optional, it contributes min_size * presence_literal</span></div>
<divclass="line"><aname="l00513"></a><spanclass="lineno"> 513</span> <spanclass="comment">// amount of demand to the mandatory demands sum. So the final cut is generated</span></div>
<divclass="line"><aname="l00514"></a><spanclass="lineno"> 514</span> <spanclass="comment">// as follows:</span></div>
<divclass="line"><aname="l00515"></a><spanclass="lineno"> 515</span> <spanclass="comment">// sum(sizes of always present intervals)</span></div>
<divclass="line"><aname="l00516"></a><spanclass="lineno"> 516</span> <spanclass="comment">// + sum(presence_literal * min_of_size) <= span of all intervals.</span></div>
<divclass="line"><aname="l00520"></a><spanclass="lineno"> 520</span> <spanclass="comment">// For a given set of intervals in a no_overlap constraint, we detect violated</span></div>
<divclass="line"><aname="l00521"></a><spanclass="lineno"> 521</span> <spanclass="comment">// mandatory precedences and create a cut for these.</span></div>
<divclass="line"><aname="l00525"></a><spanclass="lineno"> 525</span> <spanclass="comment">// For a given set of intervals in a no_overlap constraint, we detect violated</span></div>
<divclass="line"><aname="l00526"></a><spanclass="lineno"> 526</span> <spanclass="comment">// area based cuts from Balas 85 [see note in the code] and create a cut for</span></div>
<divclass="line"><aname="l00531"></a><spanclass="lineno"> 531</span> <spanclass="comment">// Extracts the variables that have a Literal view from base variables and</span></div>
<divclass="line"><aname="l00532"></a><spanclass="lineno"> 532</span> <spanclass="comment">// create a generator that will returns constraint of the form "at_most_one"</span></div>
<divclass="line"><aname="l00533"></a><spanclass="lineno"> 533</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#l00105">time_limit.h:105</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_cover_cut_helper_html_a28706d15758f23844d625462fa39edbc"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_cover_cut_helper.html#a28706d15758f23844d625462fa39edbc">operations_research::sat::CoverCutHelper::cut</a></div><divclass="ttdeci">const LinearConstraint & cut() const</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8h_source.html#l00252">cuts.h:252</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_implied_bounds_processor_html_a6a4d553c8850c30428f1750d37d33d26"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_implied_bounds_processor.html#a6a4d553c8850c30428f1750d37d33d26">operations_research::sat::ImpliedBoundsProcessor::IbCutPool</a></div><divclass="ttdeci">TopNCuts & IbCutPool()</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8h_source.html#l00125">cuts.h:125</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_1_1sat_html_a562723a1a137cee8f869c1d7eb9641b0"><divclass="ttname"><ahref="namespaceoperations__research_1_1sat.html#a562723a1a137cee8f869c1d7eb9641b0">operations_research::sat::CreateSquareCutGenerator</a></div><divclass="ttdeci">CutGenerator CreateSquareCutGenerator(IntegerVariable y, IntegerVariable x, Model *model)</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8cc_source.html#l01428">cuts.cc:1428</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_1_1sat_html_acd00c99b5770a8f86418ce2c60c716b8"><divclass="ttname"><ahref="namespaceoperations__research_1_1sat.html#acd00c99b5770a8f86418ce2c60c716b8">operations_research::sat::CreatePositiveMultiplicationCutGenerator</a></div><divclass="ttdeci">CutGenerator CreatePositiveMultiplicationCutGenerator(IntegerVariable z, IntegerVariable x, IntegerVariable y, Model *model)</div><divclass="ttdef"><b>Definition:</b><ahref="cuts_8cc_source.html#l01332">cuts.cc:1332</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#l02531">cuts.cc:2531</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>