Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
set_cover_heuristics.h
Go to the documentation of this file.
1// Copyright 2010-2025 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_SET_COVER_SET_COVER_HEURISTICS_H_
15#define OR_TOOLS_SET_COVER_SET_COVER_HEURISTICS_H_
16
17#include <cstdint>
18#include <limits>
19#include <string>
20#include <vector>
21
22#include "absl/strings/string_view.h"
23#include "absl/time/time.h"
24#include "absl/types/span.h"
29
30namespace operations_research {
31
32// Solver classes for the weighted set covering problem.
33//
34// The solution procedure is based on the general scheme known as local search.
35// Once a solution exists, it is improved by modifying it slightly, for example
36// by flipping a binary variable, so as to minimize the cost.
37// But first, we have to generate a first solution that is as good as possible.
38//
39// The first solution is then improved by using local search descent, which
40// eliminates the S_j's that have no interest in the solution.
41//
42// A mix of the guided local search (GLS) and Tabu Search (TS) metaheuristic
43// is also provided.
44//
45// The term 'focus' hereafter means a subset of the S_j's designated by their
46// indices. Focus make it possible to run the algorithms on the corresponding
47// subproblems.
48
49// Base class for all set cover solution generators. This is almost an
50// interface.
52 public:
53 // By default, the maximum number of iterations is set to infinity, and the
54 // maximum time in seconds is set to infinity as well (and the time limit is
55 // not yet implemented).
59 absl::string_view class_name, absl::string_view name)
60 : run_time_(absl::ZeroDuration()),
61 consistency_level_(consistency_level),
62 inv_(inv),
63 class_name_(class_name),
64 name_(name),
65 time_limit_in_seconds_(std::numeric_limits<double>::infinity()),
66 max_iterations_(std::numeric_limits<int64_t>::max()) {}
67
68 virtual ~SetCoverSolutionGenerator() = default;
69
70 void SetName(const absl::string_view name) { name_ = name; }
71
72 SetCoverInvariant* inv() const { return inv_; }
73
74 // Resets the limits to their default values.
76 time_limit_in_seconds_ = std::numeric_limits<double>::infinity();
77 max_iterations_ = std::numeric_limits<int64_t>::max();
78 return *this;
79 }
80
81 // Sets the maximum number of iterations.
83 max_iterations_ = max_iterations;
84 return *this;
85 }
86
87 // Returns the maximum number of iterations.
88 int64_t max_iterations() const { return max_iterations_; }
89
90 // Sets the time limit in seconds.
92 time_limit_in_seconds_ = seconds;
93 return *this;
94 }
95
96 absl::Duration run_time() const { return run_time_; }
97
98 // Returns the total elapsed runtime in seconds.
99 double run_time_in_seconds() const {
100 return absl::ToDoubleSeconds(run_time_);
101 }
102
103 // Returns the total elapsed runtime in microseconds.
105 return absl::ToInt64Microseconds(run_time_);
106 }
107
108 // Returns the name of the heuristic.
109 std::string name() const { return name_; }
110
111 // Returns the name of the class.
112 std::string class_name() const { return class_name_; }
113
114 // Returns the current cost of the solution in the invariant.
115 Cost cost() const { return inv_->cost(); }
116
117 // Virtual methods that must be implemented by derived classes.
118
119 // Computes the next full solution taking into account all the subsets.
120 virtual bool NextSolution() = 0;
121
122 // Computes the next partial solution considering only the subsets whose
123 // indices are in focus.
124 virtual bool NextSolution(absl::Span<const SubsetIndex> focus) = 0;
125
126 // Same as above, but with a vector of Booleans as focus.
127 virtual bool NextSolution(const SubsetBoolVector& in_focus) = 0;
128
129 bool CheckInvariantConsistency() const;
130
131 protected:
132 // Accessors.
133 SetCoverModel* model() const { return inv_->model(); }
134 BaseInt num_subsets() const { return model()->num_subsets(); }
135
136 // The time limit in seconds.
137 double time_limit_in_seconds() const { return time_limit_in_seconds_; }
138
139 // run_time_ is an abstract duration for the time spent in NextSolution().
140 absl::Duration run_time_;
141
142 // The consistency needed by the solution generator.
144
145 private:
146 // The data structure that will maintain the invariant for the model.
147 SetCoverInvariant* inv_;
148
149 // The name of the solution generator class. Cannot be changed by the user.
150 std::string class_name_;
151
152 // The name of the solution generator object. Set to the name of the class
153 // by default, but can be changed by the user.
154 std::string name_;
155
156 // The time limit in seconds.
157 double time_limit_in_seconds_;
158
159 // The maximum number of iterations.
160 int64_t max_iterations_;
161};
162
163// Now we define two classes that are used to implement the solution
164// generators. The first one uses a vector of subset indices as focus, while
165// the second one uses a vector of Booleans. This makes the declaration of the
166// solution generators shorter, more readable and improves type correctness.
167
168// The class of solution generators that use a vector of subset indices as
169// focus, with a transformation from a vector of Booleans to a vector of
170// subset indices if needed.
172 public:
175 SetCoverInvariant::ConsistencyLevel consistency_level,
176 absl::string_view class_name, absl::string_view name)
177 : SetCoverSolutionGenerator(inv, consistency_level, class_name, name) {}
178
179 bool NextSolution(absl::Span<const SubsetIndex> _) override { return false; }
180
181 bool NextSolution() final { return NextSolution(model()->all_subsets()); }
182
183 bool NextSolution(const SubsetBoolVector& in_focus) final {
184 return NextSolution(MakeSubsetIndexSpan(in_focus));
185 }
186
187 private:
188 // Converts a vector of Booleans to a vector of subset indices.
189 // TODO(user): this should not be, but a better iterator system should be
190 // implemented.
191 absl::Span<const SubsetIndex> MakeSubsetIndexSpan(
192 const SubsetBoolVector& in_focus) {
193 std::vector<SubsetIndex> result;
194 result.reserve(in_focus.size());
195 SubsetIndex i(0);
196 for (const auto bit : in_focus) {
197 if (bit) {
198 result.push_back(i);
199 }
200 }
201 return absl::MakeConstSpan(result);
202 }
203};
204
205// The class of solution generators that use a vector of Booleans as focus,
206// with a transformation from a vector of subset indices to a vector of
207// Booleans if needed.
209 public:
212 SetCoverInvariant::ConsistencyLevel consistency_level,
213 absl::string_view class_name, absl::string_view name)
214 : SetCoverSolutionGenerator(inv, consistency_level, class_name, name) {}
215
216 bool NextSolution(const SubsetBoolVector& _) override { return false; }
217
218 bool NextSolution(absl::Span<const SubsetIndex> focus) final {
219 return NextSolution(MakeBoolVector(focus, num_subsets()));
220 }
221
222 bool NextSolution() final {
224 }
225
226 private:
227 // Converts a vector of subset indices to a vector of Booleans.
228 // TODO(user): this should not be, but a better iterator system should be
229 // implemented.
230 SubsetBoolVector MakeBoolVector(absl::Span<const SubsetIndex> focus,
231 BaseInt size) {
232 SubsetBoolVector result(SubsetIndex(size), false);
233 for (const SubsetIndex subset : focus) {
234 result[subset] = true;
235 }
236 return result;
237 }
238};
239
240// An obvious idea is to take all the S_j's (or equivalently to set all the
241// x_j's to 1). It's very silly but fast, and we can improve on it later
242// using local search.
243
244// The consistency level is maintained up to kFreeAndUncovered.
246 public:
249
252 inv, SetCoverInvariant::ConsistencyLevel::kFreeAndUncovered,
253 "TrivialGenerator", name) {}
254
256 bool NextSolution(absl::Span<const SubsetIndex> focus) final;
257};
258
259// A slightly more complicated but better way to compute a first solution is
260// to select columns randomly. Less silly than the previous one, and
261// provides much better results.
262// TODO(user): make it possible to use other random generators. Idea: bias
263// the generator towards the columns with the least marginal costs.
264
265// The consistency level is maintained up to kFreeAndUncovered.
267 public:
270
273 inv, SetCoverInvariant::ConsistencyLevel::kFreeAndUncovered,
274 "RandomGenerator", name) {}
275
277 bool NextSolution(absl::Span<const SubsetIndex> focus) final;
278};
279
280// The first solution is obtained using the Chvatal heuristic, that
281// guarantees that the solution is at most 1 + log(n) times the optimal
282// value. Vasek Chvatal, 1979. A greedy heuristic for the set-covering
283// problem. Mathematics of Operations Research, 4(3):233-235, 1979.
284// http://www.jstor.org/stable/3689577
285//
286// Chvatal's heuristic works as follows: Choose the subset that covers as
287// many remaining uncovered elements as possible for the least possible cost
288// per element and iterate.
289//
290// The following papers dive into the details of this class of algorithms.
291//
292// Young, Neal E. 2008. “Greedy Set-Cover Algorithms.” In Encyclopedia of
293// Algorithms, 379–81. Boston, MA: Springer US. Draft at:
294// http://www.cs.ucr.edu/~neal/non_arxiv/Young08SetCover.pdf
295//
296// Cormode, Graham, Howard Karloff, and Anthony Wirth. 2010. “Set Cover
297// Algorithms for Very Large Datasets.” In CIKM ’10. ACM Press.
298// https://doi.org/10.1145/1871437.1871501.
299
300// The consistency level is maintained up to kFreeAndUncovered.
302 public:
305
308 inv, SetCoverInvariant::ConsistencyLevel::kFreeAndUncovered,
309 "GreedyGenerator", name) {}
310
312 bool NextSolution(absl::Span<const SubsetIndex> focus) final;
313};
314
315// Solution generator based on the degree of elements.
316// The degree of an element is the number of subsets covering it.
317// The generator consists in iteratively choosing a non-covered element with
318// the smallest degree, and selecting a subset that covers it with the least
319// ratio cost / number of uncovered elements. The number of uncovered elements
320// are updated for each impacted subset. The newly-covered elements degrees
321// are also updated and set to zero.
322
323// The consistency level is maintained up to kFreeAndUncovered.
325 public:
328
331 inv, SetCoverInvariant::ConsistencyLevel::kFreeAndUncovered,
332 "ElementDegreeGenerator", name) {}
333
335 bool NextSolution(const SubsetBoolVector& in_focus) final;
336};
337
338// Solution generator based on the degree of elements.
339// The heuristic is the same as ElementDegreeSolutionGenerator, but the number
340// of uncovered elements for a subset is computed on-demand. In empirical
341// tests, this is faster than ElementDegreeSolutionGenerator because a very
342// small percentage of need to be computed, and even fewer among them need to
343// be computed again later on.
344
345// Because the number of uncovered elements is computed on-demand, the
346// consistency level only needs to be set to kCostAndCoverage.
349 public:
352
354 absl::string_view name)
356 inv, SetCoverInvariant::ConsistencyLevel::kCostAndCoverage,
357 "LazyElementDegreeGenerator", name) {}
358
360 bool NextSolution(const SubsetBoolVector& in_focus) final;
361};
362
363// Once we have a first solution to the problem, there may be (most often,
364// there are) elements in E that are covered several times. To decrease the
365// total cost, SteepestSearch tries to eliminate some redundant S_j's from
366// the solution or equivalently, to flip some x_j's from 1 to 0. the
367// algorithm gets its name because it goes in the steepest immediate
368// direction, taking the S_j with the largest total cost.
369
370// The consistency level is maintained up to kFreeAndUncovered.
372 public:
374 : SteepestSearch(inv, "SteepestSearch") {}
375
378 inv, SetCoverInvariant::ConsistencyLevel::kFreeAndUncovered,
379 "SteepestSearch", name) {}
380
382 bool NextSolution(const SubsetBoolVector& in_focus) final;
383};
384
385// Lazy Steepest Search is a variant of Steepest Search that does not use
386// any priority queue to update the priorities of the subsets. The
387// priorities are computed when needed. It is faster to compute because
388// there are relatively few subsets in the solution, because the cardinality
389// of the solution is bounded by the number of elements.
391 public:
393 : LazySteepestSearch(inv, "LazySteepestSearch") {}
394
397 inv, SetCoverInvariant::ConsistencyLevel::kCostAndCoverage,
398 "LazySteepestSearch", name) {}
399
401 bool NextSolution(const SubsetBoolVector& in_focus) final;
402};
403
404// A Tabu list is a fixed-sized set with FIFO replacement. It is expected to
405// be of small size, usually a few dozens of elements.
406template <typename T>
407class TabuList {
408 public:
409 explicit TabuList(T size) : array_(0), fill_(0), index_(0) {
410 array_.resize(size.value(), T(-1));
411 }
412
413 // Returns the size of the array.
414 int size() const { return array_.size(); }
415
416 // Initializes the array of the Tabu list.
417 void Init(int size) {
418 array_.resize(size, T(-1));
419 fill_ = 0;
420 index_ = 0;
421 }
422
423 // Adds t to the array. When the end of the array is reached, re-start at 0.
424 void Add(T t) {
425 const int size = array_.size();
426 array_[index_] = t;
427 ++index_;
428 if (index_ >= size) {
429 index_ = 0;
430 }
431 if (fill_ < size) {
432 ++fill_;
433 }
434 }
435
436 // Returns true if t is in the array. This is O(size), but small.
437 bool Contains(T t) const {
438 for (int i = 0; i < fill_; ++i) {
439 if (t == array_[i]) {
440 return true;
441 }
442 }
443 return false;
444 }
445
446 private:
447 std::vector<T> array_;
448 int fill_;
449 int index_;
450};
451
452// As usual and well-known with local search, SteepestSearch reaches a local
453// minimum. We therefore implement Guided Tabu Search, which is a crossover
454// of Guided Local Search and Tabu Search.
455//
456// Guided Local Search penalizes the parts of the solution that have been
457// often used. It behaves as a long-term memory which "learns" the most used
458// features and introduces some diversification in the search.
459//
460// C. Voudouris (1997) "Guided local search for combinatorial optimisation
461// problems", PhD Thesis, University of Essex, Colchester, UK, July, 1997.
462//
463// Tabu Search makes it possible to degrade the solution temporarily
464// by disallowing to go back for a certain time (changes are put in a "Tabu"
465// list).
466//
467// Tabu behaves like a short-term memory and is the intensification part of
468// the local search metaheuristic.
469//
470// F. Glover (1989) "Tabu Search – Part 1". ORSA Journal on Computing.
471// 1 (2):190–206. doi:10.1287/ijoc.1.3.190.
472// F. Glover (1990) "Tabu Search – Part 2". ORSA Journal on Computing.
473// 2 (1): 4–32. doi:10.1287/ijoc.2.1.4.
474
475// The consistency level is maintained up to kFreeAndUncovered.
477 public:
479 : GuidedTabuSearch(inv, "GuidedTabuSearch") {}
480
483 inv, SetCoverInvariant::ConsistencyLevel::kFreeAndUncovered,
484 "GuidedTabuSearch", name),
485 lagrangian_factor_(kDefaultLagrangianFactor),
486 penalty_factor_(kDefaultPenaltyFactor),
487 epsilon_(kDefaultEpsilon),
488 augmented_costs_(),
489 times_penalized_(),
490 tabu_list_(SubsetIndex(kDefaultTabuListSize)) {
491 Initialize();
492 }
493
494 // Initializes the Guided Tabu Search algorithm.
495 void Initialize();
496
498 bool NextSolution(absl::Span<const SubsetIndex> focus) final;
499
500 // TODO(user): re-introduce this is the code. It was used to favor
501 // subsets with the same marginal costs but that would cover more
502 // elements. But first, see if it makes sense to compute it.
503 void SetLagrangianFactor(double factor) { lagrangian_factor_ = factor; }
504 double GetLagrangianFactor() const { return lagrangian_factor_; }
505
506 void SetEpsilon(double r) { epsilon_ = r; }
507 double GetEpsilon() const { return epsilon_; }
508
509 // Setters and getters for the Guided Tabu Search algorithm parameters.
510 void SetPenaltyFactor(double factor) { penalty_factor_ = factor; }
511 double GetPenaltyFactor() const { return penalty_factor_; }
512
513 void SetTabuListSize(int size) { tabu_list_.Init(size); }
514 int GetTabuListSize() const { return tabu_list_.size(); }
515
516 private:
517 // Updates the penalties on the subsets in focus.
518 void UpdatePenalties(absl::Span<const SubsetIndex> focus);
519
520 // Search handling variables and default parameters.
521 static constexpr double kDefaultLagrangianFactor = 100.0;
522 double lagrangian_factor_;
523
524 // Guided local search-related data.
525 static constexpr double kPenaltyUpdateEpsilon = 1e-1;
526
527 // Guided Tabu Search parameters.
528 static constexpr double kDefaultPenaltyFactor = 0.3;
529 double penalty_factor_;
530
531 // Tabu Search parameters.
532 static constexpr double kDefaultEpsilon = 1e-6;
533 double epsilon_;
534
535 // Penalized costs for each subset as used in Guided Tabu Search.
536 SubsetCostVector augmented_costs_;
537
538 // The number of times each subset was penalized during Guided Tabu
539 // Search.
540 SubsetToIntVector times_penalized_;
541
542 // TODO(user): remove and use priority_queue.
543 // Utilities for the different subsets. They are updated ("penalized")
544 // costs.
545 SubsetCostVector utilities_;
546
547 // Tabu search-related data.
548 static constexpr int kDefaultTabuListSize = 17; // Nice prime number.
549 TabuList<SubsetIndex> tabu_list_;
550};
551
552// Guided Local Search penalizes the parts of the solution that have been
553// often used. It behaves as a long-term memory which "learns" the most used
554// features and introduces some diversification in the search.
555// At each iteration, the algorithm selects a subset from the focus with
556// maximum utility of penalization and penalizes it.
557
558// It has been observed that good values for the penalisation factor can be
559// found by dividing the value of the objective function of a local minimum
560// with the number of features present in it [1]. In our case, the
561// penalisation factor is the sum of the costs of the subsets selected in
562// the focus divided by the number of subsets in the focus times a tunable
563// factor alpha_. [1] C. Voudouris (1997) "Guided local search for
564// combinatorial optimisation problems", PhD Thesis, University of Essex,
565// Colchester, UK, July, 1997.
566
567// The consistency level is maintained up to kRedundancy.
569 public:
571 : GuidedLocalSearch(inv, "GuidedLocalSearch") {}
572
575 inv, SetCoverInvariant::ConsistencyLevel::kRedundancy,
576 "GuidedLocalSearch", name),
577 epsilon_(kDefaultEpsilon),
578 alpha_(kDefaultAlpha) {
579 Initialize();
580 }
581
582 // Initializes the Guided Local Search algorithm.
583 void Initialize();
584
586 bool NextSolution(absl::Span<const SubsetIndex> focus) final;
587
588 private:
589 // Setters and getters for the Guided Local Search algorithm parameters.
590 void SetEpsilon(double r) { epsilon_ = r; }
591
592 double GetEpsilon() const { return epsilon_; }
593
594 void SetAlpha(double r) { alpha_ = r; }
595
596 double GetAlpha() const { return alpha_; }
597
598 // The epsilon value for the Guided Local Search algorithm.
599 // Used to penalize the subsets within epsilon of the maximum utility.
600 static constexpr double kDefaultEpsilon = 1e-8;
601 double epsilon_;
602
603 // The alpha value for the Guided Local Search algorithm.
604 // Tunable factor used to penalize the subsets.
605 static constexpr double kDefaultAlpha = 0.5;
606 double alpha_;
607
608 // The penalization value for the Guided Local Search algorithm.
609 double penalization_factor_;
610
611 // The penalties of each feature during Guided Local Search.
612 SubsetToIntVector penalties_;
613
614 // Computes the delta of the cost of the solution if subset state changed.
615 Cost ComputeDelta(SubsetIndex subset) const;
616
617 // The priority heap used to select the subset with the maximum priority
618 // to be updated.
619 AdjustableKAryHeap<float, SubsetIndex::ValueType, 2, true> priority_heap_;
620
621 // The utility heap used to select the subset with the maximum utility to
622 // be penalized.
623 AdjustableKAryHeap<float, SubsetIndex::ValueType, 2, true> utility_heap_;
624};
625
626// Randomly clears a proportion num_subsets variables in the solution.
627// Returns a list of subset indices to be potentially reused as a focus.
628// Randomly clears at least num_subsets variables in the
629// solution. There can be more than num_subsets variables cleared because
630// the intersecting subsets are also removed from the solution. Returns a
631// list of subset indices that can be reused as a focus.
632
633// The consistency level is maintained up to kCostAndCoverage.
634std::vector<SubsetIndex> ClearRandomSubsets(BaseInt num_subsets,
635 SetCoverInvariant* inv);
636
637// Same as above, but clears the subset indices in focus.
638std::vector<SubsetIndex> ClearRandomSubsets(absl::Span<const SubsetIndex> focus,
639 BaseInt num_subsets,
640 SetCoverInvariant* inv);
641
642// Clears the variables (subsets) that cover the most covered elements. This
643// is capped by num_subsets. If the cap is reached, the subsets are chosen
644// randomly.
645// Returns the list of the chosen subset indices.
646// This indices can then be used ax a focus.
647
648// The consistency level is maintained up to kCostAndCoverage.
649std::vector<SubsetIndex> ClearMostCoveredElements(BaseInt num_subsets,
650 SetCoverInvariant* inv);
651
652// Same as above, but clears the subset indices in focus.
653std::vector<SubsetIndex> ClearMostCoveredElements(
654 absl::Span<const SubsetIndex> focus, BaseInt num_subsets,
655 SetCoverInvariant* inv);
656} // namespace operations_research
657
658#endif // OR_TOOLS_SET_COVER_SET_COVER_HEURISTICS_H_
bool NextSolution(const SubsetBoolVector &_) override
Same as above, but with a vector of Booleans as focus.
bool NextSolution(absl::Span< const SubsetIndex > focus) final
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
BoolVectorBasedSolutionGenerator(SetCoverInvariant *inv, SetCoverInvariant::ConsistencyLevel consistency_level, absl::string_view class_name, absl::string_view name)
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
ElementDegreeSolutionGenerator(SetCoverInvariant *inv, absl::string_view name)
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
GreedySolutionGenerator(SetCoverInvariant *inv, absl::string_view name)
void Initialize()
Initializes the Guided Local Search algorithm.
GuidedLocalSearch(SetCoverInvariant *inv, absl::string_view name)
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
void Initialize()
Initializes the Guided Tabu Search algorithm.
GuidedTabuSearch(SetCoverInvariant *inv, absl::string_view name)
void SetPenaltyFactor(double factor)
Setters and getters for the Guided Tabu Search algorithm parameters.
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
LazyElementDegreeSolutionGenerator(SetCoverInvariant *inv, absl::string_view name)
LazySteepestSearch(SetCoverInvariant *inv, absl::string_view name)
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
RandomSolutionGenerator(SetCoverInvariant *inv, absl::string_view name)
Main class for describing a weighted set-covering problem.
double run_time_in_seconds() const
Returns the total elapsed runtime in seconds.
virtual SetCoverSolutionGenerator & ResetLimits()
Resets the limits to their default values.
double run_time_in_microseconds() const
Returns the total elapsed runtime in microseconds.
SetCoverInvariant::ConsistencyLevel consistency_level_
The consistency needed by the solution generator.
int64_t max_iterations() const
Returns the maximum number of iterations.
virtual bool NextSolution()=0
Virtual methods that must be implemented by derived classes.
absl::Duration run_time_
run_time_ is an abstract duration for the time spent in NextSolution().
virtual bool NextSolution(absl::Span< const SubsetIndex > focus)=0
std::string name() const
Returns the name of the heuristic.
Cost cost() const
Returns the current cost of the solution in the invariant.
SetCoverSolutionGenerator & SetTimeLimitInSeconds(double seconds)
Sets the time limit in seconds.
virtual bool NextSolution(const SubsetBoolVector &in_focus)=0
Same as above, but with a vector of Booleans as focus.
double time_limit_in_seconds() const
The time limit in seconds.
std::string class_name() const
Returns the name of the class.
SetCoverSolutionGenerator(SetCoverInvariant *inv, SetCoverInvariant::ConsistencyLevel consistency_level, absl::string_view class_name, absl::string_view name)
SetCoverSolutionGenerator & SetMaxIterations(int64_t max_iterations)
Sets the maximum number of iterations.
SteepestSearch(SetCoverInvariant *inv, absl::string_view name)
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
SubsetListBasedSolutionGenerator(SetCoverInvariant *inv, SetCoverInvariant::ConsistencyLevel consistency_level, absl::string_view class_name, absl::string_view name)
bool NextSolution(const SubsetBoolVector &in_focus) final
Same as above, but with a vector of Booleans as focus.
bool NextSolution(absl::Span< const SubsetIndex > _) override
void Init(int size)
Initializes the array of the Tabu list.
bool Contains(T t) const
Returns true if t is in the array. This is O(size), but small.
int size() const
Returns the size of the array.
void Add(T t)
Adds t to the array. When the end of the array is reached, re-start at 0.
bool NextSolution() final
Virtual methods that must be implemented by derived classes.
TrivialSolutionGenerator(SetCoverInvariant *inv, absl::string_view name)
In SWIG mode, we don't want anything besides these top-level includes.
util_intops::StrongVector< SubsetIndex, Cost > SubsetCostVector
Definition base_types.h:58
std::vector< SubsetIndex > ClearRandomSubsets(BaseInt num_subsets, SetCoverInvariant *inv)
The consistency level is maintained up to kCostAndCoverage.
util_intops::StrongVector< SubsetIndex, BaseInt > SubsetToIntVector
Definition base_types.h:65
std::vector< SubsetIndex > ClearMostCoveredElements(BaseInt max_num_subsets, SetCoverInvariant *inv)
The consistency level is maintained up to kCostAndCoverage.
util_intops::StrongVector< SubsetIndex, bool > SubsetBoolVector
Definition base_types.h:71
double Cost
Basic non-strict type for cost. The speed penalty for using double is ~2%.
Definition base_types.h:32
STL namespace.