forked from google/or-tools
-
Notifications
You must be signed in to change notification settings - Fork 9
/
bop_fs.h
150 lines (129 loc) · 5.83 KB
/
bop_fs.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2010-2024 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef OR_TOOLS_BOP_BOP_FS_H_
#define OR_TOOLS_BOP_BOP_FS_H_
#include <cstdint>
#include <memory>
#include "absl/random/bit_gen_ref.h"
#include "absl/strings/string_view.h"
#include "ortools/bop/bop_base.h"
#include "ortools/bop/bop_parameters.pb.h"
#include "ortools/glop/lp_solver.h"
#include "ortools/lp_data/lp_data.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/sat/sat_solver.h"
#include "ortools/util/time_limit.h"
namespace operations_research {
namespace bop {
// Tries to find a first solution using SAT and a given assignment preference.
// This optimizer will never run again once it has found a solution except if
// the policy is kNotGuided in which case it will be ran again.
class GuidedSatFirstSolutionGenerator : public BopOptimizerBase {
public:
// The different guiding heuristics
enum class Policy {
kNotGuided, // The default SAT solver.
kLpGuided, // Guided by the values of the linear relaxation.
kObjectiveGuided, // Guided by the objective coefficient.
kUserGuided, // Guided by the problem assignment_preference().
};
GuidedSatFirstSolutionGenerator(absl::string_view name, Policy policy);
~GuidedSatFirstSolutionGenerator() override;
bool ShouldBeRun(const ProblemState& problem_state) const override;
// Note that if the last call to Optimize() returned CONTINUE and if the
// problem didn't change, calling this will resume the solve from its last
// position.
Status Optimize(const BopParameters& parameters,
const ProblemState& problem_state, LearnedInfo* learned_info,
TimeLimit* time_limit) override;
private:
BopOptimizerBase::Status SynchronizeIfNeeded(
const ProblemState& problem_state);
const Policy policy_;
bool abort_;
int64_t state_update_stamp_;
std::unique_ptr<sat::SatSolver> sat_solver_;
};
// This class implements an optimizer that tries various random search
// strategies, each with a really low conflict limit. It can be used to generate
// a first solution or to improve an existing one.
//
// By opposition to all the other optimizers, this one doesn't return right away
// when a new solution is found. Instead, it continues to improve it as long as
// it has time.
//
// TODO(user): Coupled with some Local Search it might be used to diversify
// the solutions. To try.
class BopRandomFirstSolutionGenerator : public BopOptimizerBase {
public:
BopRandomFirstSolutionGenerator(absl::string_view name,
const BopParameters& parameters,
sat::SatSolver* sat_propagator,
absl::BitGenRef random);
~BopRandomFirstSolutionGenerator() override;
bool ShouldBeRun(const ProblemState& problem_state) const override;
Status Optimize(const BopParameters& parameters,
const ProblemState& problem_state, LearnedInfo* learned_info,
TimeLimit* time_limit) override;
private:
BopOptimizerBase::Status SynchronizeIfNeeded(
const ProblemState& problem_state);
int random_seed_;
absl::BitGenRef random_;
sat::SatSolver* sat_propagator_;
};
// This class computes the linear relaxation of the state problem.
// Optimize() fills the relaxed values (possibly floating values) that can be
// used by other optimizers as BopSatLpFirstSolutionGenerator for instance,
// and the lower bound.
class LinearRelaxation : public BopOptimizerBase {
public:
LinearRelaxation(const BopParameters& parameters, absl::string_view name);
~LinearRelaxation() override;
bool ShouldBeRun(const ProblemState& problem_state) const override;
Status Optimize(const BopParameters& parameters,
const ProblemState& problem_state, LearnedInfo* learned_info,
TimeLimit* time_limit) override;
private:
BopOptimizerBase::Status SynchronizeIfNeeded(
const ProblemState& problem_state);
// Runs Glop to solve the current lp_model_.
// Updates the time limit and returns the status of the solve.
// Note that when the solve is incremental, the preprocessor is deactivated,
// and the dual simplex is used.
glop::ProblemStatus Solve(bool incremental_solve, TimeLimit* time_limit);
// Computes and returns a better best bound using strong branching, i.e.
// doing a what-if analysis on each variable v: compute the best bound when
// v is assigned to true, compute the best bound when v is assigned to false,
// and then use those best bounds to improve the overall best bound.
// As a side effect, it might fix some variables.
double ComputeLowerBoundUsingStrongBranching(LearnedInfo* learned_info,
TimeLimit* time_limit);
// Returns true when the cost is worse than the cost of the current solution.
// If they are within the given tolerance, returns false.
bool CostIsWorseThanSolution(double scaled_cost, double tolerance) const;
const BopParameters parameters_;
int64_t state_update_stamp_;
bool lp_model_loaded_;
int num_full_solves_;
glop::LinearProgram lp_model_;
glop::LPSolver lp_solver_;
double scaling_;
double offset_;
int num_fixed_variables_;
bool problem_already_solved_;
double scaled_solution_cost_;
};
} // namespace bop
} // namespace operations_research
#endif // OR_TOOLS_BOP_BOP_FS_H_