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