Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
model_solve_parameters.cc
Go to the documentation of this file.
1// Copyright 2010-2024 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 <stdint.h>
17
18#include <initializer_list>
19#include <optional>
20#include <utility>
21
22#include "absl/algorithm/container.h"
23#include "absl/status/status.h"
24#include "absl/status/statusor.h"
25#include "google/protobuf/repeated_field.h"
32#include "ortools/math_opt/model_parameters.pb.h"
33#include "ortools/math_opt/solution.pb.h"
34#include "ortools/math_opt/sparse_containers.pb.h"
37
38namespace operations_research {
39namespace math_opt {
40
41using ::google::protobuf::RepeatedField;
42
51
56
58 const ModelStorage* const expected_storage) const {
59 for (const SolutionHint& hint : solution_hints) {
60 RETURN_IF_ERROR(hint.CheckModelStorage(expected_storage))
61 << "invalid hint in solution_hints";
62 }
63 if (initial_basis.has_value()) {
64 RETURN_IF_ERROR(initial_basis->CheckModelStorage(expected_storage))
65 << "invalid initial_basis";
66 }
67 RETURN_IF_ERROR(variable_values_filter.CheckModelStorage(expected_storage))
68 << "invalid variable_values_filter";
69 RETURN_IF_ERROR(dual_values_filter.CheckModelStorage(expected_storage))
70 << "invalid dual_values_filter";
72 quadratic_dual_values_filter.CheckModelStorage(expected_storage))
73 << "invalid quadratic_dual_values_filter";
74 RETURN_IF_ERROR(reduced_costs_filter.CheckModelStorage(expected_storage))
75 << "invalid reduced_costs_filter";
76 for (const auto [var, unused] : branching_priorities) {
78 /*storage=*/var.storage(),
79 /*expected_storage=*/expected_storage))
80 << "invalid variable " << var << " in branching_priorities";
81 }
82 for (const auto& [objective, params] : objective_parameters) {
84 /*storage=*/objective.storage(),
85 /*expected_storage=*/expected_storage))
86 << "invalid objective " << objective << " in objective_parameters";
87 }
88 for (const LinearConstraint lazy_linear_constraint :
91 /*storage=*/lazy_linear_constraint.storage(),
92 /*expected_storage=*/expected_storage))
93 << "invalid LinearConstraint " << lazy_linear_constraint
94 << " in lazy_linear_constraints";
95 }
96 return absl::OkStatus();
97}
98
100 const ModelStorage* expected_storage) const {
101 for (const auto& [v, _] : variable_values) {
103 /*storage=*/v.storage(),
104 /*expected_storage=*/expected_storage))
105 << "invalid variable " << v << " in variable_values";
106 }
107 for (const auto& [c, _] : dual_values) {
109 /*storage=*/c.storage(),
110 /*expected_storage=*/expected_storage))
111 << "invalid constraint " << c << " in dual_values";
112 }
113 return absl::OkStatus();
114}
115
117 SolutionHintProto hint;
118 *hint.mutable_variable_values() = VariableValuesToProto(variable_values);
119 *hint.mutable_dual_values() = LinearConstraintValuesToProto(dual_values);
120 return hint;
121}
122
123absl::StatusOr<ModelSolveParameters::SolutionHint>
125 const Model& model, const SolutionHintProto& hint_proto) {
127 VariableMap<double> variable_values,
128 VariableValuesFromProto(model.storage(), hint_proto.variable_values()),
129 _ << "failed to parse SolutionHintProto.variable_values");
132 model.storage(), hint_proto.dual_values()),
133 _ << "failed to parse SolutionHintProto.dual_values");
134 return SolutionHint{
135 .variable_values = std::move(variable_values),
136 .dual_values = std::move(dual_values),
137 };
138}
139
141 const {
142 ObjectiveParametersProto params;
143 if (objective_degradation_absolute_tolerance) {
144 params.set_objective_degradation_absolute_tolerance(
145 *objective_degradation_absolute_tolerance);
146 }
147 if (objective_degradation_relative_tolerance) {
148 params.set_objective_degradation_relative_tolerance(
149 *objective_degradation_relative_tolerance);
150 }
151 return params;
152}
153
156 const ObjectiveParametersProto& proto) {
157 ObjectiveParameters result;
158 if (proto.has_objective_degradation_absolute_tolerance()) {
160 proto.objective_degradation_absolute_tolerance();
161 }
162 if (proto.has_objective_degradation_relative_tolerance()) {
164 proto.objective_degradation_relative_tolerance();
165 }
166 return result;
167}
168
169// TODO: b/315974557 - Return an error if a RepeatedField is too long.
170ModelSolveParametersProto ModelSolveParameters::Proto() const {
171 ModelSolveParametersProto ret;
172 *ret.mutable_variable_values_filter() = variable_values_filter.Proto();
173 *ret.mutable_dual_values_filter() = dual_values_filter.Proto();
174 *ret.mutable_quadratic_dual_values_filter() =
176 *ret.mutable_reduced_costs_filter() = reduced_costs_filter.Proto();
177
178 if (initial_basis.has_value()) {
179 *ret.mutable_initial_basis() = initial_basis->Proto();
180 }
181
182 for (const SolutionHint& solution_hint : solution_hints) {
183 *ret.add_solution_hints() = solution_hint.Proto();
184 }
185 if (!branching_priorities.empty()) {
186 RepeatedField<int64_t>& variable_ids =
187 *ret.mutable_branching_priorities()->mutable_ids();
188 RepeatedField<int32_t>& variable_values =
189 *ret.mutable_branching_priorities()->mutable_values();
190 variable_ids.Reserve(static_cast<int>(branching_priorities.size()));
191 variable_values.Reserve(static_cast<int>(branching_priorities.size()));
192 for (const Variable& key : SortedKeys(branching_priorities)) {
193 variable_ids.Add(key.id());
194 variable_values.Add(branching_priorities.at(key));
195 }
196 }
197 for (const auto& [objective, params] : objective_parameters) {
198 if (objective.id()) {
199 (*ret.mutable_auxiliary_objective_parameters())[*objective.id()] =
200 params.Proto();
201 } else {
202 *ret.mutable_primary_objective_parameters() = params.Proto();
203 }
204 }
205 if (!lazy_linear_constraints.empty()) {
206 RepeatedField<int64_t>& lazy_linear_constraint_ids =
207 *ret.mutable_lazy_linear_constraint_ids();
208 lazy_linear_constraint_ids.Reserve(
209 static_cast<int>(lazy_linear_constraints.size()));
210 for (const LinearConstraint lazy_linear_constraint :
212 lazy_linear_constraint_ids.Add(lazy_linear_constraint.id());
213 }
214 absl::c_sort(lazy_linear_constraint_ids);
215 }
216 return ret;
217}
218
219absl::StatusOr<ModelSolveParameters> ModelSolveParameters::FromProto(
220 const Model& model, const ModelSolveParametersProto& proto) {
224 VariableFilterFromProto(model, proto.variable_values_filter()),
225 _ << "invalid variable_values_filter");
227 result.dual_values_filter,
228 LinearConstraintFilterFromProto(model, proto.dual_values_filter()),
229 _ << "invalid dual_values_filter");
232 model, proto.quadratic_dual_values_filter()),
233 _ << "invalid quadratic_dual_values_filter");
236 VariableFilterFromProto(model, proto.reduced_costs_filter()),
237 _ << "invalid reduced_costs_filter");
238 if (proto.has_initial_basis()) {
240 result.initial_basis,
241 Basis::FromProto(model.storage(), proto.initial_basis()),
242 _ << "invalid initial_basis");
243 }
244 for (int i = 0; i < proto.solution_hints_size(); ++i) {
247 SolutionHint::FromProto(model, proto.solution_hints(i)),
248 _ << "invalid solution_hints[" << i << "]");
249 result.solution_hints.push_back(std::move(hint));
250 }
253 VariableValuesFromProto(model.storage(), proto.branching_priorities()),
254 _ << "invalid branching_priorities");
255 if (proto.has_primary_objective_parameters()) {
256 result.objective_parameters.try_emplace(
257 Objective::Primary(model.storage()),
258 ObjectiveParameters::FromProto(proto.primary_objective_parameters()));
259 }
260 for (const auto& [id, aux_obj_params_proto] :
261 proto.auxiliary_objective_parameters()) {
262 if (!model.has_auxiliary_objective(id)) {
264 << "invalid auxiliary_objective_parameters with id: " << id
265 << ", objective not in the model";
266 }
267 result.objective_parameters.try_emplace(
268 Objective::Auxiliary(model.storage(), AuxiliaryObjectiveId{id}),
269 ObjectiveParameters::FromProto(aux_obj_params_proto));
270 }
271 for (int64_t lin_con : proto.lazy_linear_constraint_ids()) {
272 if (!model.has_linear_constraint(lin_con)) {
274 << "invalid lazy_linear_constraint with id: " << lin_con
275 << ", constraint not in the model";
276 }
277 result.lazy_linear_constraints.insert(model.linear_constraint(lin_con));
278 }
279 return result;
280}
281
282} // namespace math_opt
283} // namespace operations_research
#define RETURN_IF_ERROR(expr)
static Objective Primary(const ModelStorage *storage)
Returns an object that refers to the primary objective of the model.
Definition objective.h:220
static Objective Auxiliary(const ModelStorage *storage, AuxiliaryObjectiveId id)
Returns an object that refers to an auxiliary objective of the model.
Definition objective.h:224
SatParameters parameters
CpModelProto proto
The output proto.
IntVar * var
absl::Span< const int64_t > variable_ids
GRBmodel * model
std::optional< ModelSolveParameters::SolutionHint > hint
absl::Status CheckModelStorage(const ModelStorage *const storage, const ModelStorage *const expected_storage)
Definition key_types.h:168
absl::flat_hash_map< Variable, V > VariableMap
MapFilter< KeyType > MakeSkipAllFilter()
Definition map_filter.h:142
absl::flat_hash_map< LinearConstraint, V > LinearConstraintMap
SparseDoubleVectorProto LinearConstraintValuesToProto(const LinearConstraintMap< double > &linear_constraint_values)
Returns the proto equivalent of linear_constraint_values.
absl::StatusOr< LinearConstraintMap< double > > LinearConstraintValuesFromProto(const ModelStorage *const model, const SparseDoubleVectorProto &lin_cons_proto)
absl::StatusOr< VariableMap< double > > VariableValuesFromProto(const ModelStorage *const model, const SparseDoubleVectorProto &vars_proto)
absl::StatusOr< MapFilter< LinearConstraint > > LinearConstraintFilterFromProto(const Model &model, const SparseVectorFilterProto &proto)
Definition map_filter.cc:46
SparseDoubleVectorProto VariableValuesToProto(const VariableMap< double > &variable_values)
Returns the proto equivalent of variable_values.
absl::StatusOr< MapFilter< QuadraticConstraint > > QuadraticConstraintFilterFromProto(const Model &model, const SparseVectorFilterProto &proto)
Definition map_filter.cc:67
std::vector< typename Map::key_type > SortedKeys(const Map &map)
Definition key_types.h:87
absl::StatusOr< MapFilter< Variable > > VariableFilterFromProto(const Model &model, const SparseVectorFilterProto &proto)
Definition map_filter.cc:28
In SWIG mode, we don't want anything besides these top-level includes.
StatusBuilder InvalidArgumentErrorBuilder()
static absl::StatusOr< Basis > FromProto(const ModelStorage *model, const BasisProto &basis_proto)
Definition solution.cc:183
Parameters for an individual objective in a multi-objective model.
static ObjectiveParameters FromProto(const ObjectiveParametersProto &proto)
ObjectiveParametersProto Proto() const
Returns the proto equivalent of this object.
static absl::StatusOr< SolutionHint > FromProto(const Model &model, const SolutionHintProto &hint_proto)
absl::Status CheckModelStorage(const ModelStorage *expected_storage) const
absl::Status CheckModelStorage(const ModelStorage *expected_storage) const
MapFilter< QuadraticConstraint > quadratic_dual_values_filter
MapFilter< LinearConstraint > dual_values_filter
The filter that is applied to dual_values of DualSolution and DualRay.
ObjectiveMap< ObjectiveParameters > objective_parameters
Parameters for individual objectives in a multi-objective model.
static ModelSolveParameters OnlySomePrimalVariables(const Collection &variables)
MapFilter< Variable > reduced_costs_filter
The filter that is applied to reduced_costs of DualSolution and DualRay.
static absl::StatusOr< ModelSolveParameters > FromProto(const Model &model, const ModelSolveParametersProto &proto)
absl::flat_hash_set< LinearConstraint > lazy_linear_constraints
#define OR_ASSIGN_OR_RETURN3(lhs, rexpr, error_expression)