OR-Tools  9.6
sat/parameters_validation.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 <string>
17 #include <vector>
18 
19 #include "absl/container/flat_hash_set.h"
20 #include "absl/strings/str_cat.h"
21 #include "ortools/sat/sat_parameters.pb.h"
22 
23 namespace operations_research {
24 namespace sat {
25 
26 #define TEST_IN_RANGE(name, min, max) \
27  if (params.name() < min || params.name() > max) { \
28  return absl::StrCat("parameter '", #name, "' should be in [", min, ",", \
29  max, "]. Current value is ", params.name()); \
30  }
31 
32 #define TEST_NON_NEGATIVE(name) \
33  if (params.name() < 0) { \
34  return absl::StrCat("Parameters ", #name, " must be non-negative"); \
35  }
36 
37 #define TEST_POSITIVE(name) \
38  if (params.name() <= 0) { \
39  return absl::StrCat("Parameters ", #name, " must be positive"); \
40  }
41 
42 #define TEST_NOT_NAN(name) \
43  if (std::isnan(params.name())) { \
44  return absl::StrCat("parameter '", #name, "' is NaN"); \
45  }
46 
47 #define TEST_IS_FINITE(name) \
48  if (!std::isfinite(params.name())) { \
49  return absl::StrCat("parameter '", #name, "' is NaN or not finite"); \
50  }
51 
52 std::string ValidateParameters(const SatParameters& params) {
53  // Test that all floating point parameters are not NaN or +/- infinity.
54  TEST_IS_FINITE(random_polarity_ratio);
55  TEST_IS_FINITE(random_branches_ratio);
56  TEST_IS_FINITE(initial_variables_activity);
57  TEST_IS_FINITE(clause_cleanup_ratio);
58  TEST_IS_FINITE(pb_cleanup_ratio);
59  TEST_IS_FINITE(variable_activity_decay);
60  TEST_IS_FINITE(max_variable_activity_value);
61  TEST_IS_FINITE(glucose_max_decay);
62  TEST_IS_FINITE(glucose_decay_increment);
63  TEST_IS_FINITE(clause_activity_decay);
64  TEST_IS_FINITE(max_clause_activity_value);
65  TEST_IS_FINITE(restart_dl_average_ratio);
66  TEST_IS_FINITE(restart_lbd_average_ratio);
67  TEST_IS_FINITE(blocking_restart_multiplier);
68  TEST_IS_FINITE(strategy_change_increase_ratio);
69  TEST_IS_FINITE(absolute_gap_limit);
70  TEST_IS_FINITE(relative_gap_limit);
71  TEST_IS_FINITE(log_frequency_in_seconds);
72  TEST_IS_FINITE(model_reduction_log_frequency_in_seconds);
73  TEST_IS_FINITE(probing_deterministic_time_limit);
74  TEST_IS_FINITE(presolve_probing_deterministic_time_limit);
75  TEST_IS_FINITE(propagation_loop_detection_factor);
76  TEST_IS_FINITE(merge_no_overlap_work_limit);
77  TEST_IS_FINITE(merge_at_most_one_work_limit);
78  TEST_IS_FINITE(min_orthogonality_for_lp_constraints);
79  TEST_IS_FINITE(cut_max_active_count_value);
80  TEST_IS_FINITE(cut_active_count_decay);
81  TEST_IS_FINITE(shaving_search_deterministic_time);
82  TEST_IS_FINITE(mip_max_bound);
83  TEST_IS_FINITE(mip_var_scaling);
84  TEST_IS_FINITE(mip_wanted_precision);
85  TEST_IS_FINITE(mip_check_precision);
86  TEST_IS_FINITE(mip_max_valid_magnitude);
87  TEST_IS_FINITE(mip_drop_tolerance);
88 
89  TEST_NOT_NAN(max_time_in_seconds);
90  TEST_NOT_NAN(max_deterministic_time);
91 
92  // TODO(user): Consider using annotations directly in the proto for these
93  // validation. It is however not open sourced.
94  TEST_IN_RANGE(mip_max_activity_exponent, 1, 62);
95  TEST_IN_RANGE(mip_max_bound, 0, 1e17);
96  TEST_IN_RANGE(solution_pool_size, 1, std::numeric_limits<int32_t>::max());
97 
98  TEST_POSITIVE(glucose_decay_increment_period);
99 
100  TEST_NON_NEGATIVE(mip_wanted_precision);
101  TEST_NON_NEGATIVE(max_time_in_seconds);
102  TEST_NON_NEGATIVE(max_deterministic_time);
103  TEST_NON_NEGATIVE(new_constraints_batch_size);
104  TEST_NON_NEGATIVE(num_workers);
105  TEST_NON_NEGATIVE(num_search_workers);
106  TEST_NON_NEGATIVE(min_num_lns_workers);
107  TEST_NON_NEGATIVE(interleave_batch_size);
108  TEST_NON_NEGATIVE(probing_deterministic_time_limit);
109  TEST_NON_NEGATIVE(presolve_probing_deterministic_time_limit);
110 
111  if (params.enumerate_all_solutions() &&
112  (params.num_search_workers() > 1 || params.num_workers() > 1)) {
113  return "Enumerating all solutions does not work in parallel";
114  }
115 
116  if (params.enumerate_all_solutions() &&
117  (!params.subsolvers().empty() || !params.extra_subsolvers().empty() ||
118  !params.ignore_subsolvers().empty())) {
119  return "Enumerating all solutions does not work with custom subsolvers";
120  }
121 
122  if (params.num_search_workers() >= 1 && params.num_workers() >= 1) {
123  return "Do not specify both num_search_workers and num_workers";
124  }
125 
126  if (params.enumerate_all_solutions() && params.interleave_search()) {
127  return "Enumerating all solutions does not work with interleaved search";
128  }
129 
130  absl::flat_hash_set<std::string> valid_subsolvers({
131  "auto",
132  "core_default_lp",
133  "core_max_lp",
134  "core_or_no_lp",
135  "core",
136  "default_lp",
137  "default",
138  "fixed",
139  "lb_tree_search",
140  "less_encoding",
141  "max_hs",
142  "max_lp",
143  "no_lp",
144  "objective_lb_search_max_lp",
145  "objective_lb_search_no_lp",
146  "objective_lb_search",
147  "probing_max_lp",
148  "probing_no_lp",
149  "probing",
150  "quick_restart_max_lp",
151  "quick_restart_no_lp",
152  "quick_restart",
153  "reduced_costs",
154  });
155  for (const SatParameters& new_subsolver : params.subsolver_params()) {
156  if (new_subsolver.name().empty()) {
157  return "New subsolver parameter defined without a name";
158  }
159  valid_subsolvers.insert(new_subsolver.name());
160  }
161 
162  for (const std::string& subsolver : params.subsolvers()) {
163  if (!valid_subsolvers.contains(subsolver)) {
164  return absl::StrCat("subsolver \'", subsolver, "\' is not valid");
165  }
166  }
167 
168  for (const std::string& subsolver : params.extra_subsolvers()) {
169  if (!valid_subsolvers.contains(subsolver)) {
170  return absl::StrCat("subsolver \'", subsolver, "\' is not valid");
171  }
172  }
173 
174  for (const std::string& subsolver : params.ignore_subsolvers()) {
175  if (!valid_subsolvers.contains(subsolver)) {
176  return absl::StrCat("subsolver \'", subsolver, "\' is not valid");
177  }
178  }
179  return "";
180 }
181 
182 #undef TEST_IN_RANGE
183 #undef TEST_POSITIVE
184 #undef TEST_NON_NEGATIVE
185 #undef TEST_NOT_NAN
186 #undef TEST_IS_FINITE
187 
188 } // namespace sat
189 } // namespace operations_research
int64_t max
Definition: alldiff_cst.cc:140
std::string ValidateParameters(const SatParameters &params)
Collection of objects used to extend the Constraint Solver library.
#define TEST_IN_RANGE(name, min, max)
#define TEST_NON_NEGATIVE(name)
#define TEST_POSITIVE(name)
#define TEST_NOT_NAN(name)
#define TEST_IS_FINITE(name)