Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
model_parameters_validator.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 <cstdint>
17
18#include "absl/status/status.h"
19#include "google/protobuf/repeated_field.h"
24#include "ortools/math_opt/model_parameters.pb.h"
25#include "ortools/math_opt/sparse_containers.pb.h"
29
30namespace operations_research {
31namespace math_opt {
32namespace {
33
34absl::Status ValidateSolutionHint(const SolutionHintProto& solution_hint,
35 const ModelSummary& model_summary) {
37 MakeView(solution_hint.variable_values()),
38 {.allow_positive_infinity = false, .allow_negative_infinity = false}))
39 << "Invalid solution_hint.variable_values";
41 solution_hint.variable_values().ids(), model_summary.variables,
42 "solution_hint.variable_values ids", "model variable ids"));
43
45 MakeView(solution_hint.dual_values()),
46 {.allow_positive_infinity = false, .allow_negative_infinity = false}))
47 << "Invalid solution_hint.dual_values";
49 solution_hint.dual_values().ids(), model_summary.linear_constraints,
50 "solution_hint.dual_values ids", "model linear constraint ids"));
51
52 return absl::OkStatus();
53}
54
55absl::Status ValidateBranchingPriorities(
56 const SparseInt32VectorProto& branching_priorities,
57 const ModelSummary& model_summary) {
58 const auto vector_view = MakeView(branching_priorities);
60 << "Invalid branching_priorities";
61 RETURN_IF_ERROR(CheckIdsSubset(branching_priorities.ids(),
62 model_summary.variables,
63 "branching_priorities ids", "model IDs"));
64
65 return absl::OkStatus();
66}
67
68absl::Status ValidateObjectiveParameters(
69 const ObjectiveParametersProto& parameters) {
70 if (parameters.objective_degradation_absolute_tolerance() < 0) {
72 << "ObjectiveParametersProto.objective_degradation_absolute_"
73 "tolerance = "
74 << parameters.objective_degradation_absolute_tolerance() << " < 0";
75 }
76
77 if (parameters.objective_degradation_relative_tolerance() < 0) {
79 << "ObjectiveParametersProto.objective_degradation_relative_"
80 "tolerance = "
81 << parameters.objective_degradation_relative_tolerance() << " < 0";
82 }
83 return absl::OkStatus();
84}
85
86absl::Status ValidateLazyLinearConstraints(
87 const google::protobuf::RepeatedField<int64_t>& lazy_linear_constraint_ids,
88 const ModelSummary& model_summary) {
90 CheckIdsRangeAndStrictlyIncreasing(lazy_linear_constraint_ids));
92 lazy_linear_constraint_ids, model_summary.linear_constraints,
93 "lazy_linear_constraint ids", "model linear constraint IDs"));
94 return absl::OkStatus();
95}
96
97} // namespace
98
99absl::Status ValidateSparseVectorFilter(const SparseVectorFilterProto& v,
100 const IdNameBiMap& valid_ids) {
103 CheckIdsSubset(v.filtered_ids(), valid_ids, "filtered_ids", "model IDs"));
104 if (!v.filter_by_ids() && !v.filtered_ids().empty()) {
105 return absl::InvalidArgumentError(
106 "Invalid SparseVectorFilterProto.filter_by_id* specification. To "
107 "filter by "
108 "IDs you must set SparseVectorFilterProto.filter_by_ids to 'true'.");
109 }
110
111 return absl::OkStatus();
112}
113
115 const ModelSolveParametersProto& parameters,
116 const ModelSummary& model_summary) {
118 parameters.variable_values_filter(), model_summary.variables))
119 << "invalid variable_values_filter";
121 model_summary.variables))
122 << "invalid reduced_costs_filter";
124 model_summary.linear_constraints))
125 << "invalid dual_values_filter";
126 if (parameters.has_initial_basis()) {
127 RETURN_IF_ERROR(ValidateBasis(parameters.initial_basis(), model_summary,
128 /*check_dual_feasibility=*/false));
129 }
130 for (const SolutionHintProto& solution_hint : parameters.solution_hints()) {
131 RETURN_IF_ERROR(ValidateSolutionHint(solution_hint, model_summary));
132 }
133 RETURN_IF_ERROR(ValidateBranchingPriorities(parameters.branching_priorities(),
134 model_summary));
136 ValidateObjectiveParameters(parameters.primary_objective_parameters()))
137 << "invalid primary_objective_parameters";
138 for (const auto& [objective, params] :
139 parameters.auxiliary_objective_parameters()) {
140 if (!model_summary.auxiliary_objectives.HasId(objective)) {
142 << "Entry in auxiliary_objective_parameters for unknown "
143 "objective: "
144 << objective;
145 }
146 RETURN_IF_ERROR(ValidateObjectiveParameters(params))
147 << "invalid auxiliary_objective_parameters entry for objective: "
148 << objective;
149 }
150 RETURN_IF_ERROR(ValidateLazyLinearConstraints(
151 parameters.lazy_linear_constraint_ids(), model_summary))
152 << "invalid lazy_linear_constraint_ids";
153 return absl::OkStatus();
154}
155
156} // namespace math_opt
157} // namespace operations_research
#define RETURN_IF_ERROR(expr)
SatParameters parameters
SparseVectorView< T > MakeView(absl::Span< const int64_t > ids, const Collection &values)
absl::Status CheckIdsAndValues(const SparseVectorView< T > &vector_view, absl::string_view value_name="values")
absl::Status CheckIdsSubset(absl::Span< const int64_t > ids, const IdNameBiMap &universe, std::optional< int64_t > upper_bound)
absl::Status ValidateBasis(const BasisProto &basis, const ModelSummary &model_summary, const bool check_dual_feasibility)
absl::Status ValidateSparseVectorFilter(const SparseVectorFilterProto &v, const IdNameBiMap &valid_ids)
absl::Status ValidateModelSolveParameters(const ModelSolveParametersProto &parameters, const ModelSummary &model_summary)
absl::Status CheckIdsRangeAndStrictlyIncreasing(absl::Span< const int64_t > ids)
In SWIG mode, we don't want anything besides these top-level includes.
StatusBuilder InvalidArgumentErrorBuilder()