18 #include "absl/strings/str_join.h"
33 for (
const auto& kv : rhs.terms_) {
34 terms_[kv.first] += kv.second;
36 offset_ += rhs.offset_;
41 for (
const auto& kv : rhs.terms_) {
42 terms_[kv.first] -= kv.second;
44 offset_ -= rhs.offset_;
52 }
else if (rhs != 1) {
53 for (
auto& kv : terms_) {
63 return (*
this) *= 1 / rhs;
76 double solution = offset_;
77 for (
const auto& pair : terms_) {
78 solution += pair.first->solution_value() * pair.second;
85 void AppendTerm(
const double coef,
const std::string& var_name,
86 const bool is_first, std::string* s) {
89 absl::StrAppend(s, var_name);
90 }
else if (
coef == -1.0) {
91 absl::StrAppend(s,
"-", var_name);
93 absl::StrAppend(s,
coef,
"*", var_name);
96 const std::string op =
coef < 0 ?
"-" :
"+";
97 const double abs_coef = std::abs(
coef);
98 if (abs_coef == 1.0) {
99 absl::StrAppend(s,
" ", op,
" ", var_name);
101 absl::StrAppend(s,
" ", op,
" ", abs_coef,
"*", var_name);
106 void AppendOffset(
const double offset,
const bool is_first, std::string* s) {
108 absl::StrAppend(s, offset);
111 const std::string op = offset < 0 ?
"-" :
"+";
112 absl::StrAppend(s,
" ", op,
" ", std::abs(offset));
120 std::vector<const MPVariable*> vars_in_order;
121 for (
const auto& var_val_pair : terms_) {
122 vars_in_order.push_back(var_val_pair.first);
124 std::sort(vars_in_order.begin(), vars_in_order.end(),
126 return v->index() < u->index();
129 bool is_first =
true;
133 AppendTerm(terms_.at(
var),
var->name(), is_first, &result);
136 AppendOffset(offset_, is_first, &result);
169 : lower_bound_(lower_bound),
170 linear_expr_(linear_expr),
171 upper_bound_(upper_bound) {
172 lower_bound_ -= linear_expr_.
offset();
173 upper_bound_ -= linear_expr_.
offset();
174 linear_expr_ -= linear_expr_.
offset();
178 return LinearRange(-std::numeric_limits<double>::infinity(), lhs - rhs, 0);
184 return LinearRange(0, lhs - rhs, std::numeric_limits<double>::infinity());