OR-Tools  9.6
parameters.cc
Go to the documentation of this file.
1 // Copyright 2010-2022 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 #include <optional>
18 #include <sstream>
19 #include <string>
20 #include <type_traits>
21 #include <utility>
22 
23 #include "absl/status/status.h"
24 #include "absl/status/statusor.h"
25 #include "absl/strings/string_view.h"
26 #include "absl/time/time.h"
27 #include "absl/types/span.h"
28 #include "ortools/base/logging.h"
29 #include "ortools/base/protoutil.h"
31 #include "ortools/math_opt/parameters.pb.h"
32 #include "ortools/math_opt/solvers/gurobi.pb.h"
35 
36 namespace operations_research {
37 namespace math_opt {
38 namespace {
39 
40 template <typename EnumType>
41 bool ParseEnumFlag(const absl::string_view text, EnumType* const value,
42  std::string* const error) {
43  const std::optional<EnumType> enum_value = EnumFromString<EnumType>(text);
44  if (!enum_value.has_value()) {
45  *error = "unknown value for enumeration";
46  return false;
47  }
48 
49  *value = *enum_value;
50  return true;
51 }
52 
53 template <typename EnumType>
54 std::string UnparseEnumFlag(const EnumType value) {
55  std::ostringstream oss;
56  oss << value;
57  return oss.str();
58 }
59 
60 } // namespace
61 
62 std::optional<absl::string_view> Enum<SolverType>::ToOptString(
63  SolverType value) {
64  switch (value) {
65  case SolverType::kGscip:
66  return "gscip";
68  return "gurobi";
69  case SolverType::kGlop:
70  return "glop";
71  case SolverType::kCpSat:
72  return "cp_sat";
73  case SolverType::kGlpk:
74  return "glpk";
75  }
76  return std::nullopt;
77 }
78 
79 absl::Span<const SolverType> Enum<SolverType>::AllValues() {
80  static constexpr SolverType kSolverTypeValues[] = {
83  };
84  return absl::MakeConstSpan(kSolverTypeValues);
85 }
86 
87 bool AbslParseFlag(const absl::string_view text, SolverType* const value,
88  std::string* const error) {
89  return ParseEnumFlag(text, value, error);
90 }
91 
92 std::string AbslUnparseFlag(const SolverType value) {
93  return UnparseEnumFlag(value);
94 }
95 
96 std::optional<absl::string_view> Enum<LPAlgorithm>::ToOptString(
98  switch (value) {
100  return "primal_simplex";
102  return "dual_simplex";
104  return "barrier";
105  }
106  return std::nullopt;
107 }
108 
109 absl::Span<const LPAlgorithm> Enum<LPAlgorithm>::AllValues() {
110  static constexpr LPAlgorithm kLPAlgorithmValues[] = {
114  };
115  return absl::MakeConstSpan(kLPAlgorithmValues);
116 }
117 
118 bool AbslParseFlag(absl::string_view text, LPAlgorithm* const value,
119  std::string* const error) {
120  return ParseEnumFlag(text, value, error);
121 }
122 
123 std::string AbslUnparseFlag(const LPAlgorithm value) {
124  return UnparseEnumFlag(value);
125 }
126 
127 std::optional<absl::string_view> Enum<Emphasis>::ToOptString(Emphasis value) {
128  switch (value) {
129  case Emphasis::kOff:
130  return "off";
131  case Emphasis::kLow:
132  return "low";
133  case Emphasis::kMedium:
134  return "medium";
135  case Emphasis::kHigh:
136  return "high";
137  case Emphasis::kVeryHigh:
138  return "very_high";
139  }
140  return std::nullopt;
141 }
142 
143 absl::Span<const Emphasis> Enum<Emphasis>::AllValues() {
144  static constexpr Emphasis kEmphasisValues[] = {
147  };
148  return absl::MakeConstSpan(kEmphasisValues);
149 }
150 
151 bool AbslParseFlag(absl::string_view text, Emphasis* const value,
152  std::string* const error) {
153  return ParseEnumFlag(text, value, error);
154 }
155 
156 std::string AbslUnparseFlag(const Emphasis value) {
157  return UnparseEnumFlag(value);
158 }
159 
160 GurobiParametersProto GurobiParameters::Proto() const {
161  GurobiParametersProto result;
162  for (const auto& [key, val] : param_values) {
163  GurobiParametersProto::Parameter& p = *result.add_parameters();
164  p.set_name(key);
165  p.set_value(val);
166  }
167  return result;
168 }
169 
171  const GurobiParametersProto& proto) {
172  GurobiParameters result;
173  for (const GurobiParametersProto::Parameter& p : proto.parameters()) {
174  result.param_values[p.name()] = p.value();
175  }
176  return result;
177 }
178 
179 SolveParametersProto SolveParameters::Proto() const {
180  SolveParametersProto result;
181  result.set_enable_output(enable_output);
182  if (time_limit < absl::InfiniteDuration()) {
184  result.mutable_time_limit()));
185  }
186  if (iteration_limit.has_value()) {
187  result.set_iteration_limit(*iteration_limit);
188  }
189  if (node_limit.has_value()) {
190  result.set_node_limit(*node_limit);
191  }
192  if (cutoff_limit.has_value()) {
193  result.set_cutoff_limit(*cutoff_limit);
194  }
195  if (objective_limit.has_value()) {
196  result.set_objective_limit(*objective_limit);
197  }
198  if (best_bound_limit.has_value()) {
199  result.set_best_bound_limit(*best_bound_limit);
200  }
201  if (solution_limit.has_value()) {
202  result.set_solution_limit(*solution_limit);
203  }
204  if (threads.has_value()) {
205  result.set_threads(*threads);
206  }
207  if (random_seed.has_value()) {
208  result.set_random_seed(*random_seed);
209  }
210  if (relative_gap_tolerance.has_value()) {
211  result.set_relative_gap_tolerance(*relative_gap_tolerance);
212  }
213  if (absolute_gap_tolerance.has_value()) {
214  result.set_absolute_gap_tolerance(*absolute_gap_tolerance);
215  }
216  if (solution_pool_size.has_value()) {
217  result.set_solution_pool_size(*solution_pool_size);
218  }
219  result.set_lp_algorithm(EnumToProto(lp_algorithm));
220  result.set_presolve(EnumToProto(presolve));
221  result.set_cuts(EnumToProto(cuts));
222  result.set_heuristics(EnumToProto(heuristics));
223  result.set_scaling(EnumToProto(scaling));
224  *result.mutable_gscip() = gscip;
225  *result.mutable_gurobi() = gurobi.Proto();
226  *result.mutable_glop() = glop;
227  *result.mutable_cp_sat() = cp_sat;
228  return result;
229 }
230 
231 absl::StatusOr<SolveParameters> SolveParameters::FromProto(
232  const SolveParametersProto& proto) {
233  SolveParameters result;
234  result.enable_output = proto.enable_output();
235  if (proto.has_time_limit()) {
238  _ << "invalid time_limit");
239  } else {
240  result.time_limit = absl::InfiniteDuration();
241  }
242  if (proto.has_iteration_limit()) {
243  result.iteration_limit = proto.iteration_limit();
244  }
245  if (proto.has_node_limit()) {
246  result.node_limit = proto.node_limit();
247  }
248  if (proto.has_cutoff_limit()) {
249  result.cutoff_limit = proto.cutoff_limit();
250  }
251  if (proto.has_objective_limit()) {
252  result.objective_limit = proto.objective_limit();
253  }
254  if (proto.has_best_bound_limit()) {
255  result.best_bound_limit = proto.best_bound_limit();
256  }
257  if (proto.has_solution_limit()) {
258  result.solution_limit = proto.solution_limit();
259  }
260  if (proto.has_threads()) {
261  result.threads = proto.threads();
262  }
263  if (proto.has_random_seed()) {
264  result.random_seed = proto.random_seed();
265  }
266  if (proto.has_absolute_gap_tolerance()) {
267  result.absolute_gap_tolerance = proto.absolute_gap_tolerance();
268  }
269  if (proto.has_relative_gap_tolerance()) {
270  result.relative_gap_tolerance = proto.relative_gap_tolerance();
271  }
272  if (proto.has_solution_pool_size()) {
273  result.solution_pool_size = proto.solution_pool_size();
274  }
275  result.lp_algorithm = EnumFromProto(proto.lp_algorithm());
276  result.presolve = EnumFromProto(proto.presolve());
277  result.cuts = EnumFromProto(proto.cuts());
278  result.heuristics = EnumFromProto(proto.heuristics());
279  result.scaling = EnumFromProto(proto.scaling());
280  result.gscip = proto.gscip();
281  result.gurobi = GurobiParameters::FromProto(proto.gurobi());
282  result.glop = proto.glop();
283  result.cp_sat = proto.cp_sat();
284  return result;
285 }
286 
287 bool AbslParseFlag(absl::string_view text, SolveParameters* solve_parameters,
288  std::string* error) {
289  SolveParametersProto proto;
290  if (!ProtobufParseTextProtoForFlag(text, &proto, error)) {
291  return false;
292  }
293  absl::StatusOr<SolveParameters> params = SolveParameters::FromProto(proto);
294  if (!params.ok()) {
295  *error = absl::StrCat(
296  "SolveParametersProto was invalid and could not convert to "
297  "SolveParameters: ",
298  params.status().ToString());
299  return false;
300  }
301  *solve_parameters = *std::move(params);
302  return true;
303 }
304 
305 std::string AbslUnparseFlag(SolveParameters solve_parameters) {
306  return ProtobufTextFormatPrintToString(solve_parameters.Proto());
307 }
308 
309 } // namespace math_opt
310 } // namespace operations_research
CpModelProto proto
int64_t value
bool AbslParseFlag(const absl::string_view text, SolverType *const value, std::string *const error)
Definition: parameters.cc:87
std::string AbslUnparseFlag(const SolverType value)
Definition: parameters.cc:92
std::optional< typename EnumProto< P >::Cpp > EnumFromProto(const P proto_value)
Definition: enums.h:279
Enum< E >::Proto EnumToProto(const std::optional< E > value)
Definition: enums.h:268
Collection of objects used to extend the Constraint Solver library.
std::string ProtobufTextFormatPrintToString(const ProtoType proto)
bool ProtobufParseTextProtoForFlag(absl::string_view text, ProtoType *message_out, std::string *error_out)
inline ::absl::StatusOr< absl::Duration > DecodeGoogleApiProto(const google::protobuf::Duration &proto)
Definition: protoutil.h:42
inline ::absl::StatusOr< google::protobuf::Duration > EncodeGoogleApiProto(absl::Duration d)
Definition: protoutil.h:27
static std::optional< absl::string_view > ToOptString(E value)
Definition: basis_status.cc:24
static absl::Span< const E > AllValues()
Definition: basis_status.cc:41
static GurobiParameters FromProto(const GurobiParametersProto &proto)
Definition: parameters.cc:170
gtl::linked_hash_map< std::string, std::string > param_values
Definition: parameters.h:178
std::optional< double > absolute_gap_tolerance
Definition: parameters.h:295
std::optional< double > relative_gap_tolerance
Definition: parameters.h:310
std::optional< LPAlgorithm > lp_algorithm
Definition: parameters.h:328
static absl::StatusOr< SolveParameters > FromProto(const SolveParametersProto &proto)
Definition: parameters.cc:231
std::optional< int32_t > solution_pool_size
Definition: parameters.h:320
#define OR_ASSIGN_OR_RETURN3(lhs, rexpr, error_expression)