<ahref="cp__model__presolve_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="l00038"name="l00038"></a><spanclass="lineno"> 38</span><spanclass="comment">// Replaces all the instance of a variable i (and the literals referring to it)</span></div>
<divclass="line"><aid="l00039"name="l00039"></a><spanclass="lineno"> 39</span><spanclass="comment">// by mapping[i]. The definition of variables i is also moved to its new index.</span></div>
<divclass="line"><aid="l00040"name="l00040"></a><spanclass="lineno"> 40</span><spanclass="comment">// Variables with a negative mapping value are ignored and it is an error if</span></div>
<divclass="line"><aid="l00041"name="l00041"></a><spanclass="lineno"> 41</span><spanclass="comment">// such variable is referenced anywhere (this is CHECKed).</span></div>
<divclass="line"><aid="l00043"name="l00043"></a><spanclass="lineno"> 43</span><spanclass="comment">// The image of the mapping should be dense in [0, new_num_variables), this is</span></div>
<divclass="line"><aid="l00044"name="l00044"></a><spanclass="lineno"> 44</span><spanclass="comment">// also CHECKed.</span></div>
<divclass="line"><aid="l00048"name="l00048"></a><spanclass="lineno"> 48</span><spanclass="comment">// Presolves the initial content of presolved_model.</span></div>
<divclass="line"><aid="l00050"name="l00050"></a><spanclass="lineno"> 50</span><spanclass="comment">// This also creates a mapping model that encode the correspondence between the</span></div>
<divclass="line"><aid="l00051"name="l00051"></a><spanclass="lineno"> 51</span><spanclass="comment">// two problems. This works as follow:</span></div>
<divclass="line"><aid="l00052"name="l00052"></a><spanclass="lineno"> 52</span><spanclass="comment">// - The first variables of mapping_model are in one to one correspondence with</span></div>
<divclass="line"><aid="l00053"name="l00053"></a><spanclass="lineno"> 53</span><spanclass="comment">// the variables of the initial model.</span></div>
<divclass="line"><aid="l00054"name="l00054"></a><spanclass="lineno"> 54</span><spanclass="comment">// - The presolved_model variables are in one to one correspondence with the</span></div>
<divclass="line"><aid="l00055"name="l00055"></a><spanclass="lineno"> 55</span><spanclass="comment">// variable at the indices given by postsolve_mapping in the mapping model.</span></div>
<divclass="line"><aid="l00056"name="l00056"></a><spanclass="lineno"> 56</span><spanclass="comment">// - Fixing one of the two sets of variables and solving the model will assign</span></div>
<divclass="line"><aid="l00057"name="l00057"></a><spanclass="lineno"> 57</span><spanclass="comment">// the other set to a feasible solution of the other problem. Moreover, the</span></div>
<divclass="line"><aid="l00058"name="l00058"></a><spanclass="lineno"> 58</span><spanclass="comment">// objective value of these solutions will be the same. Note that solving such</span></div>
<divclass="line"><aid="l00059"name="l00059"></a><spanclass="lineno"> 59</span><spanclass="comment">// problems will take little time in practice because the propagation will</span></div>
<divclass="line"><aid="l00060"name="l00060"></a><spanclass="lineno"> 60</span><spanclass="comment">// basically do all the work.</span></div>
<divclass="line"><aid="l00062"name="l00062"></a><spanclass="lineno"> 62</span><spanclass="comment">// Note(user): an optimization model can be transformed into a decision problem,</span></div>
<divclass="line"><aid="l00063"name="l00063"></a><spanclass="lineno"> 63</span><spanclass="comment">// if for instance the objective is fixed, or independent from the rest of the</span></div>
<divclass="line"><aid="l00066"name="l00066"></a><spanclass="lineno"> 66</span><spanclass="comment">// TODO(user): Identify disconnected components and returns a vector of</span></div>
<divclass="line"><aid="l00067"name="l00067"></a><spanclass="lineno"> 67</span><spanclass="comment">// presolved model? If we go this route, it may be nicer to store the indices</span></div>
<divclass="line"><aid="l00068"name="l00068"></a><spanclass="lineno"> 68</span><spanclass="comment">// inside the model. We can add a IntegerVariableProto::initial_index;</span></div>
<divclass="line"><aid="l00074"name="l00074"></a><spanclass="lineno"> 74</span><spanclass="comment">// We returns the status of the problem after presolve:</span></div>
<divclass="line"><aid="l00075"name="l00075"></a><spanclass="lineno"> 75</span><spanclass="comment">// - UNKNOWN if everything was ok.</span></div>
<divclass="line"><aid="l00076"name="l00076"></a><spanclass="lineno"> 76</span><spanclass="comment">// - INFEASIBLE if the model was proven so during presolve</span></div>
<divclass="line"><aid="l00077"name="l00077"></a><spanclass="lineno"> 77</span><spanclass="comment">// - MODEL_INVALID if the model caused some issues, like if we are not able</span></div>
<divclass="line"><aid="l00078"name="l00078"></a><spanclass="lineno"> 78</span><spanclass="comment">// to scale a floating point objective with enough precision.</span></div>
<divclass="line"><aid="l00081"name="l00081"></a><spanclass="lineno"> 81</span><spanclass="comment">// Executes presolve method for the given constraint. Public for testing only.</span></div>
<divclass="line"><aid="l00088"name="l00088"></a><spanclass="lineno"> 88</span><spanclass="comment">// A simple helper that logs the rules applied so far and return INFEASIBLE.</span></div>
<divclass="line"><aid="l00091"name="l00091"></a><spanclass="lineno"> 91</span><spanclass="comment">// Runs the inner loop of the presolver.</span></div>
<divclass="line"><aid="l00099"name="l00099"></a><spanclass="lineno"> 99</span><spanclass="comment">// They should return false only if the constraint <-> variable graph didn't</span></div>
<divclass="line"><aid="l00100"name="l00100"></a><spanclass="lineno"> 100</span><spanclass="comment">// change. This is just an optimization, returning true is always correct.</span></div>
<divclass="line"><aid="l00102"name="l00102"></a><spanclass="lineno"> 102</span><spanclass="comment">// Invariant about UNSAT: All these functions should abort right away if</span></div>
<divclass="line"><aid="l00103"name="l00103"></a><spanclass="lineno"> 103</span><spanclass="comment">// context_.IsUnsat() is true. And the only way to change the status to unsat</span></div>
<divclass="line"><aid="l00104"name="l00104"></a><spanclass="lineno"> 104</span><spanclass="comment">// is through ABSL_MUST_USE_RESULT function that should also abort right away</span></div>
<divclass="line"><aid="l00105"name="l00105"></a><spanclass="lineno"> 105</span><spanclass="comment">// the current code. This way we shouldn't keep doing computation on an</span></div>
<divclass="line"><aid="l00107"name="l00107"></a><spanclass="lineno"> 107</span><spanclass="comment">// TODO(user): Make these public and unit test.</span></div>
<divclass="line"><aid="l00137"name="l00137"></a><spanclass="lineno"> 137</span><spanclass="comment">// Regroups terms and substitute affine relations.</span></div>
<divclass="line"><aid="l00138"name="l00138"></a><spanclass="lineno"> 138</span><spanclass="comment">// Returns true if the set of variables in the expression changed.</span></div>
<divclass="line"><aid="l00148"name="l00148"></a><spanclass="lineno"> 148</span><spanclass="comment">// For the linear constraints, we have more than one function.</span></div>
<divclass="line"><aid="l00161"name="l00161"></a><spanclass="lineno"> 161</span><spanclass="comment">// If a constraint is of the form "a * expr_X + expr_Y" and expr_Y can only</span></div>
<divclass="line"><aid="l00162"name="l00162"></a><spanclass="lineno"> 162</span><spanclass="comment">// take small values compared to a, depending on the bounds, the constraint</span></div>
<divclass="line"><aid="l00163"name="l00163"></a><spanclass="lineno"> 163</span><spanclass="comment">// can be equivalent to a constraint on expr_X only.</span></div>
<divclass="line"><aid="l00165"name="l00165"></a><spanclass="lineno"> 165</span><spanclass="comment">// For instance "10'001 X + 9'999 Y <= 105'000, with X, Y in [0, 100]" can</span></div>
<divclass="line"><aid="l00166"name="l00166"></a><spanclass="lineno"> 166</span><spanclass="comment">// be rewritten as X + Y <= 10 ! This can easily happen after scaling to</span></div>
<divclass="line"><aid="l00167"name="l00167"></a><spanclass="lineno"> 167</span><spanclass="comment">// integer cofficient a floating point constraint.</span></div>
<divclass="line"><aid="l00170"name="l00170"></a><spanclass="lineno"> 170</span><spanclass="comment">// This detects and converts constraints of the form:</span></div>
<divclass="line"><aid="l00171"name="l00171"></a><spanclass="lineno"> 171</span><spanclass="comment">// "X = sum Boolean * value", with "sum Boolean <= 1".</span></div>
<divclass="line"><aid="l00173"name="l00173"></a><spanclass="lineno"> 173</span><spanclass="comment">// Note that it is not super fast, so it shouldn't be called too often.</span></div>
<divclass="line"><aid="l00180"name="l00180"></a><spanclass="lineno"> 180</span><spanclass="comment">// Remove duplicate constraints. This also merge domain of linear constraints</span></div>
<divclass="line"><aid="l00181"name="l00181"></a><spanclass="lineno"> 181</span><spanclass="comment">// with duplicate linear expressions.</span></div>
<divclass="line"><aid="l00184"name="l00184"></a><spanclass="lineno"> 184</span><spanclass="comment">// Detects if a linear constraint is "included" in another one, and do</span></div>
<divclass="line"><aid="l00185"name="l00185"></a><spanclass="lineno"> 185</span><spanclass="comment">// related presolve.</span></div>
<divclass="line"><aid="l00188"name="l00188"></a><spanclass="lineno"> 188</span><spanclass="comment">// Returns true if the domain of x is implied by the current constraints.</span></div>
<divclass="line"><aid="l00190"name="l00190"></a><spanclass="lineno"> 190</span><spanclass="comment">// Warning: this potentially scan all the constraint in which x appear.</span></div>
<divclass="line"><aid="l00191"name="l00191"></a><spanclass="lineno"> 191</span><spanclass="comment">// work_done will be incremented by the number of entries scanned.</span></div>
<divclass="line"><aid="l00195"name="l00195"></a><spanclass="lineno"> 195</span><spanclass="comment">// Detects if two columns that contains only linear constraints share a lot of</span></div>
<divclass="line"><aid="l00196"name="l00196"></a><spanclass="lineno"> 196</span><spanclass="comment">// common entries. Then calls PerformFreeColumnSubstitution() on promising</span></div>
<divclass="line"><aid="l00197"name="l00197"></a><spanclass="lineno"> 197</span><spanclass="comment">// candidate to reduce the overall number of non zeros.</span></div>
<divclass="line"><aid="l00200"name="l00200"></a><spanclass="lineno"> 200</span><spanclass="comment">// Assuming that x is implied free and only appear in linear constraints, this</span></div>
<divclass="line"><aid="l00201"name="l00201"></a><spanclass="lineno"> 201</span><spanclass="comment">// replace x by x + factor * y. This assumes that we precomputed all the</span></div>
<divclass="line"><aid="l00202"name="l00202"></a><spanclass="lineno"> 202</span><spanclass="comment">// constraints in which x appears and the coefficient of x inside.</span></div>
<divclass="line"><aid="l00207"name="l00207"></a><spanclass="lineno"> 207</span><spanclass="comment">// SetPPC is short for set packing, partitioning and covering constraints.</span></div>
<divclass="line"><aid="l00208"name="l00208"></a><spanclass="lineno"> 208</span><spanclass="comment">// These are sum of booleans <=, = and >= 1 respectively.</span></div>
<divclass="line"><aid="l00209"name="l00209"></a><spanclass="lineno"> 209</span><spanclass="comment">// We detect inclusion of these constraint which allows a few simplifications.</span></div>
<divclass="line"><aid="l00212"name="l00212"></a><spanclass="lineno"> 212</span><spanclass="comment">// Removes dominated constraints or fixes some variables for given pair of</span></div>
<divclass="line"><aid="l00213"name="l00213"></a><spanclass="lineno"> 213</span><spanclass="comment">// setppc constraints included in each other.</span></div>
<divclass="line"><aid="l00221"name="l00221"></a><spanclass="lineno"> 221</span><spanclass="comment">// Extracts AtMostOne constraint from Linear constraint.</span></div>
<divclass="line"><aid="l00224"name="l00224"></a><spanclass="lineno"> 224</span><spanclass="comment">// Returns true if the constraint changed.</span></div>
<divclass="line"><aid="l00230"name="l00230"></a><spanclass="lineno"> 230</span><spanclass="comment">// Extracts cliques from bool_and and small at_most_one constraints and</span></div>
<divclass="line"><aid="l00231"name="l00231"></a><spanclass="lineno"> 231</span><spanclass="comment">// transforms them into maximal cliques.</span></div>
<divclass="line"><aid="l00234"name="l00234"></a><spanclass="lineno"> 234</span><spanclass="comment">// Converts bool_or and at_most_one of size 2 to bool_and.</span></div>
<divclass="line"><aid="l00245"name="l00245"></a><spanclass="lineno"> 245</span><spanclass="comment">// Boths function are responsible for dealing with affine relations.</span></div>
<divclass="line"><aid="l00246"name="l00246"></a><spanclass="lineno"> 246</span><spanclass="comment">// The second one returns false on UNSAT.</span></div>
<divclass="line"><aid="l00259"name="l00259"></a><spanclass="lineno"> 259</span><spanclass="comment">// Used by CanonicalizeLinearExpressionInternal().</span></div>
<divclass="line"><aid="l00263"name="l00263"></a><spanclass="lineno"> 263</span><spanclass="comment">// This helper class perform copy with simplification from a model and a</span></div>
<divclass="line"><aid="l00264"name="l00264"></a><spanclass="lineno"> 264</span><spanclass="comment">// partial assignment to another model. The purpose is to miminize the size of</span></div>
<divclass="line"><aid="l00265"name="l00265"></a><spanclass="lineno"> 265</span><spanclass="comment">// the copied model, as well as to reduce the pressure on the memory sub-system.</span></div>
<divclass="line"><aid="l00267"name="l00267"></a><spanclass="lineno"> 267</span><spanclass="comment">// It is currently used by the LNS part, but could be used with any other scheme</span></div>
<divclass="line"><aid="l00268"name="l00268"></a><spanclass="lineno"> 268</span><spanclass="comment">// that generates partial assignments.</span></div>
<divclass="line"><aid="l00273"name="l00273"></a><spanclass="lineno"> 273</span><spanclass="comment">// Copies all constraints from in_model to working model of the context.</span></div>
<divclass="line"><aid="l00275"name="l00275"></a><spanclass="lineno"> 275</span><spanclass="comment">// During the process, it will read variable domains from the context, and</span></div>
<divclass="line"><aid="l00276"name="l00276"></a><spanclass="lineno"> 276</span><spanclass="comment">// simplify constraints to minimize the size of the copied model.</span></div>
<divclass="line"><aid="l00277"name="l00277"></a><spanclass="lineno"> 277</span><spanclass="comment">// Thus it is important that the context->working_model already have the</span></div>
<divclass="line"><aid="l00278"name="l00278"></a><spanclass="lineno"> 278</span><spanclass="comment">// variables part copied.</span></div>
<divclass="line"><aid="l00280"name="l00280"></a><spanclass="lineno"> 280</span><spanclass="comment">// It returns false iff the model is proven infeasible.</span></div>
<divclass="line"><aid="l00282"name="l00282"></a><spanclass="lineno"> 282</span><spanclass="comment">// It does not clear the constraints part of the working model of the context.</span></div>
<divclass="line"><aid="l00284"name="l00284"></a><spanclass="lineno"> 284</span><spanclass="comment">// Note(user): If first_copy is true, we will reorder the scheduling</span></div>
<divclass="line"><aid="l00285"name="l00285"></a><spanclass="lineno"> 285</span><spanclass="comment">// constraint so that they only use reference to previously defined intervals.</span></div>
<divclass="line"><aid="l00286"name="l00286"></a><spanclass="lineno"> 286</span><spanclass="comment">// This allow to be more efficient later in a few preprocessing steps.</span></div>
<divclass="line"><aid="l00291"name="l00291"></a><spanclass="lineno"> 291</span><spanclass="comment">// Copy variables from the in_model to the working model.</span></div>
<divclass="line"><aid="l00292"name="l00292"></a><spanclass="lineno"> 292</span><spanclass="comment">// It reads the 'ignore_names' parameters from the context, and keeps or</span></div>
<divclass="line"><aid="l00297"name="l00297"></a><spanclass="lineno"> 297</span><spanclass="comment">// Overwrites the out_model to be unsat. Returns false.</span></div>
<divclass="line"><aid="l00304"name="l00304"></a><spanclass="lineno"> 304</span><spanclass="comment">// All these functions return false if the constraint is found infeasible.</span></div>
<divclass="line"><aid="l00313"name="l00313"></a><spanclass="lineno"> 313</span><spanclass="comment">// These function remove unperformed intervals. Note that they requires</span></div>
<divclass="line"><aid="l00314"name="l00314"></a><spanclass="lineno"> 314</span><spanclass="comment">// interval to appear before (validated) as they test unperformed by testing</span></div>
<divclass="line"><aid="l00315"name="l00315"></a><spanclass="lineno"> 315</span><spanclass="comment">// if interval_mapping_ is empty.</span></div>
<divclass="line"><aid="l00334"name="l00334"></a><spanclass="lineno"> 334</span><spanclass="comment">// Copy in_model to the model in the presolve context.</span></div>
<divclass="line"><aid="l00335"name="l00335"></a><spanclass="lineno"> 335</span><spanclass="comment">// It performs on the fly simplification, and returns false if the</span></div>
<divclass="line"><aid="l00336"name="l00336"></a><spanclass="lineno"> 336</span><spanclass="comment">// model is proved infeasible. If reads the parameters 'ignore_names' and keeps</span></div>
<divclass="line"><aid="l00337"name="l00337"></a><spanclass="lineno"> 337</span><spanclass="comment">// or deletes variables and constraints names accordingly.</span></div>
<divclass="line"><aid="l00339"name="l00339"></a><spanclass="lineno"> 339</span><spanclass="comment">// This should only be called on the first copy of the user given model.</span></div>
<divclass="line"><aid="l00340"name="l00340"></a><spanclass="lineno"> 340</span><spanclass="comment">// Note that this reorder all constraints that use intervals last. We loose the</span></div>
<divclass="line"><aid="l00341"name="l00341"></a><spanclass="lineno"> 341</span><spanclass="comment">// user-defined order, but hopefully that should not matter too much.</span></div>
<divclass="line"><aid="l00345"name="l00345"></a><spanclass="lineno"> 345</span><spanclass="comment">// Copies the non constraint, non variables part of the model.</span></div>
<divclass="line"><aid="l00349"name="l00349"></a><spanclass="lineno"> 349</span><spanclass="comment">// Convenient wrapper to call the full presolve.</span></div>
<divclass="line"><aid="l00353"name="l00353"></a><spanclass="lineno"> 353</span><spanclass="comment">// Returns the index of duplicate constraints in the given proto in the first</span></div>
<divclass="line"><aid="l00354"name="l00354"></a><spanclass="lineno"> 354</span><spanclass="comment">// element of each pair. The second element of each pair is the "representative"</span></div>
<divclass="line"><aid="l00355"name="l00355"></a><spanclass="lineno"> 355</span><spanclass="comment">// that is the first constraint in the proto in a set of duplicate constraints.</span></div>
<divclass="line"><aid="l00357"name="l00357"></a><spanclass="lineno"> 357</span><spanclass="comment">// Empty constraints are ignored. We also do a bit more:</span></div>
<divclass="line"><aid="l00358"name="l00358"></a><spanclass="lineno"> 358</span><spanclass="comment">// - We ignore names when comparing constraint.</span></div>
<divclass="line"><aid="l00359"name="l00359"></a><spanclass="lineno"> 359</span><spanclass="comment">// - For linear constraints, we ignore the domain. This is because we can</span></div>
<divclass="line"><aid="l00360"name="l00360"></a><spanclass="lineno"> 360</span><spanclass="comment">// just merge them if the constraints are the same.</span></div>
<divclass="line"><aid="l00361"name="l00361"></a><spanclass="lineno"> 361</span><spanclass="comment">// - We return the special kObjectiveConstraint (< 0) representative if a linear</span></div>
<divclass="line"><aid="l00362"name="l00362"></a><spanclass="lineno"> 362</span><spanclass="comment">// constraint is parallel to the objective and has no enforcement literals.</span></div>
<divclass="line"><aid="l00363"name="l00363"></a><spanclass="lineno"> 363</span><spanclass="comment">// The domain of such constraint can just be merged with the objective domain.</span></div>
<divclass="line"><aid="l00365"name="l00365"></a><spanclass="lineno"> 365</span><spanclass="comment">// Visible here for testing. This is meant to be called at the end of the</span></div>
<divclass="line"><aid="l00366"name="l00366"></a><spanclass="lineno"> 366</span><spanclass="comment">// presolve where constraints have been canonicalized.</span></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>