<!-- iframe showing the search results (closed by default) -->
<divid="MSearchResultsWindow">
<iframesrc="javascript:void(0)"frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<divclass="header">
<divclass="headertitle">
<divclass="title">cuts.h</div></div>
</div><!--header-->
<divclass="contents">
<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-2018 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="l00032"></a><spanclass="lineno"> 32</span> <spanclass="comment">// A "cut" generator on a set of IntegerVariable.</span></div>
<divclass="line"><aname="l00034"></a><spanclass="lineno"> 34</span> <spanclass="comment">// The generate_cuts() function will usually be called with the current LP</span></div>
<divclass="line"><aname="l00035"></a><spanclass="lineno"> 35</span> <spanclass="comment">// optimal solution (but should work for any lp_values). Note that a</span></div>
<divclass="line"><aname="l00037"></a><spanclass="lineno"> 37</span> <spanclass="comment">// - Only look at the lp_values positions that corresponds to its 'vars' or</span></div>
<divclass="line"><aname="l00038"></a><spanclass="lineno"> 38</span> <spanclass="comment">// their negation.</span></div>
<divclass="line"><aname="l00039"></a><spanclass="lineno"> 39</span> <spanclass="comment">// - Only add cuts in term of the same variables or their negation.</span></div>
<divclass="line"><aname="l00047"></a><spanclass="lineno"> 47</span> <spanclass="comment">// Given an upper-bounded linear relation (sum terms <= ub), this algorithm</span></div>
<divclass="line"><aname="l00048"></a><spanclass="lineno"> 48</span> <spanclass="comment">// inspects the integer variable appearing in the sum and try to replace each of</span></div>
<divclass="line"><aname="l00049"></a><spanclass="lineno"> 49</span> <spanclass="comment">// them by a tight lower bound (>= coeff * binary + lb) using the implied bound</span></div>
<divclass="line"><aname="l00050"></a><spanclass="lineno"> 50</span> <spanclass="comment">// repository. By tight, we mean that it will take the same value under the</span></div>
<divclass="line"><aname="l00051"></a><spanclass="lineno"> 51</span> <spanclass="comment">// current LP solution.</span></div>
<divclass="line"><aname="l00053"></a><spanclass="lineno"> 53</span> <spanclass="comment">// We use a class to reuse memory of the tmp terms.</span></div>
<divclass="line"><aname="l00056"></a><spanclass="lineno"> 56</span> <spanclass="comment">// We will only replace IntegerVariable appearing in lp_vars_.</span></div>
<divclass="line"><aname="l00069"></a><spanclass="lineno"> 69</span> <spanclass="comment">// Same as ProcessUpperBoundedConstraint() but instead of just using</span></div>
<divclass="line"><aname="l00070"></a><spanclass="lineno"> 70</span> <spanclass="comment">// var >= coeff * binary + lb we use var == slack + coeff * binary + lb where</span></div>
<divclass="line"><aname="l00071"></a><spanclass="lineno"> 71</span> <spanclass="comment">// slack is a new temporary variable that we create.</span></div>
<divclass="line"><aname="l00073"></a><spanclass="lineno"> 73</span> <spanclass="comment">// The new slack will be such that slack_infos[(slack - first_slack) / 2]</span></div>
<divclass="line"><aname="l00074"></a><spanclass="lineno"> 74</span> <spanclass="comment">// contains its definition so that we can properly handle it in the cut</span></div>
<divclass="line"><aname="l00075"></a><spanclass="lineno"> 75</span> <spanclass="comment">// generation and substitute it back later.</span></div>
<divclass="line"><aname="l00077"></a><spanclass="lineno"> 77</span> <spanclass="comment">// This slack is equal to sum of terms + offset.</span></div>
<divclass="line"><aname="l00091"></a><spanclass="lineno"> 91</span> <spanclass="comment">// See if some of the implied bounds equation are violated and add them to</span></div>
<divclass="line"><aname="l00092"></a><spanclass="lineno"> 92</span> <spanclass="comment">// the IB cut pool if it is the case.</span></div>
<divclass="line"><aname="l00098"></a><spanclass="lineno"> 98</span> <spanclass="comment">// Substituting back the slack created by the function above should give</span></div>
<divclass="line"><aname="l00099"></a><spanclass="lineno"> 99</span> <spanclass="comment">// exactly the same cut as the original one.</span></div>
<divclass="line"><aname="l00105"></a><spanclass="lineno"> 105</span> <spanclass="comment">// Add a new variable that could be used in the new cuts.</span></div>
<divclass="line"><aname="l00108"></a><spanclass="lineno"> 108</span> <spanclass="comment">// Must be called before we process any constraints with a different</span></div>
<divclass="line"><aname="l00109"></a><spanclass="lineno"> 109</span> <spanclass="comment">// lp_values or level zero bounds.</span></div>
<divclass="line"><aname="l00121"></a><spanclass="lineno"> 121</span> <spanclass="comment">// As we compute the best implied bounds for each variable, we add violated</span></div>
<divclass="line"><aname="l00139"></a><spanclass="lineno"> 139</span> <spanclass="comment">// Temporary memory used by ProcessUpperBoundedConstraint().</span></div>
<divclass="line"><aname="l00143"></a><spanclass="lineno"> 143</span> <spanclass="comment">// Visible for testing. Returns a function f on integers such that:</span></div>
<divclass="line"><aname="l00144"></a><spanclass="lineno"> 144</span> <spanclass="comment">// - f is non-decreasing.</span></div>
<divclass="line"><aname="l00145"></a><spanclass="lineno"> 145</span> <spanclass="comment">// - f is super-additive: f(a) + f(b) <= f(a + b)</span></div>
<divclass="line"><aname="l00147"></a><spanclass="lineno"> 147</span> <spanclass="comment">// - For all x, f(x * divisor) = x * f(divisor)</span></div>
<divclass="line"><aname="l00148"></a><spanclass="lineno"> 148</span> <spanclass="comment">// - For all x, f(x * divisor + remainder) = x * f(divisor)</span></div>
<divclass="line"><aname="l00154"></a><spanclass="lineno"> 154</span> <spanclass="comment">// This is used in IntegerRoundingCut() and is responsible for "strengthening"</span></div>
<divclass="line"><aname="l00155"></a><spanclass="lineno"> 155</span> <spanclass="comment">// the cut. Just taking f(x) = x / divisor result in the non-strengthened cut</span></div>
<divclass="line"><aname="l00156"></a><spanclass="lineno"> 156</span> <spanclass="comment">// and using any function that stricly dominate this one is better.</span></div>
<divclass="line"><aname="l00159"></a><spanclass="lineno"> 159</span> <spanclass="comment">// - We first scale by a factor t so that rhs_remainder >= divisor / 2.</span></div>
<divclass="line"><aname="l00160"></a><spanclass="lineno"> 160</span> <spanclass="comment">// - Then, if max_scaling == 2, we use the function described</span></div>
<divclass="line"><aname="l00161"></a><spanclass="lineno"> 161</span> <spanclass="comment">// in "Strenghtening Chvatal-Gomory cuts and Gomory fractional cuts", Adam N.</span></div>
<divclass="line"><aname="l00162"></a><spanclass="lineno"> 162</span> <spanclass="comment">// Letchfrod, Andrea Lodi.</span></div>
<divclass="line"><aname="l00163"></a><spanclass="lineno"> 163</span> <spanclass="comment">// - Otherwise, we use a generalization of this which is a discretized version</span></div>
<divclass="line"><aname="l00164"></a><spanclass="lineno"> 164</span> <spanclass="comment">// of the classical MIR rounding function that only take the value of the</span></div>
<divclass="line"><aname="l00165"></a><spanclass="lineno"> 165</span> <spanclass="comment">// form "an_integer / max_scaling". As max_scaling goes to infinity, this</span></div>
<divclass="line"><aname="l00166"></a><spanclass="lineno"> 166</span> <spanclass="comment">// converge to the real-valued MIR function.</span></div>
<divclass="line"><aname="l00168"></a><spanclass="lineno"> 168</span> <spanclass="comment">// Note that for each value of max_scaling we will get a different function.</span></div>
<divclass="line"><aname="l00169"></a><spanclass="lineno"> 169</span> <spanclass="comment">// And that there is no dominance relation between any of these functions. So</span></div>
<divclass="line"><aname="l00170"></a><spanclass="lineno"> 170</span> <spanclass="comment">// it could be nice to try to generate a cut using different values of</span></div>
<divclass="line"><aname="l00178"></a><spanclass="lineno"> 178</span> <spanclass="comment">// Given an upper bounded linear constraint, this function tries to transform it</span></div>
<divclass="line"><aname="l00179"></a><spanclass="lineno"> 179</span> <spanclass="comment">// to a valid cut that violate the given LP solution using integer rounding.</span></div>
<divclass="line"><aname="l00180"></a><spanclass="lineno"> 180</span> <spanclass="comment">// Note that the returned cut might not always violate the LP solution, in which</span></div>
<divclass="line"><aname="l00181"></a><spanclass="lineno"> 181</span> <spanclass="comment">// case it can be discarded.</span></div>
<divclass="line"><aname="l00183"></a><spanclass="lineno"> 183</span> <spanclass="comment">// What this does is basically take the integer division of the constraint by an</span></div>
<divclass="line"><aname="l00184"></a><spanclass="lineno"> 184</span> <spanclass="comment">// integer. If the coefficients where doubles, this would be the same as scaling</span></div>
<divclass="line"><aname="l00185"></a><spanclass="lineno"> 185</span> <spanclass="comment">// the constraint and then rounding. We choose the coefficient of the most</span></div>
<divclass="line"><aname="l00186"></a><spanclass="lineno"> 186</span> <spanclass="comment">// fractional variable (rescaled by its coefficient) as the divisor, but there</span></div>
<divclass="line"><aname="l00187"></a><spanclass="lineno"> 187</span> <spanclass="comment">// are other possible alternatives.</span></div>
<divclass="line"><aname="l00189"></a><spanclass="lineno"> 189</span> <spanclass="comment">// Note that if the constraint is tight under the given lp solution, and if</span></div>
<divclass="line"><aname="l00190"></a><spanclass="lineno"> 190</span> <spanclass="comment">// there is a unique variable not at one of its bounds and fractional, then we</span></div>
<divclass="line"><aname="l00191"></a><spanclass="lineno"> 191</span> <spanclass="comment">// are guaranteed to generate a cut that violate the current LP solution. This</span></div>
<divclass="line"><aname="l00192"></a><spanclass="lineno"> 192</span> <spanclass="comment">// should be the case for Chvatal-Gomory base constraints modulo our loss of</span></div>
<divclass="line"><aname="l00193"></a><spanclass="lineno"> 193</span> <spanclass="comment">// precision while doing exact integer computations.</span></div>
<divclass="line"><aname="l00196"></a><spanclass="lineno"> 196</span> <spanclass="comment">// - We assumes that the given initial constraint is tight using the given lp</span></div>
<divclass="line"><aname="l00197"></a><spanclass="lineno"> 197</span> <spanclass="comment">// values. This could be relaxed, but for now it should always be the case, so</span></div>
<divclass="line"><aname="l00198"></a><spanclass="lineno"> 198</span> <spanclass="comment">// we log a message and abort if not, to ease debugging.</span></div>
<divclass="line"><aname="l00199"></a><spanclass="lineno"> 199</span> <spanclass="comment">// - The IntegerVariable of the cuts are not used here. We assumes that the</span></div>
<divclass="line"><aname="l00200"></a><spanclass="lineno"> 200</span> <spanclass="comment">// first three vectors are in one to one correspondence with the initial order</span></div>
<divclass="line"><aname="l00201"></a><spanclass="lineno"> 201</span> <spanclass="comment">// of the variable in the cut.</span></div>
<divclass="line"><aname="l00203"></a><spanclass="lineno"> 203</span> <spanclass="comment">// TODO(user): There is a bunch of heuristic involved here, and we could spend</span></div>
<divclass="line"><aname="l00204"></a><spanclass="lineno"> 204</span> <spanclass="comment">// more effort tunning them. In particular, one can try many heuristics and keep</span></div>
<divclass="line"><aname="l00205"></a><spanclass="lineno"> 205</span> <spanclass="comment">// the best looking cut (or more than one). This is not on the critical code</span></div>
<divclass="line"><aname="l00206"></a><spanclass="lineno"> 206</span> <spanclass="comment">// path, so we can spend more effort in finding good cuts.</span></div>
<divclass="line"><aname="l00217"></a><spanclass="lineno"> 217</span> <spanclass="comment">// Returns the number of implied bound lifted Booleans in the last</span></div>
<divclass="line"><aname="l00218"></a><spanclass="lineno"> 218</span> <spanclass="comment">// ComputeCut() call. Useful for investigation.</span></div>
<divclass="line"><aname="l00222"></a><spanclass="lineno"> 222</span> <spanclass="comment">// The helper is just here to reuse the memory for these vectors.</span></div>
<divclass="line"><aname="l00241"></a><spanclass="lineno"> 241</span> <spanclass="comment">// Try to find a cut with a knapsack heuristic.</span></div>
<divclass="line"><aname="l00242"></a><spanclass="lineno"> 242</span> <spanclass="comment">// If this returns true, you can get the cut via cut().</span></div>
<divclass="line"><aname="l00248"></a><spanclass="lineno"> 248</span> <spanclass="comment">// If successful, info about the last generated cut.</span></div>
<divclass="line"><aname="l00252"></a><spanclass="lineno"> 252</span> <spanclass="comment">// Single line of text that we append to the cut log line.</span></div>
<divclass="line"><aname="l00259"></a><spanclass="lineno"> 259</span>  IntegerValue positive_coeff; <spanclass="comment">// abs(coeff in original constraint).</span></div>
<divclass="line"><aname="l00269"></a><spanclass="lineno"> 269</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="l00270"></a><spanclass="lineno"> 270</span> <spanclass="comment">// cannot be part of a cover that will violate the lp solution. This method</span></div>
<divclass="line"><aname="l00271"></a><spanclass="lineno"> 271</span> <spanclass="comment">// returns a reduced constraint by removing such variables from the given</span></div>
<divclass="line"><aname="l00278"></a><spanclass="lineno"> 278</span> <spanclass="comment">// Returns true if sum of all the variables in the given constraint is less than</span></div>
<divclass="line"><aname="l00279"></a><spanclass="lineno"> 279</span> <spanclass="comment">// or equal to constraint upper bound. This method assumes that all the</span></div>
<divclass="line"><aname="l00280"></a><spanclass="lineno"> 280</span> <spanclass="comment">// coefficients are non negative.</span></div>
<divclass="line"><aname="l00284"></a><spanclass="lineno"> 284</span> <spanclass="comment">// If the left variables in lp solution satisfies following inequality, we prove</span></div>
<divclass="line"><aname="l00285"></a><spanclass="lineno"> 285</span> <spanclass="comment">// that there does not exist any knapsack cut which is violated by the solution.</span></div>
<divclass="line"><aname="l00286"></a><spanclass="lineno"> 286</span> <spanclass="comment">// Let |Cmin| = smallest possible cover size.</span></div>
<divclass="line"><aname="l00287"></a><spanclass="lineno"> 287</span> <spanclass="comment">// Let S = smallest (var_ub - lp_values[var]) first |Cmin| variables.</span></div>
<divclass="line"><aname="l00288"></a><spanclass="lineno"> 288</span> <spanclass="comment">// Let cut lower bound = sum_(var in S)(var_ub - lp_values[var])</span></div>
<divclass="line"><aname="l00289"></a><spanclass="lineno"> 289</span> <spanclass="comment">// For any cover,</span></div>
<divclass="line"><aname="l00290"></a><spanclass="lineno"> 290</span> <spanclass="comment">// If cut lower bound >= 1</span></div>
<divclass="line"><aname="l00291"></a><spanclass="lineno"> 291</span> <spanclass="comment">// ==> sum_(var in S)(var_ub - lp_values[var]) >= 1</span></div>
<divclass="line"><aname="l00292"></a><spanclass="lineno"> 292</span> <spanclass="comment">// ==> sum_(var in cover)(var_ub - lp_values[var]) >= 1</span></div>
<divclass="line"><aname="l00293"></a><spanclass="lineno"> 293</span> <spanclass="comment">// ==> The solution already satisfies cover. Since this is true for all covers,</span></div>
<divclass="line"><aname="l00294"></a><spanclass="lineno"> 294</span> <spanclass="comment">// this method returns false in such cases.</span></div>
<divclass="line"><aname="l00295"></a><spanclass="lineno"> 295</span> <spanclass="comment">// This method assumes that the constraint is preprocessed and has only non</span></div>
<divclass="line"><aname="l00302"></a><spanclass="lineno"> 302</span> <spanclass="comment">// Struct to help compute upper bound for knapsack instance.</span></div>
<divclass="line"><aname="l00311"></a><spanclass="lineno"> 311</span> <spanclass="comment">// Gets upper bound on profit for knapsack instance by solving the linear</span></div>
<divclass="line"><aname="l00315"></a><spanclass="lineno"> 315</span> <spanclass="comment">// Returns true if the linear relaxation upper bound for the knapsack instance</span></div>
<divclass="line"><aname="l00316"></a><spanclass="lineno"> 316</span> <spanclass="comment">// shows that this constraint cannot be used to form a cut. This method assumes</span></div>
<divclass="line"><aname="l00317"></a><spanclass="lineno"> 317</span> <spanclass="comment">// that all the coefficients are non negative.</span></div>
<divclass="line"><aname="l00323"></a><spanclass="lineno"> 323</span> <spanclass="comment">// Returns true if the given constraint passes all the filters described above.</span></div>
<divclass="line"><aname="l00324"></a><spanclass="lineno"> 324</span> <spanclass="comment">// This method assumes that the constraint is preprocessed and has only non</span></div>
<divclass="line"><aname="l00331"></a><spanclass="lineno"> 331</span> <spanclass="comment">// Converts the given constraint into canonical knapsack form (described</span></div>
<divclass="line"><aname="l00332"></a><spanclass="lineno"> 332</span> <spanclass="comment">// below) and adds it to 'knapsack_constraints'.</span></div>
<divclass="line"><aname="l00334"></a><spanclass="lineno"> 334</span> <spanclass="comment">// - Constraint has finite upper bound.</span></div>
<divclass="line"><aname="l00335"></a><spanclass="lineno"> 335</span> <spanclass="comment">// - All coefficients are positive.</span></div>
<divclass="line"><aname="l00336"></a><spanclass="lineno"> 336</span> <spanclass="comment">// For constraint with finite lower bound, this method also adds the negation of</span></div>
<divclass="line"><aname="l00337"></a><spanclass="lineno"> 337</span> <spanclass="comment">// the given constraint after converting it to canonical knapsack form.</span></div>
<divclass="line"><aname="l00342"></a><spanclass="lineno"> 342</span> <spanclass="comment">// Returns true if the cut is lifted. Lifting procedure is described below.</span></div>
<divclass="line"><aname="l00344"></a><spanclass="lineno"> 344</span> <spanclass="comment">// First we decide a lifting sequence for the binary variables which are not</span></div>
<divclass="line"><aname="l00345"></a><spanclass="lineno"> 345</span> <spanclass="comment">// already in cut. We lift the cut for each lifting candidate one by one.</span></div>
<divclass="line"><aname="l00347"></a><spanclass="lineno"> 347</span> <spanclass="comment">// Given the original constraint where the lifting candidate is fixed to one, we</span></div>
<divclass="line"><aname="l00348"></a><spanclass="lineno"> 348</span> <spanclass="comment">// compute the maximum value the cut can take and still be feasible using a</span></div>
<divclass="line"><aname="l00349"></a><spanclass="lineno"> 349</span> <spanclass="comment">// knapsack problem. We can then lift the variable in the cut using the</span></div>
<divclass="line"><aname="l00350"></a><spanclass="lineno"> 350</span> <spanclass="comment">// difference between the cut upper bound and this maximum value.</span></div>
<divclass="line"><aname="l00358"></a><spanclass="lineno"> 358</span> <spanclass="comment">// A cut generator that creates knpasack cover cuts.</span></div>
<divclass="line"><aname="l00362"></a><spanclass="lineno"> 362</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="l00363"></a><spanclass="lineno"> 363</span> <spanclass="comment">// subset C of {1 , .. , n} such that \sum_{c \in C}(a_c * u_c) > b.</span></div>
<divclass="line"><aname="l00365"></a><spanclass="lineno"> 365</span> <spanclass="comment">// A knapsack cover cut is a constraint of the form</span></div>
<divclass="line"><aname="l00367"></a><spanclass="lineno"> 367</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="l00368"></a><spanclass="lineno"> 368</span> <spanclass="comment">// In other words, in a feasible solution, at least some of the variables do</span></div>
<divclass="line"><aname="l00369"></a><spanclass="lineno"> 369</span> <spanclass="comment">// not take their maximum value.</span></div>
<divclass="line"><aname="l00371"></a><spanclass="lineno"> 371</span> <spanclass="comment">// If all x_i are binary variables then the cover cut becomes</span></div>
<divclass="line"><aname="l00374"></a><spanclass="lineno"> 374</span> <spanclass="comment">// The major difficulty for generating Knapsack cover cuts is finding a minimal</span></div>
<divclass="line"><aname="l00375"></a><spanclass="lineno"> 375</span> <spanclass="comment">// cover set C that cut a given floating point solution. There are many ways to</span></div>
<divclass="line"><aname="l00376"></a><spanclass="lineno"> 376</span> <spanclass="comment">// heuristically generate the cover but the following method that uses a</span></div>
<divclass="line"><aname="l00377"></a><spanclass="lineno"> 377</span> <spanclass="comment">// solution of the LP relaxation of the constraint works the best.</span></div>
<divclass="line"><aname="l00379"></a><spanclass="lineno"> 379</span> <spanclass="comment">// Look at a given linear relaxation solution for the integer problem x'</span></div>
<divclass="line"><aname="l00380"></a><spanclass="lineno"> 380</span> <spanclass="comment">// and try to solve the following knapsack problem:</span></div>
<divclass="line"><aname="l00382"></a><spanclass="lineno"> 382</span> <spanclass="comment">// such that \sum_{i=1..n}(a_i * u_i * z_i) > b,</span></div>
<divclass="line"><aname="l00383"></a><spanclass="lineno"> 383</span> <spanclass="comment">// where z_i is a binary decision variable and x_i' are values of the variables</span></div>
<divclass="line"><aname="l00384"></a><spanclass="lineno"> 384</span> <spanclass="comment">// in the given relaxation solution x'. If the objective of the optimal solution</span></div>
<divclass="line"><aname="l00385"></a><spanclass="lineno"> 385</span> <spanclass="comment">// of this problem is less than 1, this algorithm does not generate any cuts.</span></div>
<divclass="line"><aname="l00386"></a><spanclass="lineno"> 386</span> <spanclass="comment">// Otherwise, it adds a knapsack cover cut in the form</span></div>
<divclass="line"><aname="l00388"></a><spanclass="lineno"> 388</span> <spanclass="comment">// where z_i' is the value of z_i in the optimal solution of the above</span></div>
<divclass="line"><aname="l00389"></a><spanclass="lineno"> 389</span> <spanclass="comment">// problem and cb is the upper bound for the cut constraint. Note that the above</span></div>
<divclass="line"><aname="l00390"></a><spanclass="lineno"> 390</span> <spanclass="comment">// problem can be converted into a standard kanpsack form by replacing z_i by 1</span></div>
<divclass="line"><aname="l00391"></a><spanclass="lineno"> 391</span> <spanclass="comment">// - y_i. In that case the problem becomes</span></div>
<divclass="line"><aname="l00396"></a><spanclass="lineno"> 396</span> <spanclass="comment">// Solving this knapsack instance would help us find the smallest cover with</span></div>
<divclass="line"><aname="l00397"></a><spanclass="lineno"> 397</span> <spanclass="comment">// maximum LP violation.</span></div>
<divclass="line"><aname="l00400"></a><spanclass="lineno"> 400</span> <spanclass="comment">// Let lambda = \sum_{c \in C}(a_c * u_c) - b and max_coeff = \max_{c</span></div>
<divclass="line"><aname="l00401"></a><spanclass="lineno"> 401</span> <spanclass="comment">// \in C}(a_c), then cut can be strengthened as</span></div>
<divclass="line"><aname="l00404"></a><spanclass="lineno"> 404</span> <spanclass="comment">// For further information about knapsack cover cuts see</span></div>
<divclass="line"><aname="l00405"></a><spanclass="lineno"> 405</span> <spanclass="comment">// A. Atamtürk, Cover and Pack Inequalities for (Mixed) Integer Programming</span></div>
<divclass="line"><aname="l00406"></a><spanclass="lineno"> 406</span> <spanclass="comment">// Annals of Operations Research Volume 139, Issue 1 , pp 21-38, 2005.</span></div>
<divclass="line"><aname="l00412"></a><spanclass="lineno"> 412</span> <spanclass="comment">// A cut generator for z = x * y (x and y >= 0).</span></div>
<divclass="line"><aname="l00418"></a><spanclass="lineno"> 418</span> <spanclass="comment">// A cut generator for y = x ^ 2 (x >= 0).</span></div>
<divclass="line"><aname="l00419"></a><spanclass="lineno"> 419</span> <spanclass="comment">// It will dynamically add a linear inequality to push y closer to the parabola.</span></div>
<divclass="line"><aname="l00420"></a><spanclass="lineno"> 420</span> CutGenerator <aclass="code"href="namespaceoperations__research_1_1sat.html#a562723a1a137cee8f869c1d7eb9641b0">CreateSquareCutGenerator</a>(IntegerVariable y, IntegerVariable x,</div>
<divclass="line"><aname="l00423"></a><spanclass="lineno"> 423</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="l00424"></a><spanclass="lineno"> 424</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="l00425"></a><spanclass="lineno"> 425</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="l00426"></a><spanclass="lineno"> 426</span> <spanclass="comment">// D. The cut generator first sorts the variables based on LP values and adds</span></div>
<divclass="line"><aname="l00427"></a><spanclass="lineno"> 427</span> <spanclass="comment">// cuts of the form described above if they are violated by lp solution. Note</span></div>
<divclass="line"><aname="l00428"></a><spanclass="lineno"> 428</span> <spanclass="comment">// that all the fixed variables are ignored while generating cuts.</span></div>
<divclass="line"><aname="l00432"></a><spanclass="lineno"> 432</span> <spanclass="comment">// Consider the Lin Max constraint with d expressions and n variables in the</span></div>
<divclass="line"><aname="l00433"></a><spanclass="lineno"> 433</span> <spanclass="comment">// form: target = max {exprs[k] = Sum (wki * xi + bk)}. k in {1,..,d}.</span></div>
<divclass="line"><aname="l00434"></a><spanclass="lineno"> 434</span> <spanclass="comment">// Li = lower bound of xi</span></div>
<divclass="line"><aname="l00435"></a><spanclass="lineno"> 435</span> <spanclass="comment">// Ui = upper bound of xi.</span></div>
<divclass="line"><aname="l00436"></a><spanclass="lineno"> 436</span> <spanclass="comment">// Let zk be in {0,1} for all k in {1,..,d}.</span></div>
<divclass="line"><aname="l00437"></a><spanclass="lineno"> 437</span> <spanclass="comment">// The target = exprs[k] when zk = 1.</span></div>
<divclass="line"><aname="l00439"></a><spanclass="lineno"> 439</span> <spanclass="comment">// The following is a valid linearization for Lin Max.</span></div>
<divclass="line"><aname="l00440"></a><spanclass="lineno"> 440</span> <spanclass="comment">// target >= exprs[k], for all k in {1,..,d}</span></div>
<divclass="line"><aname="l00441"></a><spanclass="lineno"> 441</span> <spanclass="comment">// target <= Sum (wli * xi) + Sum((Nlk + bk) * zk), for all l in {1,..,d}</span></div>
<divclass="line"><aname="l00442"></a><spanclass="lineno"> 442</span> <spanclass="comment">// Where Nlk is a large number defined as:</span></div>
<divclass="line"><aname="l00444"></a><spanclass="lineno"> 444</span> <spanclass="comment">// = Sum (max corner difference for variable i, target expr l, max expr k)</span></div>
<divclass="line"><aname="l00446"></a><spanclass="lineno"> 446</span> <spanclass="comment">// Consider a partition of variables xi into set {1,..,d} as I.</span></div>
<divclass="line"><aname="l00447"></a><spanclass="lineno"> 447</span> <spanclass="comment">// i.e. I(i) = j means xi is mapped to jth index.</span></div>
<divclass="line"><aname="l00448"></a><spanclass="lineno"> 448</span> <spanclass="comment">// The following inequality is valid and sharp cut for the lin max constraint</span></div>
<divclass="line"><aname="l00449"></a><spanclass="lineno"> 449</span> <spanclass="comment">// described above.</span></div>
<divclass="line"><aname="l00458"></a><spanclass="lineno"> 458</span> <spanclass="comment">// For detailed proof of validity, refer</span></div>
<divclass="line"><aname="l00459"></a><spanclass="lineno"> 459</span> <spanclass="comment">// Reference: "Strong mixed-integer programming formulations for trained neural</span></div>
<divclass="line"><aname="l00460"></a><spanclass="lineno"> 460</span> <spanclass="comment">// networks" by Ross Anderson et. (https://arxiv.org/pdf/1811.01988.pdf).</span></div>
<divclass="line"><aname="l00462"></a><spanclass="lineno"> 462</span> <spanclass="comment">// In the cut generator, we compute the most violated partition I by computing</span></div>
<divclass="line"><aname="l00463"></a><spanclass="lineno"> 463</span> <spanclass="comment">// the rhs value (wI(i)i * lp_value(xi) + Sum(k=1..d)(MPlusCoefficient_ki * zk))</span></div>
<divclass="line"><aname="l00464"></a><spanclass="lineno"> 464</span> <spanclass="comment">// for each variable for each partition index. We choose the partition index</span></div>
<divclass="line"><aname="l00465"></a><spanclass="lineno"> 465</span> <spanclass="comment">// that gives lowest rhs value for a given variable.</span></div>
<divclass="line"><aname="l00467"></a><spanclass="lineno"> 467</span> <spanclass="comment">// Note: This cut generator requires all expressions to contain only positive</span></div>
<divclass="line"><aname="l00473"></a><spanclass="lineno"> 473</span> <spanclass="comment">// For a given set of intervals and demands, we compute the maximum energy of</span></div>
<divclass="line"><aname="l00474"></a><spanclass="lineno"> 474</span> <spanclass="comment">// each task and make sure it is less than the span of the intervals * its</span></div>
<divclass="line"><aname="l00477"></a><spanclass="lineno"> 477</span> <spanclass="comment">// If an interval is optional, it contributes</span></div>
<divclass="line"><aname="l00481"></a><spanclass="lineno"> 481</span> <spanclass="comment">// If an interval is performed, it contributes either min_demand * size or</span></div>
<divclass="line"><aname="l00482"></a><spanclass="lineno"> 482</span> <spanclass="comment">// demand * min_size. We choose the most violated formulation.</span></div>
<divclass="line"><aname="l00484"></a><spanclass="lineno"> 484</span> <spanclass="comment">// The maximum energy is capacity * span of intervals at level 0.</span></div>
<divclass="line"><aname="l00490"></a><spanclass="lineno"> 490</span> <spanclass="comment">// For a given set of intervals and demands, we first compute the mandatory part</span></div>
<divclass="line"><aname="l00491"></a><spanclass="lineno"> 491</span> <spanclass="comment">// of the interval as [start_max , end_min]. We use this to calculate mandatory</span></div>
<divclass="line"><aname="l00492"></a><spanclass="lineno"> 492</span> <spanclass="comment">// demands for each start_max time points for eligible intervals.</span></div>
<divclass="line"><aname="l00493"></a><spanclass="lineno"> 493</span> <spanclass="comment">// Since the sum of these mandatory demands must be smaller or equal to the</span></div>
<divclass="line"><aname="l00494"></a><spanclass="lineno"> 494</span> <spanclass="comment">// capacity, we create a cut representing that.</span></div>
<divclass="line"><aname="l00496"></a><spanclass="lineno"> 496</span> <spanclass="comment">// If an interval is optional, it contributes min_demand * presence_literal</span></div>
<divclass="line"><aname="l00497"></a><spanclass="lineno"> 497</span> <spanclass="comment">// amount of demand to the mandatory demands sum. So the final cut is generated</span></div>
<divclass="line"><aname="l00498"></a><spanclass="lineno"> 498</span> <spanclass="comment">// as follows:</span></div>
<divclass="line"><aname="l00499"></a><spanclass="lineno"> 499</span> <spanclass="comment">// sum(demands of always present intervals)</span></div>
<divclass="line"><aname="l00506"></a><spanclass="lineno"> 506</span> <spanclass="comment">// For a given set of intervals, we first compute the min and max of all</span></div>
<divclass="line"><aname="l00507"></a><spanclass="lineno"> 507</span> <spanclass="comment">// intervals. Then we create a cut that indicates that all intervals must fit</span></div>
<divclass="line"><aname="l00508"></a><spanclass="lineno"> 508</span> <spanclass="comment">// in that span.</span></div>
<divclass="line"><aname="l00510"></a><spanclass="lineno"> 510</span> <spanclass="comment">// If an interval is optional, it contributes min_size * presence_literal</span></div>
<divclass="line"><aname="l00511"></a><spanclass="lineno"> 511</span> <spanclass="comment">// amount of demand to the mandatory demands sum. So the final cut is generated</span></div>
<divclass="line"><aname="l00512"></a><spanclass="lineno"> 512</span> <spanclass="comment">// as follows:</span></div>
<divclass="line"><aname="l00513"></a><spanclass="lineno"> 513</span> <spanclass="comment">// sum(sizes of always present intervals)</span></div>
<divclass="line"><aname="l00514"></a><spanclass="lineno"> 514</span> <spanclass="comment">// + sum(presence_literal * min_of_size) <= span of all intervals.</span></div>
<divclass="line"><aname="l00518"></a><spanclass="lineno"> 518</span> <spanclass="comment">// For a given set of intervals in a no_overlap constraint, we detect violated</span></div>
<divclass="line"><aname="l00519"></a><spanclass="lineno"> 519</span> <spanclass="comment">// mandatory precedences and create a cut for these.</span></div>
<divclass="line"><aname="l00523"></a><spanclass="lineno"> 523</span> <spanclass="comment">// Extracts the variables that have a Literal view from base variables and</span></div>
<divclass="line"><aname="l00524"></a><spanclass="lineno"> 524</span> <spanclass="comment">// create a generator that will returns constraint of the form "at_most_one"</span></div>
<divclass="line"><aname="l00525"></a><spanclass="lineno"> 525</span> <spanclass="comment">// between such literals.</span></div>
<divclass="ttc"id="anamespaceoperations__research_html"><divclass="ttname"><ahref="namespaceoperations__research.html">operations_research</a></div><divclass="ttdoc">The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...</div><divclass="ttdef"><b>Definition:</b><ahref="dense__doubly__linked__list_8h_source.html#l00021">dense_doubly_linked_list.h:21</a></div></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="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#l01421">cuts.cc:1421</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#l00123">cuts.h:123</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#l01325">cuts.cc:1325</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#l00250">cuts.h:250</a></div></div>