28 const int size =
ct.bool_or().literals_size();
30 bool satisfied =
false;
31 for (
int i = 0; i < size; ++i) {
32 const int ref =
ct.bool_or().literals(i);
43 if (satisfied)
return;
46 const int first_ref =
ct.bool_or().literals(0);
53 const std::vector<bool>& prefer_lower_value,
54 std::vector<Domain>* domains) {
55 int64 fixed_activity = 0;
56 const int size =
ct.linear().vars().size();
57 std::vector<int> free_vars;
58 std::vector<int64> free_coeffs;
59 for (
int i = 0; i < size; ++i) {
60 const int var =
ct.linear().vars(i);
61 const int64 coeff =
ct.linear().coeffs(i);
62 CHECK_LT(
var, domains->size());
63 if (coeff == 0)
continue;
65 fixed_activity += (*domains)[
var].FixedValue() * coeff;
67 free_vars.push_back(
var);
68 free_coeffs.push_back(coeff);
71 if (free_vars.empty())
return;
77 if (free_vars.size() == 1) {
78 const int var = free_vars[0];
88 std::vector<Domain> to_add;
89 to_add.push_back(
Domain(0));
90 for (
int i = 0; i + 1 < free_vars.size(); ++i) {
97 for (
int i = free_vars.size() - 1; i >= 0; --i) {
100 const int var = free_vars[i];
101 const int64 coeff = free_coeffs[i];
105 CHECK(!domain.
IsEmpty()) <<
ct.ShortDebugString();
111 fixed_activity += coeff *
value;
120 for (
const int ref :
ct.int_max().vars()) {
132 const int target_ref =
ct.int_max().target();
135 (*domains)[target_var] = (*domains)[target_var].IntersectionWith(
Domain(m));
137 (*domains)[target_var] =
138 (*domains)[target_var].IntersectionWith(
Domain(-m));
140 CHECK(!(*domains)[target_var].IsEmpty());
145 const int index_ref =
ct.element().index();
147 const int target_ref =
ct.element().target();
153 if (!(*domains)[target_var].
IsFixed() && !(*domains)[index_var].
IsFixed()) {
154 const int64 index_value = (*domains)[index_var].Min();
155 (*domains)[index_var] =
Domain(index_value);
158 const int selected_ref =
ct.element().vars(
160 const int selected_var =
PositiveRef(selected_ref);
161 if (!(*domains)[selected_var].
IsFixed()) {
162 (*domains)[selected_var] =
Domain((*domains)[selected_var].Min());
167 if ((*domains)[index_var].
IsFixed()) {
168 const int64 index_value = (*domains)[index_var].FixedValue();
169 const int selected_ref =
ct.element().vars(
171 const int selected_var =
PositiveRef(selected_ref);
172 const int64 selected_value = (*domains)[selected_var].FixedValue();
173 (*domains)[target_var] = (*domains)[target_var].IntersectionWith(
177 DCHECK(!(*domains)[target_var].IsEmpty());
182 const int64 target_value = (*domains)[target_var].FixedValue();
183 int selected_index_value = -1;
184 for (
int i = 0; i <
ct.element().vars().size(); ++i) {
185 const int ref =
ct.element().vars(i);
189 if (
value == target_value) {
190 selected_index_value = i;
194 if (
value == -target_value) {
195 selected_index_value = i;
201 CHECK_NE(selected_index_value, -1);
202 (*domains)[index_var] = (*domains)[index_var].IntersectionWith(
Domain(
203 RefIsPositive(index_var) ? selected_index_value : -selected_index_value));
204 DCHECK(!(*domains)[index_var].IsEmpty());
208 const CpModelProto& mapping_proto,
209 const std::vector<int>& postsolve_mapping,
216 if (
response->solution_size() != postsolve_mapping.size())
return;
220 std::vector<Domain> domains(mapping_proto.variables_size());
221 for (
int i = 0; i < postsolve_mapping.size(); ++i) {
222 CHECK_LE(postsolve_mapping[i], domains.size());
225 for (
int i = 0; i < domains.size(); ++i) {
226 if (domains[i].IsEmpty()) {
229 CHECK(!domains[i].IsEmpty());
236 CHECK(!mapping_proto.has_objective());
237 std::vector<bool> prefer_lower_value(domains.size(),
true);
238 if (mapping_proto.has_objective()) {
239 const int size = mapping_proto.objective().vars().size();
240 for (
int i = 0; i < size; ++i) {
241 int var = mapping_proto.objective().vars(i);
242 int64 coeff = mapping_proto.objective().coeffs(i);
247 prefer_lower_value[i] = (coeff >= 0);
252 const int num_constraints = mapping_proto.constraints_size();
253 for (
int i = num_constraints - 1; i >= 0; i--) {
254 const ConstraintProto&
ct = mapping_proto.constraints(i);
257 bool enforced =
true;
258 for (
const int ref :
ct.enforcement_literal()) {
265 if (!enforced)
continue;
267 switch (
ct.constraint_case()) {
268 case ConstraintProto::kBoolOr:
271 case ConstraintProto::kLinear:
274 case ConstraintProto::kIntMax:
277 case ConstraintProto::kElement:
283 LOG(FATAL) <<
"Unsupported constraint: " <<
ct.ShortDebugString();
288 response->mutable_solution()->Clear();
289 CHECK_LE(num_variables_in_original_model, domains.size());
290 for (
int i = 0; i < num_variables_in_original_model; ++i) {
291 if (prefer_lower_value[i]) {
292 response->add_solution(domains[i].Min());
294 response->add_solution(domains[i].Max());