OR-Tools  9.2
bop_ls.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// This file defines the needed classes to efficiently perform Local Search in
15// Bop.
16// Local Search is a technique used to locally improve an existing solution by
17// flipping a limited number of variables. To be successful the produced
18// solution has to satisfy all constraints of the problem and improve the
19// objective cost.
20//
21// The class BopLocalSearchOptimizer is the only public interface for Local
22// Search in Bop. For unit-testing purposes this file also contains the four
23// internal classes AssignmentAndConstraintFeasibilityMaintainer,
24// OneFlipConstraintRepairer, SatWrapper and LocalSearchAssignmentIterator.
25// They are implementation details and should not be used outside of bop_ls.
26
27#ifndef OR_TOOLS_BOP_BOP_LS_H_
28#define OR_TOOLS_BOP_BOP_LS_H_
29
30#include <array>
31#include <cstdint>
32
33#include "absl/container/flat_hash_map.h"
34#include "absl/container/flat_hash_set.h"
35#include "absl/random/random.h"
36#include "ortools/base/hash.h"
43
44namespace operations_research {
45namespace bop {
46
47// This class is used to ease the connection with the SAT solver.
48//
49// TODO(user): remove? the meat of the logic is used in just one place, so I am
50// not sure having this extra layer improve the readability.
52 public:
53 explicit SatWrapper(sat::SatSolver* sat_solver);
54
55 // Returns the current state of the solver propagation trail.
56 std::vector<sat::Literal> FullSatTrail() const;
57
58 // Returns true if the problem is UNSAT.
59 // Note that an UNSAT problem might not be marked as UNSAT at first because
60 // the SAT solver is not able to prove it; After some decisions / learned
61 // conflicts, the SAT solver might be able to prove UNSAT and so this will
62 // return true.
63 bool IsModelUnsat() const { return sat_solver_->IsModelUnsat(); }
64
65 // Return the current solver VariablesAssignment.
67 return sat_solver_->Assignment();
68 }
69
70 // Applies the decision that makes the given literal true and returns the
71 // number of decisions to backtrack due to conflicts if any.
72 // Two cases:
73 // - No conflicts: Returns 0 and fills the propagated_literals with the
74 // literals that have been propagated due to the decision including the
75 // the decision itself.
76 // - Conflicts: Returns the number of decisions to backtrack (the current
77 // decision included, i.e. returned value > 0) and fills the
78 // propagated_literals with the literals that the conflicts propagated.
79 // Note that the decision variable should not be already assigned in SAT.
80 int ApplyDecision(sat::Literal decision_literal,
81 std::vector<sat::Literal>* propagated_literals);
82
83 // Backtracks the last decision if any.
84 void BacktrackOneLevel();
85
86 // Bactracks all the decisions.
87 void BacktrackAll();
88
89 // Extracts any new information learned during the search.
91
92 // Returns a deterministic number that should be correlated with the time
93 // spent in the SAT wrapper. The order of magnitude should be close to the
94 // time in seconds.
95 double deterministic_time() const;
96
97 private:
98 sat::SatSolver* sat_solver_;
99 DISALLOW_COPY_AND_ASSIGN(SatWrapper);
100};
101
102// Forward declaration.
103class LocalSearchAssignmentIterator;
104
105// This class defines a Local Search optimizer. The goal is to find a new
106// solution with a better cost than the given solution by iterating on all
107// assignments that can be reached in max_num_decisions decisions or less.
108// The bop parameter max_number_of_explored_assignments_per_try_in_ls can be
109// used to specify the number of new assignments to iterate on each time the
110// method Optimize() is called. Limiting that parameter allows to reduce the
111// time spent in the Optimize() method at once, and still explore all the
112// reachable assignments (if Optimize() is called enough times).
113// Note that due to propagation, the number of variables with a different value
114// in the new solution can be greater than max_num_decisions.
116 public:
117 LocalSearchOptimizer(const std::string& name, int max_num_decisions,
118 absl::BitGenRef random, sat::SatSolver* sat_propagator);
119 ~LocalSearchOptimizer() override;
120
121 private:
122 bool ShouldBeRun(const ProblemState& problem_state) const override;
123 Status Optimize(const BopParameters& parameters,
124 const ProblemState& problem_state, LearnedInfo* learned_info,
125 TimeLimit* time_limit) override;
126
127 int64_t state_update_stamp_;
128
129 // Maximum number of decisions the Local Search can take.
130 // Note that there is no limit on the number of changed variables due to
131 // propagation.
132 const int max_num_decisions_;
133
134 // A wrapper around the given sat_propagator.
135 SatWrapper sat_wrapper_;
136
137 // Iterator on all reachable assignments.
138 // Note that this iterator is only reset when Synchronize() is called, i.e.
139 // the iterator continues its iteration of the next assignments each time
140 // Optimize() is called until everything is explored or a solution is found.
141 std::unique_ptr<LocalSearchAssignmentIterator> assignment_iterator_;
142
143 // Random generator.
144 absl::BitGenRef random_;
145};
146
147//------------------------------------------------------------------------------
148// Implementation details. The declarations of those utility classes are in
149// the .h for testing reasons.
150//------------------------------------------------------------------------------
151
152// Maintains some information on a sparse set of integers in [0, n). More
153// specifically this class:
154// - Allows to dynamically add/remove element from the set.
155// - Has a backtracking support.
156// - Maintains the number of elements in the set.
157// - Maintains a superset of the elements of the set that contains all the
158// modified elements.
159template <typename IntType>
161 public:
163
164 // Prepares the class for integers in [0, n) and initializes the set to the
165 // empty one. Note that this run in O(n). Once resized, it is better to call
166 // BacktrackAll() instead of this to clear the set.
167 void ClearAndResize(IntType n);
168
169 // Changes the state of the given integer i to be either inside or outside the
170 // set. Important: this should only be called with the opposite state of the
171 // current one, otherwise size() will not be correct.
172 void ChangeState(IntType i, bool should_be_inside);
173
174 // Returns the current number of elements in the set.
175 // Note that this is not its maximum size n.
176 int size() const { return size_; }
177
178 // Returns a superset of the current set of integers.
179 const std::vector<IntType>& Superset() const { return stack_; }
180
181 // BacktrackOneLevel() backtracks to the state the class was in when the
182 // last AddBacktrackingLevel() was called. BacktrackAll() just restore the
183 // class to its state just after the last ClearAndResize().
185 void BacktrackOneLevel();
186 void BacktrackAll();
187
188 private:
189 int size_;
190
191 // Contains the elements whose status has been changed at least once.
192 std::vector<IntType> stack_;
193 std::vector<bool> in_stack_;
194
195 // Used for backtracking. Contains the size_ and the stack_.size() at the time
196 // of each call to AddBacktrackingLevel() that is not yet backtracked over.
197 std::vector<int> saved_sizes_;
198 std::vector<int> saved_stack_sizes_;
199};
200
201// A simple and efficient class to hash a given set of integers in [0, n).
202// It uses O(n) memory and produces a good hash (random linear function).
203template <typename IntType>
205 public:
206 explicit NonOrderedSetHasher(absl::BitGenRef random) : random_(random) {}
207
208 // Initializes the NonOrderedSetHasher to hash sets of integer in [0, n).
209 void Initialize(int size) {
210 hashes_.resize(size);
211 for (IntType i(0); i < size; ++i) {
212 hashes_[i] = absl::Uniform<uint64_t>(random_);
213 }
214 }
215
216 // Ignores the given set element in all subsequent hash computation. Note that
217 // this will be reset by the next call to Initialize().
218 void IgnoreElement(IntType e) { hashes_[e] = 0; }
219
220 // Returns the hash of the given set. The hash is independent of the set
221 // order, but there must be no duplicate element in the set. This uses a
222 // simple random linear function which has really good hashing properties.
223 uint64_t Hash(const std::vector<IntType>& set) const {
224 uint64_t hash = 0;
225 for (const IntType i : set) hash ^= hashes_[i];
226 return hash;
227 }
228
229 // The hash of a set is simply the XOR of all its elements. This allows
230 // to compute an hash incrementally or without the need of a vector<>.
231 uint64_t Hash(IntType e) const { return hashes_[e]; }
232
233 // Returns true if Initialize() has been called with a non-zero size.
234 bool IsInitialized() const { return !hashes_.empty(); }
235
236 private:
237 absl::BitGenRef random_;
239};
240
241// This class is used to incrementally maintain an assignment and the
242// feasibility of the constraints of a given LinearBooleanProblem.
243//
244// The current assignment is initialized using a feasible reference solution,
245// i.e. the reference solution satisfies all the constraints of the problem.
246// The current assignment is updated using the Assign() method.
247//
248// Note that the current assignment is not a solution in the sense that it
249// might not be feasible, ie. violates some constraints.
250//
251// The assignment can be accessed at any time using Assignment().
252// The set of infeasible constraints can be accessed at any time using
253// PossiblyInfeasibleConstraints().
254//
255// Note that this class is reversible, i.e. it is possible to backtrack to
256// previously added backtracking levels.
257// levels. Consider for instance variable a, b, c, and d.
258// Method called Assigned after method call
259// 1- Assign({a, b}) a b
260// 2- AddBacktrackingLevel() a b |
261// 3- Assign({c}) a b | c
262// 4- Assign({d}) a b | c d
263// 5- BacktrackOneLevel() a b
264// 6- Assign({c}) a b c
265// 7- BacktrackOneLevel()
267 public:
268 // Note that the constraint indices used in this class are not the same as
269 // the one used in the given LinearBooleanProblem here.
271 const sat::LinearBooleanProblem& problem, absl::BitGenRef random);
272
273 // When we construct the problem, we treat the objective as one constraint.
274 // This is the index of this special "objective" constraint.
275 static const ConstraintIndex kObjectiveConstraint;
276
277 // Sets a new reference solution and reverts all internal structures to their
278 // initial state. Note that the reference solution has to be feasible.
279 void SetReferenceSolution(const BopSolution& reference_solution);
280
281 // Behaves exactly like SetReferenceSolution() where the passed reference
282 // is the current assignment held by this class. Note that the current
283 // assignment must be feasible (i.e. IsFeasible() is true).
285
286 // Assigns all literals. That updates the assignment, the constraint values,
287 // and the infeasible constraints.
288 // Note that the assignment of those literals can be reverted thanks to
289 // AddBacktrackingLevel() and BacktrackOneLevel().
290 // Note that a variable can't be assigned twice, even for the same literal.
291 void Assign(const std::vector<sat::Literal>& literals);
292
293 // Adds a new backtracking level to specify the state that will be restored
294 // by BacktrackOneLevel().
295 // See the example in the class comment.
297
298 // Backtracks internal structures to the previous level defined by
299 // AddBacktrackingLevel(). As a consequence the state will be exactly as
300 // before the previous call to AddBacktrackingLevel().
301 // Note that backtracking the initial state has no effect.
302 void BacktrackOneLevel();
303 void BacktrackAll();
304
305 // This returns the list of literal that appear in exactly all the current
306 // infeasible constraints (ignoring the objective) and correspond to a flip in
307 // a good direction for all the infeasible constraint. Performing this flip
308 // may repair the problem without any propagations.
309 //
310 // Important: The returned reference is only valid until the next
311 // PotentialOneFlipRepairs() call.
312 const std::vector<sat::Literal>& PotentialOneFlipRepairs();
313
314 // Returns true if there is no infeasible constraint in the current state.
315 bool IsFeasible() const { return infeasible_constraint_set_.size() == 0; }
316
317 // Returns the *exact* number of infeasible constraints.
318 // Note that PossiblyInfeasibleConstraints() will potentially return a larger
319 // number of constraints.
321 return infeasible_constraint_set_.size();
322 }
323
324 // Returns a superset of all the infeasible constraints in the current state.
325 const std::vector<ConstraintIndex>& PossiblyInfeasibleConstraints() const {
326 return infeasible_constraint_set_.Superset();
327 }
328
329 // Returns the number of constraints of the problem, objective included,
330 // i.e. the number of constraint in the problem + 1.
331 size_t NumConstraints() const { return constraint_lower_bounds_.size(); }
332
333 // Returns the value of the var in the assignment.
334 // As the assignment is initialized with the reference solution, if the
335 // variable has not been assigned through Assign(), the returned value is
336 // the value of the variable in the reference solution.
337 bool Assignment(VariableIndex var) const { return assignment_.Value(var); }
338
339 // Returns the current assignment.
340 const BopSolution& reference() const { return reference_; }
341
342 // Returns the lower bound of the constraint.
343 int64_t ConstraintLowerBound(ConstraintIndex constraint) const {
344 return constraint_lower_bounds_[constraint];
345 }
346
347 // Returns the upper bound of the constraint.
348 int64_t ConstraintUpperBound(ConstraintIndex constraint) const {
349 return constraint_upper_bounds_[constraint];
350 }
351
352 // Returns the value of the constraint. The value is computed using the
353 // variable values in the assignment. Note that a constraint is feasible iff
354 // its value is between its two bounds (inclusive).
355 int64_t ConstraintValue(ConstraintIndex constraint) const {
356 return constraint_values_[constraint];
357 }
358
359 // Returns true if the given constraint is currently feasible.
360 bool ConstraintIsFeasible(ConstraintIndex constraint) const {
361 const int64_t value = ConstraintValue(constraint);
362 return value >= ConstraintLowerBound(constraint) &&
363 value <= ConstraintUpperBound(constraint);
364 }
365
366 std::string DebugString() const;
367
368 private:
369 // This is lazily called by PotentialOneFlipRepairs() once.
370 void InitializeConstraintSetHasher();
371
372 // This is used by PotentialOneFlipRepairs(). It encodes a ConstraintIndex
373 // together with a "repair" direction depending on the bound that make a
374 // constraint infeasible. An "up" direction means that the constraint activity
375 // is lower than the lower bound and we need to make the activity move up to
376 // fix the infeasibility.
377 DEFINE_INT_TYPE(ConstraintIndexWithDirection, int32_t);
378 ConstraintIndexWithDirection FromConstraintIndex(ConstraintIndex index,
379 bool up) const {
380 return ConstraintIndexWithDirection(2 * index.value() + (up ? 1 : 0));
381 }
382
383 // Over constrains the objective cost by the given delta. This should only be
384 // called on a feasible reference solution and a fully backtracked state.
385 void MakeObjectiveConstraintInfeasible(int delta);
386
387 // Local structure to represent the sparse matrix by variable used for fast
388 // update of the contraint values.
389 struct ConstraintEntry {
390 ConstraintEntry(ConstraintIndex c, int64_t w) : constraint(c), weight(w) {}
391 ConstraintIndex constraint;
392 int64_t weight;
393 };
394
395 absl::StrongVector<VariableIndex,
397 by_variable_matrix_;
398 absl::StrongVector<ConstraintIndex, int64_t> constraint_lower_bounds_;
399 absl::StrongVector<ConstraintIndex, int64_t> constraint_upper_bounds_;
400
401 BopSolution assignment_;
402 BopSolution reference_;
403
405 BacktrackableIntegerSet<ConstraintIndex> infeasible_constraint_set_;
406
407 // This contains the list of variable flipped in assignment_.
408 // flipped_var_trail_backtrack_levels_[i-1] is the index in flipped_var_trail_
409 // of the first variable flipped after the i-th AddBacktrackingLevel() call.
410 std::vector<int> flipped_var_trail_backtrack_levels_;
411 std::vector<VariableIndex> flipped_var_trail_;
412
413 // Members used by PotentialOneFlipRepairs().
414 std::vector<sat::Literal> tmp_potential_repairs_;
415 NonOrderedSetHasher<ConstraintIndexWithDirection> constraint_set_hasher_;
416 absl::flat_hash_map<uint64_t, std::vector<sat::Literal>>
417 hash_to_potential_repairs_;
418
419 DISALLOW_COPY_AND_ASSIGN(AssignmentAndConstraintFeasibilityMaintainer);
420};
421
422// This class is an utility class used to select which infeasible constraint to
423// repair and identify one variable to flip to actually repair the constraint.
424// A constraint 'lb <= sum_i(w_i * x_i) <= ub', with 'lb' the lower bound,
425// 'ub' the upper bound, 'w_i' the weight of the i-th term and 'x_i' the
426// boolean variable appearing in the i-th term, is infeasible for a given
427// assignment iff its value 'sum_i(w_i * x_i)' is outside of the bounds.
428// Repairing-a-constraint-in-one-flip means making the constraint feasible by
429// just flipping the value of one unassigned variable of the current assignment
430// from the AssignmentAndConstraintFeasibilityMaintainer.
431// For performance reasons, the pairs weight / variable (w_i, x_i) are stored
432// in a sparse manner as a vector of terms (w_i, x_i). In the following the
433// TermIndex term_index refers to the position of the term in the vector.
435 public:
436 // Note that the constraint indices used in this class follow the same
437 // convention as the one used in the
438 // AssignmentAndConstraintFeasibilityMaintainer.
439 //
440 // TODO(user): maybe merge the two classes? maintaining this implicit indices
441 // convention between the two classes sounds like a bad idea.
443 const sat::LinearBooleanProblem& problem,
445 const sat::VariablesAssignment& sat_assignment);
446
447 static const ConstraintIndex kInvalidConstraint;
448 static const TermIndex kInitTerm;
449 static const TermIndex kInvalidTerm;
450
451 // Returns the index of a constraint to repair. This will always return the
452 // index of a constraint that can be repaired in one flip if there is one.
453 // Note however that if there is only one possible candidate, it will be
454 // returned without checking that it can indeed be repaired in one flip.
455 // This is because the later check can be expensive, and is not needed in our
456 // context.
457 ConstraintIndex ConstraintToRepair() const;
458
459 // Returns the index of the next term which repairs the constraint when the
460 // value of its variable is flipped. This method explores terms with an
461 // index strictly greater than start_term_index and then terms with an index
462 // smaller than or equal to init_term_index if any.
463 // Returns kInvalidTerm when no reparing terms are found.
464 //
465 // Note that if init_term_index == start_term_index, then all the terms will
466 // be explored. Both TermIndex arguments can take values in [-1, constraint
467 // size).
468 TermIndex NextRepairingTerm(ConstraintIndex ct_index,
469 TermIndex init_term_index,
470 TermIndex start_term_index) const;
471
472 // Returns true if the constraint is infeasible and if flipping the variable
473 // at the given index will repair it.
474 bool RepairIsValid(ConstraintIndex ct_index, TermIndex term_index) const;
475
476 // Returns the literal formed by the variable at the given constraint term and
477 // assigned to the opposite value of this variable in the current assignment.
478 sat::Literal GetFlip(ConstraintIndex ct_index, TermIndex term_index) const;
479
480 // Local structure to represent the sparse matrix by constraint used for fast
481 // lookups.
483 ConstraintTerm(VariableIndex v, int64_t w) : var(v), weight(w) {}
484 VariableIndex var;
485 int64_t weight;
486 };
487
488 private:
489 // Sorts the terms of each constraints in the by_constraint_matrix_ to iterate
490 // on most promising variables first.
491 void SortTermsOfEachConstraints(int num_variables);
492
493 absl::StrongVector<ConstraintIndex,
495 by_constraint_matrix_;
497 const sat::VariablesAssignment& sat_assignment_;
498
499 DISALLOW_COPY_AND_ASSIGN(OneFlipConstraintRepairer);
500};
501
502// This class is used to iterate on all assignments that can be obtained by
503// deliberately flipping 'n' variables from the reference solution, 'n' being
504// smaller than or equal to max_num_decisions.
505// Note that one deliberate variable flip may lead to many other flips due to
506// constraint propagation, those additional flips are not counted in 'n'.
508 public:
509 LocalSearchAssignmentIterator(const ProblemState& problem_state,
510 int max_num_decisions,
511 int max_num_broken_constraints,
512 absl::BitGenRef random,
513 SatWrapper* sat_wrapper);
515
516 // Parameters of the LS algorithm.
517 void UseTranspositionTable(bool v) { use_transposition_table_ = v; }
519 use_potential_one_flip_repairs_ = v;
520 }
521
522 // Synchronizes the iterator with the problem state, e.g. set fixed variables,
523 // set the reference solution. Call this only when a new solution has been
524 // found. This will restart the LS.
525 void Synchronize(const ProblemState& problem_state);
526
527 // Synchronize the SatWrapper with our current search state. This needs to be
528 // called before calls to NextAssignment() if the underlying SatWrapper was
529 // used by someone else than this class.
531
532 // Move to the next assignment. Returns false when the search is finished.
533 bool NextAssignment();
534
535 // Returns the last feasible assignment.
537 return maintainer_.reference();
538 }
539
540 // Returns true if the current assignment has a better solution than the one
541 // passed to the last Synchronize() call.
543 return better_solution_has_been_found_;
544 }
545
546 // Returns a deterministic number that should be correlated with the time
547 // spent in the iterator. The order of magnitude should be close to the time
548 // in seconds.
549 double deterministic_time() const;
550
551 std::string DebugString() const;
552
553 private:
554 // This is called when a better solution has been found to restore the search
555 // to the new "root" node.
556 void UseCurrentStateAsReference();
557
558 // See transposition_table_ below.
559 static constexpr size_t kStoredMaxDecisions = 4;
560
561 // Internal structure used to represent a node of the search tree during local
562 // search.
563 struct SearchNode {
564 SearchNode()
565 : constraint(OneFlipConstraintRepairer::kInvalidConstraint),
566 term_index(OneFlipConstraintRepairer::kInvalidTerm) {}
567 SearchNode(ConstraintIndex c, TermIndex t) : constraint(c), term_index(t) {}
568 ConstraintIndex constraint;
569 TermIndex term_index;
570 };
571
572 // Applies the decision. Automatically backtracks when SAT detects conflicts.
573 void ApplyDecision(sat::Literal literal);
574
575 // Adds one more decision to repair infeasible constraints.
576 // Returns true in case of success.
577 bool GoDeeper();
578
579 // Backtracks and moves to the next decision in the search tree.
580 void Backtrack();
581
582 // Looks if the current decisions (in search_nodes_) plus the new one (given
583 // by l) lead to a position already present in transposition_table_.
584 bool NewStateIsInTranspositionTable(sat::Literal l);
585
586 // Inserts the current set of decisions in transposition_table_.
587 void InsertInTranspositionTable();
588
589 // Initializes the given array with the current decisions in search_nodes_ and
590 // by filling the other positions with 0.
591 void InitializeTranspositionTableKey(
592 std::array<int32_t, kStoredMaxDecisions>* a);
593
594 // Looks for the next repairing term in the given constraints while skipping
595 // the position already present in transposition_table_. A given TermIndex of
596 // -1 means that this is the first time we explore this constraint.
597 bool EnqueueNextRepairingTermIfAny(ConstraintIndex ct_to_repair,
598 TermIndex index);
599
600 const int max_num_decisions_;
601 const int max_num_broken_constraints_;
602 bool better_solution_has_been_found_;
603 AssignmentAndConstraintFeasibilityMaintainer maintainer_;
604 SatWrapper* const sat_wrapper_;
605 OneFlipConstraintRepairer repairer_;
606 std::vector<SearchNode> search_nodes_;
608
609 // Temporary vector used by ApplyDecision().
610 std::vector<sat::Literal> tmp_propagated_literals_;
611
612 // For each set of explored decisions, we store it in this table so that we
613 // don't explore decisions (a, b) and later (b, a) for instance. The decisions
614 // are converted to int32_t, sorted and padded with 0 before beeing inserted
615 // here.
616 //
617 // TODO(user): We may still miss some equivalent states because it is possible
618 // that completely differents decisions lead to exactly the same state.
619 // However this is more time consuming to detect because we must apply the
620 // last decision first before trying to compare the states.
621 //
622 // TODO(user): Currently, we only store kStoredMaxDecisions or less decisions.
623 // Ideally, this should be related to the maximum number of decision in the
624 // LS, but that requires templating the whole LS optimizer.
625 bool use_transposition_table_;
626 absl::flat_hash_set<std::array<int32_t, kStoredMaxDecisions>>
627 transposition_table_;
628
629 bool use_potential_one_flip_repairs_;
630
631 // The number of explored nodes.
632 int64_t num_nodes_;
633
634 // The number of skipped nodes thanks to the transposition table.
635 int64_t num_skipped_nodes_;
636
637 // The overall number of better solution found. And the ones found by the
638 // use_potential_one_flip_repairs_ heuristic.
639 int64_t num_improvements_;
640 int64_t num_improvements_by_one_flip_repairs_;
641 int64_t num_inspected_one_flip_repairs_;
642
643 DISALLOW_COPY_AND_ASSIGN(LocalSearchAssignmentIterator);
644};
645
646} // namespace bop
647} // namespace operations_research
648#endif // OR_TOOLS_BOP_BOP_LS_H_
void resize(size_type new_size)
size_type size() const
bool empty() const
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:106
int64_t ConstraintLowerBound(ConstraintIndex constraint) const
Definition: bop_ls.h:343
AssignmentAndConstraintFeasibilityMaintainer(const sat::LinearBooleanProblem &problem, absl::BitGenRef random)
Definition: bop_ls.cc:185
void SetReferenceSolution(const BopSolution &reference_solution)
Definition: bop_ls.cc:251
int64_t ConstraintUpperBound(ConstraintIndex constraint) const
Definition: bop_ls.h:348
bool ConstraintIsFeasible(ConstraintIndex constraint) const
Definition: bop_ls.h:360
int64_t ConstraintValue(ConstraintIndex constraint) const
Definition: bop_ls.h:355
const std::vector< ConstraintIndex > & PossiblyInfeasibleConstraints() const
Definition: bop_ls.h:325
void Assign(const std::vector< sat::Literal > &literals)
Definition: bop_ls.cc:304
const std::vector< sat::Literal > & PotentialOneFlipRepairs()
Definition: bop_ls.cc:353
void ChangeState(IntType i, bool should_be_inside)
Definition: bop_ls.cc:135
const std::vector< IntType > & Superset() const
Definition: bop_ls.h:179
const std::string & name() const
Definition: bop_base.h:49
bool Value(VariableIndex var) const
Definition: bop_solution.h:46
const BopSolution & LastReferenceAssignment() const
Definition: bop_ls.h:536
LocalSearchAssignmentIterator(const ProblemState &problem_state, int max_num_decisions, int max_num_broken_constraints, absl::BitGenRef random, SatWrapper *sat_wrapper)
Definition: bop_ls.cc:682
void Synchronize(const ProblemState &problem_state)
Definition: bop_ls.cc:713
LocalSearchOptimizer(const std::string &name, int max_num_decisions, absl::BitGenRef random, sat::SatSolver *sat_propagator)
Definition: bop_ls.cc:36
NonOrderedSetHasher(absl::BitGenRef random)
Definition: bop_ls.h:206
uint64_t Hash(IntType e) const
Definition: bop_ls.h:231
uint64_t Hash(const std::vector< IntType > &set) const
Definition: bop_ls.h:223
sat::Literal GetFlip(ConstraintIndex ct_index, TermIndex term_index) const
Definition: bop_ls.cc:597
bool RepairIsValid(ConstraintIndex ct_index, TermIndex term_index) const
Definition: bop_ls.cc:580
TermIndex NextRepairingTerm(ConstraintIndex ct_index, TermIndex init_term_index, TermIndex start_term_index) const
Definition: bop_ls.cc:550
OneFlipConstraintRepairer(const sat::LinearBooleanProblem &problem, const AssignmentAndConstraintFeasibilityMaintainer &maintainer, const sat::VariablesAssignment &sat_assignment)
Definition: bop_ls.cc:445
static const ConstraintIndex kInvalidConstraint
Definition: bop_ls.h:447
SatWrapper(sat::SatSolver *sat_solver)
Definition: bop_ls.cc:624
std::vector< sat::Literal > FullSatTrail() const
Definition: bop_ls.cc:628
int ApplyDecision(sat::Literal decision_literal, std::vector< sat::Literal > *propagated_literals)
Definition: bop_ls.cc:637
void ExtractLearnedInfo(LearnedInfo *info)
Definition: bop_ls.cc:670
const sat::VariablesAssignment & SatAssignment() const
Definition: bop_ls.h:66
const VariablesAssignment & Assignment() const
Definition: sat_solver.h:363
int64_t a
SatParameters parameters
ModelSharedTimeLimit * time_limit
int64_t value
IntVar * var
Definition: expr_array.cc:1874
int64_t hash
Definition: matrix_utils.cc:61
Collection of objects used to extend the Constraint Solver library.
Literal literal
Definition: optimization.cc:85
int64_t weight
Definition: pack.cc:510
int index
Definition: pack.cc:509
int64_t delta
Definition: resource.cc:1692