OR-Tools  9.6
linear_relaxation.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #ifndef OR_TOOLS_SAT_LINEAR_RELAXATION_H_
15 #define OR_TOOLS_SAT_LINEAR_RELAXATION_H_
16 
17 #include <optional>
18 #include <vector>
19 
20 #include "ortools/sat/cp_model.pb.h"
21 #include "ortools/sat/cuts.h"
22 #include "ortools/sat/integer.h"
23 #include "ortools/sat/intervals.h"
24 #include "ortools/sat/model.h"
26 
27 namespace operations_research {
28 namespace sat {
29 
31  std::vector<LinearConstraint> linear_constraints;
32  std::vector<std::vector<Literal>> at_most_ones;
33  std::vector<CutGenerator> cut_generators;
34 };
35 
36 // Looks at all the encoding literal (li <=> var == value_i) that have a
37 // view and add a linear relaxation of their relationship with var.
38 //
39 // If the encoding is full, we can just add:
40 // - Sum li == 1
41 // - var == min_value + Sum li * (value_i - min_value)
42 //
43 // When the set of such encoding literals do not cover the full domain of var,
44 // we do something a bit more involved. Let min_not_encoded/max_not_encoded the
45 // min and max value of the domain of var that is NOT part of the encoding.
46 // We add:
47 // - Sum li <= 1
48 // - var >= (Sum li * value_i) + (1 - Sum li) * min_not_encoded
49 // - var <= (Sum li * value_i) + (1 - Sum li) * max_not_encoded
50 //
51 // Note of the special case where min_not_encoded == max_not_encoded that kind
52 // of reduce to the full encoding, except with a different "rhs" value.
53 //
54 // We also increment the corresponding counter if we added something. We
55 // consider the relaxation "tight" if the encoding was full or if
56 // min_not_encoded == max_not_encoded.
57 void AppendRelaxationForEqualityEncoding(IntegerVariable var,
58  const Model& model,
59  LinearRelaxation* relaxation,
60  int* num_tight, int* num_loose);
61 
62 // This is a different relaxation that use a partial set of literal li such that
63 // (li <=> var >= xi). In which case we use the following encoding:
64 // - li >= l_{i+1} for all possible i. Note that the xi need to be sorted.
65 // - var >= min + l0 * (x0 - min) + Sum_{i>0} li * (xi - x_{i-1})
66 // - and same as above for NegationOf(var) for the upper bound.
67 //
68 // Like for AppendRelaxationForEqualityEncoding() we skip any li that do not
69 // have an integer view.
71  const Model& model,
72  LinearRelaxation* relaxation);
73 
74 // Returns a vector of new literals in exactly one relationship.
75 // In addition, this create an IntegerView for all these literals and also add
76 // the exactly one to the LinearRelaxation.
77 std::vector<Literal> CreateAlternativeLiteralsWithView(
78  int num_literals, Model* model, LinearRelaxation* relaxation);
79 
80 void AppendBoolOrRelaxation(const ConstraintProto& ct, Model* model,
81  LinearRelaxation* relaxation);
82 
83 void AppendBoolAndRelaxation(const ConstraintProto& ct, Model* model,
84  LinearRelaxation* relaxation,
85  ActivityBoundHelper* activity_helper = nullptr);
86 
87 void AppendAtMostOneRelaxation(const ConstraintProto& ct, Model* model,
88  LinearRelaxation* relaxation);
89 
90 void AppendExactlyOneRelaxation(const ConstraintProto& ct, Model* model,
91  LinearRelaxation* relaxation);
92 
93 // Adds linearization of int max constraints. Returns a vector of z vars such
94 // that: z_vars[l] == 1 <=> target = exprs[l].
95 //
96 // Consider the Lin Max constraint with d expressions and n variables in the
97 // form: target = max {exprs[l] = Sum (wli * xi + bl)}. l in {1,..,d}.
98 // Li = lower bound of xi
99 // Ui = upper bound of xi.
100 // Let zl be in {0,1} for all l in {1,..,d}.
101 // The target = exprs[l] when zl = 1.
102 //
103 // The following is a valid linearization for Lin Max.
104 // target >= exprs[l], for all l in {1,..,d}
105 // target <= Sum_i(wki * xi) + Sum_l((Nkl + bl) * zl), for all k in {1,..,d}
106 // Where Nkl is a large number defined as:
107 // Nkl = Sum_i(max((wli - wki)*Li, (wli - wki)*Ui))
108 // = Sum (max corner difference for variable i, target expr k, max expr l)
109 // Reference: "Strong mixed-integer programming formulations for trained neural
110 // networks" by Ross Anderson et. (https://arxiv.org/pdf/1811.01988.pdf).
111 // TODO(user): Support linear expression as target.
112 void AppendLinMaxRelaxationPart1(const ConstraintProto& ct, Model* model,
113  LinearRelaxation* relaxation);
114 
116  IntegerVariable target, const std::vector<Literal>& alternative_literals,
117  const std::vector<LinearExpression>& exprs, Model* model,
118  LinearRelaxation* relaxation);
119 
120 // Note: This only works if all affine expressions share the same variable.
121 void AppendMaxAffineRelaxation(const ConstraintProto& ct, Model* model,
122  LinearRelaxation* relaxation);
123 
124 // Appends linear constraints to the relaxation. This also handles the
125 // relaxation of linear constraints with enforcement literals.
126 // A linear constraint lb <= ax <= ub with enforcement literals {ei} is relaxed
127 // as following.
128 // lb <= (Sum Negated(ei) * (lb - implied_lb)) + ax <= inf
129 // -inf <= (Sum Negated(ei) * (ub - implied_ub)) + ax <= ub
130 // Where implied_lb and implied_ub are trivial lower and upper bounds of the
131 // constraint.
133  const ConstraintProto& ct, bool linearize_enforced_constraints,
134  Model* model, LinearRelaxation* relaxation,
135  ActivityBoundHelper* activity_helper = nullptr);
136 
137 void AppendSquareRelaxation(const ConstraintProto& ct, Model* m,
138  LinearRelaxation* relaxation);
139 
140 // Adds linearization of no overlap constraints.
141 // It adds an energetic equation linking the duration of all potential tasks to
142 // the actual span of the no overlap constraint.
143 void AppendNoOverlapRelaxationAndCutGenerator(const ConstraintProto& ct,
144  Model* model,
145  LinearRelaxation* relaxation);
146 
147 // Adds linearization of cumulative constraints.The second part adds an
148 // energetic equation linking the duration of all potential tasks to the actual
149 // span * capacity of the cumulative constraint.
150 void AppendCumulativeRelaxationAndCutGenerator(const ConstraintProto& ct,
151  Model* model,
152  LinearRelaxation* relaxation);
153 
154 // Cut generators.
155 void AddIntProdCutGenerator(const ConstraintProto& ct, int linearization_level,
156  Model* m, LinearRelaxation* relaxation);
157 
158 void AddSquareCutGenerator(const ConstraintProto& ct, int linearization_level,
159  Model* m, LinearRelaxation* relaxation);
160 
161 void AddAllDiffRelaxationAndCutGenerator(const ConstraintProto& ct,
162  int linearization_level, Model* m,
163  LinearRelaxation* relaxation);
164 
165 void AddLinMaxCutGenerator(const ConstraintProto& ct, Model* m,
166  LinearRelaxation* relaxation);
167 
168 // Routing relaxation and cut generators.
169 
170 void AppendCircuitRelaxation(const ConstraintProto& ct, Model* model,
171  LinearRelaxation* relaxation);
172 
173 void AppendRoutesRelaxation(const ConstraintProto& ct, Model* model,
174  LinearRelaxation* relaxation);
175 
176 void AddCircuitCutGenerator(const ConstraintProto& ct, Model* m,
177  LinearRelaxation* relaxation);
178 
179 void AddRoutesCutGenerator(const ConstraintProto& ct, Model* m,
180  LinearRelaxation* relaxation);
181 
182 // Scheduling relaxations and cut generators.
183 
184 // Adds linearization of cumulative constraints.The second part adds an
185 // energetic equation linking the duration of all potential tasks to the actual
186 // span * capacity of the cumulative constraint. It uses the makespan to compute
187 // the span of the constraint if defined.
190  SchedulingDemandHelper* demands,
191  const std::optional<AffineExpression>& makespan,
192  Model* model, LinearRelaxation* relaxation);
193 
196  SchedulingDemandHelper* demands,
197  const std::optional<AffineExpression>& makespan,
198  Model* m, LinearRelaxation* relaxation);
199 
201  const std::optional<AffineExpression>& makespan,
202  Model* m, LinearRelaxation* relaxation);
203 
204 void AddNoOverlap2dCutGenerator(const ConstraintProto& ct, Model* m,
205  LinearRelaxation* relaxation);
206 
207 // Adds linearization of different types of constraints.
208 void TryToLinearizeConstraint(const CpModelProto& model_proto,
209  const ConstraintProto& ct,
210  int linearization_level, Model* model,
211  LinearRelaxation* relaxation,
212  ActivityBoundHelper* helper = nullptr);
213 
214 // Builds the linear relaxation of a CpModelProto.
216  Model* m);
217 
218 } // namespace sat
219 } // namespace operations_research
220 
221 #endif // OR_TOOLS_SAT_LINEAR_RELAXATION_H_
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:42
CpModelProto const * model_proto
const Constraint * ct
IntVar * var
Definition: expr_array.cc:1874
GRBmodel * model
void AppendCumulativeRelaxationAndCutGenerator(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
void AppendLinMaxRelaxationPart1(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
void AppendBoolOrRelaxation(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
void AppendAtMostOneRelaxation(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
void AddAllDiffRelaxationAndCutGenerator(const ConstraintProto &ct, int linearization_level, Model *m, LinearRelaxation *relaxation)
void AppendLinearConstraintRelaxation(const ConstraintProto &ct, bool linearize_enforced_constraints, Model *model, LinearRelaxation *relaxation, ActivityBoundHelper *activity_helper)
void AddNoOverlap2dCutGenerator(const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation)
void AddNoOverlapCutGenerator(SchedulingConstraintHelper *helper, const std::optional< AffineExpression > &makespan, Model *m, LinearRelaxation *relaxation)
void AddIntProdCutGenerator(const ConstraintProto &ct, int linearization_level, Model *m, LinearRelaxation *relaxation)
void AddCircuitCutGenerator(const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation)
void TryToLinearizeConstraint(const CpModelProto &model_proto, const ConstraintProto &ct, int linearization_level, Model *model, LinearRelaxation *relaxation, ActivityBoundHelper *activity_helper)
void AppendMaxAffineRelaxation(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
void AppendExactlyOneRelaxation(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
std::vector< Literal > CreateAlternativeLiteralsWithView(int num_literals, Model *model, LinearRelaxation *relaxation)
void AppendCircuitRelaxation(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
void AddCumulativeCutGenerator(const AffineExpression &capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands_helper, const std::optional< AffineExpression > &makespan, Model *m, LinearRelaxation *relaxation)
void AppendSquareRelaxation(const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation)
void AddSquareCutGenerator(const ConstraintProto &ct, int linearization_level, Model *m, LinearRelaxation *relaxation)
void AppendBoolAndRelaxation(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation, ActivityBoundHelper *activity_helper)
void AddLinMaxCutGenerator(const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation)
void AppendRoutesRelaxation(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
void AppendRelaxationForEqualityEncoding(IntegerVariable var, const Model &model, LinearRelaxation *relaxation, int *num_tight, int *num_loose)
void AddCumulativeRelaxation(const AffineExpression &capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands_helper, const std::optional< AffineExpression > &makespan, Model *model, LinearRelaxation *relaxation)
void AddRoutesCutGenerator(const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation)
LinearRelaxation ComputeLinearRelaxation(const CpModelProto &model_proto, Model *m)
void AppendNoOverlapRelaxationAndCutGenerator(const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation)
void AppendLinMaxRelaxationPart2(IntegerVariable target, const std::vector< Literal > &alternative_literals, const std::vector< LinearExpression > &exprs, Model *model, LinearRelaxation *relaxation)
void AppendPartialGreaterThanEncodingRelaxation(IntegerVariable var, const Model &model, LinearRelaxation *relaxation)
Collection of objects used to extend the Constraint Solver library.
int64_t capacity
std::vector< std::vector< Literal > > at_most_ones
std::vector< LinearConstraint > linear_constraints
std::vector< CutGenerator > cut_generators