OR-Tools  9.1
cp_model_objective.cc
Go to the documentation of this file.
1// Copyright 2010-2021 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
15
16#include <cstdint>
17
19
20namespace operations_research {
21namespace sat {
22
24 if (!cp_model->has_objective()) return;
25
26 if (cp_model->objective().vars_size() == 1) {
27 // Canonicalize the objective to make it easier on us by always making the
28 // coefficient equal to 1.0.
29 const int old_ref = cp_model->objective().vars(0);
30 const int64_t old_coeff = cp_model->objective().coeffs(0);
31 const double muliplier = static_cast<double>(std::abs(old_coeff));
32 if (old_coeff < 0) {
33 cp_model->mutable_objective()->set_vars(0, NegatedRef(old_ref));
34 }
35 if (muliplier != 1.0) {
36 // TODO(user): deal with this case.
37 CHECK(cp_model->objective().domain().empty());
38
39 double old_factor = cp_model->objective().scaling_factor();
40 if (old_factor == 0.0) old_factor = 1.0;
41 const double old_offset = cp_model->objective().offset();
42 cp_model->mutable_objective()->set_scaling_factor(old_factor * muliplier);
43 cp_model->mutable_objective()->set_offset(old_offset / muliplier);
44 }
45 cp_model->mutable_objective()->set_coeffs(0, 1.0);
46 return;
47 }
48
49 // Compute trivial bounds on the objective, this is needed otherwise the
50 // overflow checker might not be happy with the new constraint we are about
51 // to create. Note that the model validator should make sure that there is no
52 // overflow in the computation below.
53 int64_t min_obj = 0;
54 int64_t max_obj = 0;
55 for (int i = 0; i < cp_model->objective().vars_size(); ++i) {
56 const int ref = cp_model->objective().vars(i);
57 const int var = PositiveRef(ref);
58 const int64_t coeff =
59 cp_model->objective().coeffs(i) * (RefIsPositive(ref) ? 1 : -1);
60 const int64_t value1 = cp_model->variables(var).domain(0) * coeff;
61 const int64_t value2 = cp_model->variables(var).domain(
62 cp_model->variables(var).domain_size() - 1) *
63 coeff;
64 min_obj += std::min(value1, value2);
65 max_obj += std::max(value1, value2);
66 }
67
68 // Create the new objective var.
69 const int obj_ref = cp_model->variables_size();
70 {
71 IntegerVariableProto* obj = cp_model->add_variables();
72 Domain obj_domain(min_obj, max_obj);
73 if (!cp_model->objective().domain().empty()) {
74 obj_domain = obj_domain.IntersectionWith(
75 ReadDomainFromProto(cp_model->objective()));
76 }
77 FillDomainInProto(obj_domain, obj);
78 }
79
80 // Add the linear constraint.
82 ct->add_domain(0);
83 ct->add_domain(0);
84 *(ct->mutable_vars()) = cp_model->objective().vars();
85 *(ct->mutable_coeffs()) = cp_model->objective().coeffs();
86 ct->add_vars(obj_ref);
87 ct->add_coeffs(-1);
88
89 // Update the objective.
90 cp_model->mutable_objective()->clear_vars();
91 cp_model->mutable_objective()->clear_coeffs();
92 cp_model->mutable_objective()->add_vars(obj_ref);
93 cp_model->mutable_objective()->add_coeffs(1);
94 cp_model->mutable_objective()->clear_domain();
95}
96
97} // namespace sat
98} // namespace operations_research
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
#define CHECK(condition)
Definition: base/logging.h:491
We call domain any subset of Int64 = [kint64min, kint64max].
Domain IntersectionWith(const Domain &domain) const
Returns the intersection of D and domain.
::operations_research::sat::LinearConstraintProto * mutable_linear()
const ::operations_research::sat::CpObjectiveProto & objective() const
const ::operations_research::sat::IntegerVariableProto & variables(int index) const
::operations_research::sat::ConstraintProto * add_constraints()
::operations_research::sat::IntegerVariableProto * add_variables()
::operations_research::sat::CpObjectiveProto * mutable_objective()
::PROTOBUF_NAMESPACE_ID::int64 coeffs(int index) const
void set_vars(int index, ::PROTOBUF_NAMESPACE_ID::int32 value)
void add_coeffs(::PROTOBUF_NAMESPACE_ID::int64 value)
::PROTOBUF_NAMESPACE_ID::int64 domain(int index) const
void set_coeffs(int index, ::PROTOBUF_NAMESPACE_ID::int64 value)
::PROTOBUF_NAMESPACE_ID::int32 vars(int index) const
void add_vars(::PROTOBUF_NAMESPACE_ID::int32 value)
::PROTOBUF_NAMESPACE_ID::int64 domain(int index) const
Definition: cp_model.pb.h:6893
const Constraint * ct
IntVar * var
Definition: expr_array.cc:1874
bool RefIsPositive(int ref)
void EncodeObjectiveAsSingleVariable(CpModelProto *cp_model)
void FillDomainInProto(const Domain &domain, ProtoWithDomain *proto)
Domain ReadDomainFromProto(const ProtoWithDomain &proto)
Collection of objects used to extend the Constraint Solver library.