OR-Tools  9.1
lb_tree_search.h
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#ifndef OR_TOOLS_SAT_LB_TREE_SEARCH_H_
15#define OR_TOOLS_SAT_LB_TREE_SEARCH_H_
16
17#include <limits>
18#include <vector>
19
20#include "ortools/sat/integer.h"
25
26namespace operations_research {
27namespace sat {
28
29// Implement a "classic" MIP tree search by having an exhaustive list of open
30// nodes.
31//
32// The goal of this subsolver is to improve the objective lower bound. It is
33// meant to be used in a multi-thread portfolio, and as such it really do not
34// care about finding solution. It is all about improving the lower bound.
35//
36// TODO(user): What this is doing is really similar to asking a SAT solver if
37// the current objective lower bound is reachable by solving a SAT problem.
38// However, this code handle on the side all the "conflict" of the form
39// objective > current_lb. As a result, when it is UNSAT, we can bump the lower
40// bound by a bigger amount than one. We also do not completely loose everything
41// learned so far for the next iteration.
43 public:
44 explicit LbTreeSearch(Model* model);
45
46 // Explores the search space.
48 const std::function<void()>& feasible_solution_observer);
49
50 private:
51 // Code a binary tree.
52 struct Node {
53 Node(Literal l, IntegerValue lb)
54 : literal(l),
55 objective_lb(lb),
56 true_objective(lb),
57 false_objective(lb) {}
58
59 // Invariant: the objective bounds only increase.
60 void UpdateObjective() {
61 objective_lb =
62 std::max(objective_lb, std::min(true_objective, false_objective));
63 }
64 void UpdateTrueObjective(IntegerValue v) {
65 true_objective = std::max(true_objective, v);
66 UpdateObjective();
67 }
68 void UpdateFalseObjective(IntegerValue v) {
69 false_objective = std::max(false_objective, v);
70 UpdateObjective();
71 }
72
73 // The decision for the true and false branch under this node.
74 /*const*/ Literal literal;
75
76 // The objective lower bound at this node.
77 IntegerValue objective_lb;
78
79 // The objective lower bound in both branches.
80 // This is only updated when we backtrack over this node.
81 IntegerValue true_objective;
82 IntegerValue false_objective;
83
84 // Points to adjacent nodes in the tree. Large if no connection.
85 int true_child = std::numeric_limits<int32_t>::max();
86 int false_child = std::numeric_limits<int32_t>::max();
87
88 // Instead of storing the full reason for an objective LB increase in one
89 // the branches (which can lead to a quadratic memory usage), we stores the
90 // level of the highest decision needed, not counting this node literal.
91 // Basically, the reason for true_objective without {literal} only includes
92 // literal with levels in [0, true_level].
93 //
94 // This allows us to slighlty reduce the size of the overall tree. If both
95 // branches have a low enough level, then we can backjump in the search tree
96 // and skip all the nodes in-between by connecting directly the correct
97 // ancestor to this node. Note that when we do that, the level of the nodes
98 // in the sub-branch change, but this still work.
99 int true_level = std::numeric_limits<int32_t>::max();
100 int false_level = std::numeric_limits<int32_t>::max();
101 };
102
103 // Returns true if this node objective lb is greater than the root level
104 // objective lower bound.
105 bool NodeImprovesLowerBound(const LbTreeSearch::Node& node);
106
107 // Model singleton class used here.
108 TimeLimit* time_limit_;
109 ModelRandomGenerator* random_;
110 SatSolver* sat_solver_;
111 IntegerTrail* integer_trail_;
112 SharedResponseManager* shared_response_;
113 SatDecisionPolicy* sat_decision_;
114 IntegerSearchHelper* search_helper_;
115 IntegerVariable objective_var_;
116
117 // Memory for all the nodes.
118 std::vector<Node> nodes_;
119
120 // The list of nodes in the current branch, in order from the root.
121 std::vector<int> current_branch_;
122
123 // Our heuristic used to explore the tree. See code for detail.
124 std::function<BooleanOrIntegerLiteral()> search_heuristic_;
125};
126
127} // namespace sat
128} // namespace operations_research
129
130#endif // OR_TOOLS_SAT_LB_TREE_SEARCH_H_
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:105
SatSolver::Status Search(const std::function< void()> &feasible_solution_observer)
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:38
GRBmodel * model
Collection of objects used to extend the Constraint Solver library.
Literal literal
Definition: optimization.cc:85