<ahref="sat_2lp__utils_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="l00014"name="l00014"></a><spanclass="lineno"> 14</span><spanclass="comment">// Utility functions to interact with an lp solver from the SAT context.</span></div>
<divclass="line"><aid="l00035"name="l00035"></a><spanclass="lineno"> 35</span><spanclass="comment">// Returns the smallest factor f such that f * abs(x) is integer modulo the</span></div>
<divclass="line"><aid="l00036"name="l00036"></a><spanclass="lineno"> 36</span><spanclass="comment">// given tolerance relative to f (we use f * tolerance). It is only looking</span></div>
<divclass="line"><aid="l00037"name="l00037"></a><spanclass="lineno"> 37</span><spanclass="comment">// for f smaller than the given limit. Returns zero if no such factor exist.</span></div>
<divclass="line"><aid="l00039"name="l00039"></a><spanclass="lineno"> 39</span><spanclass="comment">// The complexity is a lot less than O(limit), but it is possible that we might</span></div>
<divclass="line"><aid="l00040"name="l00040"></a><spanclass="lineno"> 40</span><spanclass="comment">// miss the smallest such factor if the tolerance used is too low. This is</span></div>
<divclass="line"><aid="l00041"name="l00041"></a><spanclass="lineno"> 41</span><spanclass="comment">// because we only rely on the best rational approximations of x with increasing</span></div>
<divclass="line"><aid="l00045"name="l00045"></a><spanclass="lineno"> 45</span><spanclass="comment">// Multiplies all continuous variable by the given scaling parameters and change</span></div>
<divclass="line"><aid="l00046"name="l00046"></a><spanclass="lineno"> 46</span><spanclass="comment">// the rest of the model accordingly. The returned vector contains the scaling</span></div>
<divclass="line"><aid="l00047"name="l00047"></a><spanclass="lineno"> 47</span><spanclass="comment">// of each variable (will always be 1.0 for integers) and can be used to recover</span></div>
<divclass="line"><aid="l00048"name="l00048"></a><spanclass="lineno"> 48</span><spanclass="comment">// a solution of the unscaled problem from one of the new scaled problems by</span></div>
<divclass="line"><aid="l00049"name="l00049"></a><spanclass="lineno"> 49</span><spanclass="comment">// dividing the variable values.</span></div>
<divclass="line"><aid="l00051"name="l00051"></a><spanclass="lineno"> 51</span><spanclass="comment">// We usually scale a continuous variable by scaling, but if its domain is going</span></div>
<divclass="line"><aid="l00052"name="l00052"></a><spanclass="lineno"> 52</span><spanclass="comment">// to have larger values than max_bound, then we scale to have the max domain</span></div>
<divclass="line"><aid="l00053"name="l00053"></a><spanclass="lineno"> 53</span><spanclass="comment">// magnitude equal to max_bound.</span></div>
<divclass="line"><aid="l00055"name="l00055"></a><spanclass="lineno"> 55</span><spanclass="comment">// Note that it is recommended to call DetectImpliedIntegers() before this</span></div>
<divclass="line"><aid="l00056"name="l00056"></a><spanclass="lineno"> 56</span><spanclass="comment">// function so that we do not scale variables that do not need to be scaled.</span></div>
<divclass="line"><aid="l00058"name="l00058"></a><spanclass="lineno"> 58</span><spanclass="comment">// TODO(user): Also scale the solution hint if any.</span></div>
<divclass="line"><aid="l00062"name="l00062"></a><spanclass="lineno"> 62</span><spanclass="comment">// This simple step helps and should be done first. Returns false if the model</span></div>
<divclass="line"><aid="l00063"name="l00063"></a><spanclass="lineno"> 63</span><spanclass="comment">// is trivially infeasible because of crossing bounds.</span></div>
<divclass="line"><aid="l00068"name="l00068"></a><spanclass="lineno"> 68</span><spanclass="comment">// Performs some extra tests on the given MPModelProto and returns false if one</span></div>
<divclass="line"><aid="l00069"name="l00069"></a><spanclass="lineno"> 69</span><spanclass="comment">// is not satisfied. These are needed before trying to convert it to the native</span></div>
<divclass="line"><aid="l00075"name="l00075"></a><spanclass="lineno"> 75</span><spanclass="comment">// To satisfy our scaling requirements, any terms that is almost zero can just</span></div>
<divclass="line"><aid="l00076"name="l00076"></a><spanclass="lineno"> 76</span><spanclass="comment">// be set to zero. We need to do that before operations like</span></div>
<divclass="line"><aid="l00077"name="l00077"></a><spanclass="lineno"> 77</span><spanclass="comment">// DetectImpliedIntegers(), becauses really low coefficients can cause issues</span></div>
<divclass="line"><aid="l00078"name="l00078"></a><spanclass="lineno"> 78</span><spanclass="comment">// and might lead to less detection.</span></div>
<divclass="line"><aid="l00082"name="l00082"></a><spanclass="lineno"> 82</span><spanclass="comment">// This will mark implied integer as such. Note that it can also discover</span></div>
<divclass="line"><aid="l00083"name="l00083"></a><spanclass="lineno"> 83</span><spanclass="comment">// variable of the form coeff * Integer + offset, and will change the model</span></div>
<divclass="line"><aid="l00084"name="l00084"></a><spanclass="lineno"> 84</span><spanclass="comment">// so that these are marked as integer. It is why we return both a scaling and</span></div>
<divclass="line"><aid="l00085"name="l00085"></a><spanclass="lineno"> 85</span><spanclass="comment">// an offset to transform the solution back to its original domain.</span></div>
<divclass="line"><aid="l00087"name="l00087"></a><spanclass="lineno"> 87</span><spanclass="comment">// TODO(user): Actually implement the offset part. This currently only happens</span></div>
<divclass="line"><aid="l00088"name="l00088"></a><spanclass="lineno"> 88</span><spanclass="comment">// on the 3 neos-46470* miplib problems where we have a non-integer rhs.</span></div>
<divclass="line"><aid="l00092"name="l00092"></a><spanclass="lineno"> 92</span><spanclass="comment">// Converts a MIP problem to a CpModel. Returns false if the coefficients</span></div>
<divclass="line"><aid="l00093"name="l00093"></a><spanclass="lineno"> 93</span><spanclass="comment">// couldn't be converted to integers with a good enough precision.</span></div>
<divclass="line"><aid="l00095"name="l00095"></a><spanclass="lineno"> 95</span><spanclass="comment">// There is a bunch of caveats and you can find more details on the</span></div>
<divclass="line"><aid="l00096"name="l00096"></a><spanclass="lineno"> 96</span><spanclass="comment">// SatParameters proto documentation for the mip_* parameters.</span></div>
<divclass="line"><aid="l00102"name="l00102"></a><spanclass="lineno"> 102</span><spanclass="comment">// Converts a CP-SAT model to a MPModelProto one.</span></div>
<divclass="line"><aid="l00103"name="l00103"></a><spanclass="lineno"> 103</span><spanclass="comment">// This only works for pure linear model (otherwise it returns false). This is</span></div>
<divclass="line"><aid="l00104"name="l00104"></a><spanclass="lineno"> 104</span><spanclass="comment">// mainly useful for debugging or using CP-SAT presolve and then trying other</span></div>
<divclass="line"><aid="l00107"name="l00107"></a><spanclass="lineno"> 107</span><spanclass="comment">// TODO(user): This first version do not even handle basic Boolean constraint.</span></div>
<divclass="line"><aid="l00108"name="l00108"></a><spanclass="lineno"> 108</span><spanclass="comment">// Support more constraints as needed.</span></div>
<divclass="line"><aid="l00112"name="l00112"></a><spanclass="lineno"> 112</span><spanclass="comment">// Scales a double objective to its integer version and fills it in the proto.</span></div>
<divclass="line"><aid="l00113"name="l00113"></a><spanclass="lineno"> 113</span><spanclass="comment">// The variable listed in the objective must be already defined in the cp_model</span></div>
<divclass="line"><aid="l00114"name="l00114"></a><spanclass="lineno"> 114</span><spanclass="comment">// proto as this uses the variables bounds to compute a proper scaling.</span></div>
<divclass="line"><aid="l00116"name="l00116"></a><spanclass="lineno"> 116</span><spanclass="comment">// This uses params.mip_wanted_tolerance() and</span></div>
<divclass="line"><aid="l00117"name="l00117"></a><spanclass="lineno"> 117</span><spanclass="comment">// params.mip_max_activity_exponent() to compute the scaling. Note however that</span></div>
<divclass="line"><aid="l00118"name="l00118"></a><spanclass="lineno"> 118</span><spanclass="comment">// if the wanted tolerance is not satisfied this still scale with best effort.</span></div>
<divclass="line"><aid="l00119"name="l00119"></a><spanclass="lineno"> 119</span><spanclass="comment">// You can see in the log the tolerance guaranteed by this automatic scaling.</span></div>
<divclass="line"><aid="l00121"name="l00121"></a><spanclass="lineno"> 121</span><spanclass="comment">// This will almost always returns true except for really bad cases like having</span></div>
<divclass="line"><aid="l00122"name="l00122"></a><spanclass="lineno"> 122</span><spanclass="comment">// infinity in the objective.</span></div>
<divclass="line"><aid="l00128"name="l00128"></a><spanclass="lineno"> 128</span><spanclass="comment">// Given a CpModelProto with a floating point objective, and its scaled integer</span></div>
<divclass="line"><aid="l00129"name="l00129"></a><spanclass="lineno"> 129</span><spanclass="comment">// version with a known lower bound, this uses the variable bounds to derive a</span></div>
<divclass="line"><aid="l00130"name="l00130"></a><spanclass="lineno"> 130</span><spanclass="comment">// correct lower bound on the original objective.</span></div>
<divclass="line"><aid="l00132"name="l00132"></a><spanclass="lineno"> 132</span><spanclass="comment">// Note that the integer version can be way different, but then the bound is</span></div>
<divclass="line"><aid="l00133"name="l00133"></a><spanclass="lineno"> 133</span><spanclass="comment">// likely to be bad. For now, we solve this with a simple LP with one</span></div>
<divclass="line"><aid="l00136"name="l00136"></a><spanclass="lineno"> 136</span><spanclass="comment">// TODO(user): Code a custom algo with more precision guarantee?</span></div>
<divclass="line"><aid="l00142"name="l00142"></a><spanclass="lineno"> 142</span><spanclass="comment">// Converts an integer program with only binary variables to a Boolean</span></div>
<divclass="line"><aid="l00143"name="l00143"></a><spanclass="lineno"> 143</span><spanclass="comment">// optimization problem. Returns false if the problem didn't contains only</span></div>
<divclass="line"><aid="l00144"name="l00144"></a><spanclass="lineno"> 144</span><spanclass="comment">// binary integer variable, or if the coefficients couldn't be converted to</span></div>
<divclass="line"><aid="l00145"name="l00145"></a><spanclass="lineno"> 145</span><spanclass="comment">// integer with a good enough precision.</span></div>
<divclass="line"><aid="l00149"name="l00149"></a><spanclass="lineno"> 149</span><spanclass="comment">// Converts a Boolean optimization problem to its lp formulation.</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>
<divclass="ttc"id="aparser_8yy_8cc_html_a5a634cf4429798b1c921a81de8250051"><divclass="ttname"><ahref="parser_8yy_8cc.html#a5a634cf4429798b1c921a81de8250051">input</a></div><divclass="ttdeci">static int input(yyscan_t yyscanner)</div></div>