OR-Tools  9.2
rins.cc
Go to the documentation of this file.
1// Copyright 2010-2021 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
14#include "ortools/sat/rins.h"
15
16#include <cstdint>
17#include <limits>
18
20#include "ortools/sat/integer.h"
22
23namespace operations_research {
24namespace sat {
25
28 if (lp_solutions == nullptr) return;
29
30 const LPVariables& lp_vars = *model->GetOrCreate<LPVariables>();
31 std::vector<double> relaxation_values(
32 lp_vars.model_vars_size, std::numeric_limits<double>::infinity());
33
34 auto* integer_trail = model->GetOrCreate<IntegerTrail>();
35 for (const LPVariable& lp_var : lp_vars.vars) {
36 const IntegerVariable positive_var = lp_var.positive_var;
37 if (integer_trail->IsCurrentlyIgnored(positive_var)) continue;
38
40 if (lp == nullptr || !lp->HasSolution()) continue;
41
42 relaxation_values[lp_var.model_var] = lp->GetSolutionValue(positive_var);
43 }
44 lp_solutions->NewLPSolution(std::move(relaxation_values));
45}
46
47namespace {
48
49std::vector<double> GetLPRelaxationValues(
50 const SharedLPSolutionRepository* lp_solutions, absl::BitGenRef random) {
51 std::vector<double> relaxation_values;
52
53 if (lp_solutions == nullptr || lp_solutions->NumSolutions() == 0) {
54 return relaxation_values;
55 }
56
57 // TODO(user): Experiment with random biased solutions.
58 const SharedSolutionRepository<double>::Solution lp_solution =
60
61 for (int model_var = 0; model_var < lp_solution.variable_values.size();
62 ++model_var) {
63 relaxation_values.push_back(lp_solution.variable_values[model_var]);
64 }
65 return relaxation_values;
66}
67
68std::vector<double> GetGeneralRelaxationValues(
69 const SharedRelaxationSolutionRepository* relaxation_solutions,
70 absl::BitGenRef random) {
71 std::vector<double> relaxation_values;
72
73 if (relaxation_solutions == nullptr ||
75 return relaxation_values;
76 }
77 const SharedSolutionRepository<int64_t>::Solution relaxation_solution =
79
80 for (int model_var = 0;
81 model_var < relaxation_solution.variable_values.size(); ++model_var) {
82 relaxation_values.push_back(relaxation_solution.variable_values[model_var]);
83 }
84 return relaxation_values;
85}
86
87std::vector<double> GetIncompleteSolutionValues(
88 SharedIncompleteSolutionManager* incomplete_solutions) {
89 std::vector<double> empty_solution_values;
90
91 if (incomplete_solutions == nullptr ||
93 return empty_solution_values;
94 }
95
97}
98} // namespace
99
101 const SharedResponseManager* response_manager,
105 absl::BitGenRef random) {
106 RINSNeighborhood rins_neighborhood;
107
108 const bool use_only_relaxation_values =
109 (response_manager == nullptr ||
110 response_manager->SolutionsRepository().NumSolutions() == 0);
111
112 if (use_only_relaxation_values && lp_solutions == nullptr &&
113 incomplete_solutions == nullptr) {
114 // As of now RENS doesn't generate good neighborhoods from integer
115 // relaxation solutions.
116 return rins_neighborhood;
117 }
118
119 std::vector<double> relaxation_values;
120 if (incomplete_solutions != nullptr) {
121 relaxation_values = GetIncompleteSolutionValues(incomplete_solutions);
122 } else if (lp_solutions != nullptr) {
123 relaxation_values = GetLPRelaxationValues(lp_solutions, random);
124 } else {
125 CHECK(relaxation_solutions != nullptr)
126 << "No relaxation solutions repository or lp solutions repository "
127 "provided.";
128 relaxation_values =
129 GetGeneralRelaxationValues(relaxation_solutions, random);
130 }
131 if (relaxation_values.empty()) return rins_neighborhood;
132
133 const double tolerance = 1e-6;
135 use_only_relaxation_values
137 : response_manager->SolutionsRepository().GetRandomBiasedSolution(
138 random);
139 for (int model_var = 0; model_var < relaxation_values.size(); ++model_var) {
140 const double relaxation_value = relaxation_values[model_var];
141
142 if (relaxation_value == std::numeric_limits<double>::infinity()) {
143 continue;
144 }
145
146 if (use_only_relaxation_values) {
147 // The tolerance make sure that if the relaxation_value is close to an
148 // integer, then we fix the variable to this integer value.
149 //
150 // Important: the LP relaxation doesn't know about holes in the variable
151 // domains, so the intersection of [domain_lb, domain_ub] with the
152 // initial variable domain might be empty.
153 const int64_t domain_lb =
154 static_cast<int64_t>(std::floor(relaxation_value + tolerance));
155 const int64_t domain_ub =
156 static_cast<int64_t>(std::ceil(relaxation_value - tolerance));
157 if (domain_lb == domain_ub) {
158 rins_neighborhood.fixed_vars.push_back({model_var, domain_lb});
159 } else {
160 rins_neighborhood.reduced_domain_vars.push_back(
161 {model_var, {domain_lb, domain_ub}});
162 }
163
164 } else {
165 const IntegerValue best_solution_value =
166 IntegerValue(solution.variable_values[model_var]);
167 if (std::abs(best_solution_value.value() - relaxation_value) < 1e-4) {
168 rins_neighborhood.fixed_vars.push_back(
169 {model_var, best_solution_value.value()});
170 }
171 }
172 }
173
174 return rins_neighborhood;
175}
176
177} // namespace sat
178} // namespace operations_research
#define CHECK(condition)
Definition: base/logging.h:495
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:38
void NewLPSolution(std::vector< double > lp_solution)
const SharedSolutionRepository< int64_t > & SolutionsRepository() const
Solution GetRandomBiasedSolution(absl::BitGenRef random) const
SharedRelaxationSolutionRepository * relaxation_solutions
SharedLPSolutionRepository * lp_solutions
SharedIncompleteSolutionManager * incomplete_solutions
GRBmodel * model
void RecordLPRelaxationValues(Model *model)
Definition: rins.cc:26
RINSNeighborhood GetRINSNeighborhood(const SharedResponseManager *response_manager, const SharedRelaxationSolutionRepository *relaxation_solutions, const SharedLPSolutionRepository *lp_solutions, SharedIncompleteSolutionManager *incomplete_solutions, absl::BitGenRef random)
Definition: rins.cc:100
Collection of objects used to extend the Constraint Solver library.
IntegerVariable positive_var
Definition: rins.h:34
LinearProgrammingConstraint * lp
Definition: rins.h:35
std::vector< LPVariable > vars
Definition: rins.h:46
std::vector< std::pair< int, int64_t > > fixed_vars
Definition: rins.h:59
std::vector< std::pair< int, std::pair< int64_t, int64_t > > > reduced_domain_vars
Definition: rins.h:62