OR-Tools  9.2
variable_and_expressions.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 <string>
17#include <utility>
18#include <vector>
19
21#include "absl/container/flat_hash_map.h"
25
26namespace operations_research {
27namespace math_opt {
28
29#ifdef USE_LINEAR_EXPRESSION_COUNTERS
30LinearExpression::LinearExpression() { ++num_calls_default_constructor_; }
31
32LinearExpression::LinearExpression(const LinearExpression& other)
33 : terms_(other.terms_), offset_(other.offset_) {
34 ++num_calls_copy_constructor_;
35}
36
37LinearExpression::LinearExpression(LinearExpression&& other)
38 : terms_(std::move(other.terms_)),
39 offset_(std::exchange(other.offset_, 0.0)) {
40 ++num_calls_move_constructor_;
41}
42
43LinearExpression& LinearExpression::operator=(const LinearExpression& other) {
44 terms_ = other.terms_;
45 offset_ = other.offset_;
46 return *this;
47}
48
49ABSL_CONST_INIT thread_local int
50 LinearExpression::num_calls_default_constructor_ = 0;
51ABSL_CONST_INIT thread_local int LinearExpression::num_calls_copy_constructor_ =
52 0;
53ABSL_CONST_INIT thread_local int LinearExpression::num_calls_move_constructor_ =
54 0;
55ABSL_CONST_INIT thread_local int
56 LinearExpression::num_calls_initializer_list_constructor_ = 0;
57
58void LinearExpression::ResetCounters() {
59 num_calls_default_constructor_ = 0;
60 num_calls_copy_constructor_ = 0;
61 num_calls_move_constructor_ = 0;
62 num_calls_initializer_list_constructor_ = 0;
63}
64#endif // USE_LINEAR_EXPRESSION_COUNTERS
65
66double LinearExpression::Evaluate(
67 const VariableMap<double>& variable_values) const {
68 if (variable_values.model() != nullptr && model() != nullptr) {
69 CHECK_EQ(variable_values.model(), model())
71 }
72 double result = offset_;
73 for (const auto& [variable_id, coef] : terms_.raw_map()) {
74 result += coef * variable_values.raw_map().at(variable_id);
75 }
76 return result;
77}
78
79double LinearExpression::EvaluateWithDefaultZero(
80 const VariableMap<double>& variable_values) const {
81 if (variable_values.model() != nullptr && model() != nullptr) {
82 CHECK_EQ(variable_values.model(), model())
84 }
85 double result = offset_;
86 for (const auto& [variable_id, coef] : terms_.raw_map()) {
87 result +=
88 coef * gtl::FindWithDefault(variable_values.raw_map(), variable_id);
89 }
90 return result;
91}
92
93std::ostream& operator<<(std::ostream& ostr,
94 const LinearExpression& expression) {
95 // TODO(b/169415597): improve linear expression format:
96 // - use bijective formatting in base10 of the double factors.
97 // - handle negative coefficients, replacing `... + -3*x ` by `... - 3*x`.
98 // - make sure to quote the variable name so that we support:
99 // * variable names contains +, -, ...
100 // * variable names resembling anonymous variable names.
101 const std::vector<Variable> sorted_variables = expression.terms_.SortedKeys();
102 bool first = true;
103 for (const auto v : sorted_variables) {
104 if (first) {
105 first = false;
106 } else {
107 ostr << " + ";
108 }
109 ostr << expression.terms_.at(v) << "*";
110 const std::string& name = v.name();
111 if (name.empty()) {
112 ostr << "[" << v << "]";
113 } else {
114 ostr << name;
115 }
116 }
117
118 if (!first) {
119 ostr << " + ";
120 }
121 ostr << expression.offset();
122
123 return ostr;
124}
125
126std::ostream& operator<<(std::ostream& ostr,
127 const BoundedLinearExpression& bounded_expression) {
128 // TODO(b/170991498): use bijective conversion from double to base-10 string
129 // to make sure we can reproduce bugs.
130 ostr << bounded_expression.lower_bound
131 << " <= " << bounded_expression.expression
132 << " <= " << bounded_expression.upper_bound;
133 return ostr;
134}
135
136} // namespace math_opt
137} // namespace operations_research
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:699
IndexedModel * model() const
Definition: id_map.h:229
const StorageType & raw_map() const
Definition: id_map.h:228
const std::string name
int64_t coef
Definition: expr_array.cc:1875
GRBmodel * model
const int64_t offset_
Definition: interval.cc:2108
const Collection::value_type::second_type & FindWithDefault(const Collection &collection, const typename Collection::value_type::first_type &key, const typename Collection::value_type::second_type &value)
Definition: map_util.h:29
constexpr absl::string_view kObjectsFromOtherIndexedModel
Definition: key_types.h:56
std::ostream & operator<<(std::ostream &ostr, const BoundedLinearExpression &bounded_expression)
Collection of objects used to extend the Constraint Solver library.
STL namespace.