17 #include "absl/container/flat_hash_map.h" 18 #include "absl/container/flat_hash_set.h" 19 #include "absl/strings/str_format.h" 20 #include "absl/strings/str_join.h" 53 if (bits_.
Value() == 0) {
64 bits_(new uint64_t[length_]),
65 stamps_(new uint64_t[length_]) {
67 memset(bits_, 0,
sizeof(*bits_) * length_);
68 memset(stamps_, 0,
sizeof(*stamps_) * length_);
76 void RevBitSet::Save(
Solver*
const solver,
int offset) {
77 const uint64_t current_stamp = solver->
stamp();
78 if (current_stamp > stamps_[offset]) {
79 stamps_[offset] = current_stamp;
89 if (!(bits_[offset] &
OneBit64(pos))) {
100 if (bits_[offset] &
OneBit64(pos)) {
101 Save(solver, offset);
114 for (
int i = 0; i < length_; ++i) {
121 for (
int i = 0; i < length_; ++i) {
130 bool found_one =
false;
131 for (
int i = 0; i < length_; ++i) {
132 const uint64_t partial = bits_[i];
134 if (!(partial & (partial - 1))) {
152 for (
int offset = 0; offset < length_; ++offset) {
154 Save(solver, offset);
155 bits_[offset] = uint64_t{0};
163 :
RevBitSet(rows * columns), rows_(rows), columns_(columns) {
190 const int start =
row * columns_;
200 const int start =
row * columns_;
209 const int beginning =
row * columns_;
210 const int end = beginning + columns_ - 1;
213 if (position == -1) {
216 return position - beginning;
227 : bit_size_(bit_size),
229 bits_(word_size_, 0),
230 active_words_(word_size_) {}
233 const std::vector<uint64_t>& mask) {
235 for (
int i = 0; i < mask.size(); ++i) {
238 active_words_.
Insert(solver, i);
244 const std::vector<uint64_t>& mask) {
245 bool changed =
false;
247 for (
int index : active_words_) {
250 const uint64_t result = bits_[
index] & ~mask[
index];
253 to_remove_.push_back(
index);
258 CleanUpActives(solver);
262 void UnsortedNullableRevBitset::CleanUpActives(
Solver*
const solver) {
265 for (
int i = to_remove_.size() - 1; i >= 0; --i) {
266 active_words_.
Remove(solver, to_remove_[i]);
271 const std::vector<uint64_t>& mask) {
272 bool changed =
false;
274 for (
int index : active_words_) {
275 if (
index < mask.size()) {
278 const uint64_t result = bits_[
index] & mask[
index];
281 to_remove_.push_back(
index);
288 to_remove_.push_back(
index);
291 CleanUpActives(solver);
296 int* support_index) {
299 if (mask[*support_index] & bits_[*support_index]) {
302 for (
int index : active_words_) {
304 *support_index =
index;
316 PrintModelVisitor() : indent_(0) {}
317 ~PrintModelVisitor()
override {}
320 void BeginVisitModel(
const std::string& solver_name)
override {
321 LOG(
INFO) <<
"Model " << solver_name <<
" {";
325 void EndVisitModel(
const std::string& solver_name)
override {
331 void BeginVisitConstraint(
const std::string& type_name,
332 const Constraint*
const constraint)
override {
333 LOG(
INFO) << Spaces() << type_name;
337 void EndVisitConstraint(
const std::string& type_name,
338 const Constraint*
const constraint)
override {
342 void BeginVisitIntegerExpression(
const std::string& type_name,
343 const IntExpr*
const expr)
override {
344 LOG(
INFO) << Spaces() << type_name;
348 void EndVisitIntegerExpression(
const std::string& type_name,
349 const IntExpr*
const expr)
override {
353 void BeginVisitExtension(
const std::string& type_name)
override {
354 LOG(
INFO) << Spaces() << type_name;
358 void EndVisitExtension(
const std::string& type_name)
override { Decrease(); }
360 void VisitIntegerVariable(
const IntVar*
const variable,
361 IntExpr*
const delegate)
override {
362 if (delegate !=
nullptr) {
363 delegate->Accept(
this);
365 if (variable->Bound() && variable->name().empty()) {
366 LOG(
INFO) << Spaces() << variable->Min();
368 LOG(
INFO) << Spaces() << variable->DebugString();
373 void VisitIntegerVariable(
const IntVar*
const variable,
374 const std::string& operation, int64_t
value,
375 IntVar*
const delegate)
override {
376 LOG(
INFO) << Spaces() <<
"IntVar";
379 LOG(
INFO) << Spaces() << operation;
380 delegate->Accept(
this);
384 void VisitIntervalVariable(
const IntervalVar*
const variable,
385 const std::string& operation, int64_t
value,
386 IntervalVar*
const delegate)
override {
387 if (delegate !=
nullptr) {
388 LOG(
INFO) << Spaces() << operation <<
" <" <<
value <<
", ";
390 delegate->Accept(
this);
394 LOG(
INFO) << Spaces() << variable->DebugString();
398 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
399 LOG(
INFO) << Spaces() << sequence->DebugString();
403 void VisitIntegerArgument(
const std::string& arg_name,
404 int64_t
value)
override {
408 void VisitIntegerArrayArgument(
const std::string& arg_name,
409 const std::vector<int64_t>& values)
override {
410 LOG(
INFO) << Spaces() << arg_name <<
": [" << absl::StrJoin(values,
", ")
414 void VisitIntegerMatrixArgument(
const std::string& arg_name,
415 const IntTupleSet& values)
override {
416 const int rows = values.NumTuples();
417 const int columns = values.Arity();
418 std::string array =
"[";
419 for (
int i = 0; i < rows; ++i) {
424 for (
int j = 0; j < columns; ++j) {
428 absl::StrAppendFormat(&array,
"%d", values.Value(i, j));
433 LOG(
INFO) << Spaces() << arg_name <<
": " << array;
436 void VisitIntegerExpressionArgument(
const std::string& arg_name,
437 IntExpr*
const argument)
override {
438 set_prefix(absl::StrFormat(
"%s: ", arg_name));
440 argument->Accept(
this);
444 void VisitIntegerVariableArrayArgument(
445 const std::string& arg_name,
446 const std::vector<IntVar*>& arguments)
override {
447 LOG(
INFO) << Spaces() << arg_name <<
": [";
449 for (
int i = 0; i < arguments.size(); ++i) {
450 arguments[i]->Accept(
this);
457 void VisitIntervalArgument(
const std::string& arg_name,
458 IntervalVar*
const argument)
override {
459 set_prefix(absl::StrFormat(
"%s: ", arg_name));
461 argument->Accept(
this);
465 virtual void VisitIntervalArgumentArray(
466 const std::string& arg_name,
const std::vector<IntervalVar*>& arguments) {
467 LOG(
INFO) << Spaces() << arg_name <<
": [";
469 for (
int i = 0; i < arguments.size(); ++i) {
470 arguments[i]->Accept(
this);
477 void VisitSequenceArgument(
const std::string& arg_name,
478 SequenceVar*
const argument)
override {
479 set_prefix(absl::StrFormat(
"%s: ", arg_name));
481 argument->Accept(
this);
485 virtual void VisitSequenceArgumentArray(
486 const std::string& arg_name,
const std::vector<SequenceVar*>& arguments) {
487 LOG(
INFO) << Spaces() << arg_name <<
": [";
489 for (
int i = 0; i < arguments.size(); ++i) {
490 arguments[i]->Accept(
this);
496 std::string DebugString()
const override {
return "PrintModelVisitor"; }
499 void Increase() { indent_ += 2; }
501 void Decrease() { indent_ -= 2; }
503 std::string Spaces() {
505 for (
int i = 0; i < indent_ - 2 * (!prefix_.empty()); ++i) {
508 if (!prefix_.empty()) {
509 result.append(prefix_);
515 void set_prefix(
const std::string& prefix) { prefix_ = prefix; }
523 class ModelStatisticsVisitor :
public ModelVisitor {
525 ModelStatisticsVisitor()
526 : num_constraints_(0),
532 num_extensions_(0) {}
534 ~ModelStatisticsVisitor()
override {}
537 void BeginVisitModel(
const std::string& solver_name)
override {
539 num_constraints_ = 0;
541 num_expressions_ = 0;
546 already_visited_.clear();
547 constraint_types_.clear();
548 expression_types_.clear();
549 extension_types_.clear();
552 void EndVisitModel(
const std::string& solver_name)
override {
555 LOG(
INFO) <<
" - " << num_constraints_ <<
" constraints.";
556 for (
const auto& it : constraint_types_) {
557 LOG(
INFO) <<
" * " << it.second <<
" " << it.first;
559 LOG(
INFO) <<
" - " << num_variables_ <<
" integer variables.";
560 LOG(
INFO) <<
" - " << num_expressions_ <<
" integer expressions.";
561 for (
const auto& it : expression_types_) {
562 LOG(
INFO) <<
" * " << it.second <<
" " << it.first;
564 LOG(
INFO) <<
" - " << num_casts_ <<
" expressions casted into variables.";
565 LOG(
INFO) <<
" - " << num_intervals_ <<
" interval variables.";
566 LOG(
INFO) <<
" - " << num_sequences_ <<
" sequence variables.";
567 LOG(
INFO) <<
" - " << num_extensions_ <<
" model extensions.";
568 for (
const auto& it : extension_types_) {
569 LOG(
INFO) <<
" * " << it.second <<
" " << it.first;
573 void BeginVisitConstraint(
const std::string& type_name,
574 const Constraint*
const constraint)
override {
576 AddConstraintType(type_name);
579 void BeginVisitIntegerExpression(
const std::string& type_name,
580 const IntExpr*
const expr)
override {
581 AddExpressionType(type_name);
585 void BeginVisitExtension(
const std::string& type_name)
override {
586 AddExtensionType(type_name);
590 void VisitIntegerVariable(
const IntVar*
const variable,
591 IntExpr*
const delegate)
override {
596 VisitSubArgument(delegate);
600 void VisitIntegerVariable(
const IntVar*
const variable,
601 const std::string& operation, int64_t
value,
602 IntVar*
const delegate)
override {
606 VisitSubArgument(delegate);
609 void VisitIntervalVariable(
const IntervalVar*
const variable,
610 const std::string& operation, int64_t
value,
611 IntervalVar*
const delegate)
override {
614 VisitSubArgument(delegate);
618 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
620 for (
int i = 0; i < sequence->size(); ++i) {
621 VisitSubArgument(sequence->Interval(i));
626 void VisitIntegerExpressionArgument(
const std::string& arg_name,
627 IntExpr*
const argument)
override {
628 VisitSubArgument(argument);
631 void VisitIntegerVariableArrayArgument(
632 const std::string& arg_name,
633 const std::vector<IntVar*>& arguments)
override {
634 for (
int i = 0; i < arguments.size(); ++i) {
635 VisitSubArgument(arguments[i]);
640 void VisitIntervalArgument(
const std::string& arg_name,
641 IntervalVar*
const argument)
override {
642 VisitSubArgument(argument);
645 void VisitIntervalArrayArgument(
646 const std::string& arg_name,
647 const std::vector<IntervalVar*>& arguments)
override {
648 for (
int i = 0; i < arguments.size(); ++i) {
649 VisitSubArgument(arguments[i]);
654 void VisitSequenceArgument(
const std::string& arg_name,
655 SequenceVar*
const argument)
override {
656 VisitSubArgument(argument);
659 void VisitSequenceArrayArgument(
660 const std::string& arg_name,
661 const std::vector<SequenceVar*>& arguments)
override {
662 for (
int i = 0; i < arguments.size(); ++i) {
663 VisitSubArgument(arguments[i]);
667 std::string DebugString()
const override {
return "ModelStatisticsVisitor"; }
670 void Register(
const BaseObject*
const object) {
671 already_visited_.insert(
object);
674 bool AlreadyVisited(
const BaseObject*
const object) {
679 template <
typename T>
680 void VisitSubArgument(T*
object) {
681 if (!AlreadyVisited(
object)) {
683 object->Accept(
this);
687 void AddConstraintType(
const std::string& constraint_type) {
688 constraint_types_[constraint_type]++;
691 void AddExpressionType(
const std::string& expression_type) {
692 expression_types_[expression_type]++;
695 void AddExtensionType(
const std::string& extension_type) {
696 extension_types_[extension_type]++;
699 absl::flat_hash_map<std::string, int> constraint_types_;
700 absl::flat_hash_map<std::string, int> expression_types_;
701 absl::flat_hash_map<std::string, int> extension_types_;
702 int num_constraints_;
704 int num_expressions_;
709 absl::flat_hash_set<const BaseObject*> already_visited_;
714 class VariableDegreeVisitor :
public ModelVisitor {
716 explicit VariableDegreeVisitor(
717 absl::flat_hash_map<const IntVar*, int>*
const map)
720 ~VariableDegreeVisitor()
override {}
723 void VisitIntegerVariable(
const IntVar*
const variable,
724 IntExpr*
const delegate)
override {
725 IntVar*
const var = const_cast<IntVar*>(variable);
730 VisitSubArgument(delegate);
734 void VisitIntegerVariable(
const IntVar*
const variable,
735 const std::string& operation, int64_t
value,
736 IntVar*
const delegate)
override {
737 IntVar*
const var = const_cast<IntVar*>(variable);
741 VisitSubArgument(delegate);
744 void VisitIntervalVariable(
const IntervalVar*
const variable,
745 const std::string& operation, int64_t
value,
746 IntervalVar*
const delegate)
override {
748 VisitSubArgument(delegate);
752 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
753 for (
int i = 0; i < sequence->size(); ++i) {
754 VisitSubArgument(sequence->Interval(i));
759 void VisitIntegerExpressionArgument(
const std::string& arg_name,
760 IntExpr*
const argument)
override {
761 VisitSubArgument(argument);
764 void VisitIntegerVariableArrayArgument(
765 const std::string& arg_name,
766 const std::vector<IntVar*>& arguments)
override {
767 for (
int i = 0; i < arguments.size(); ++i) {
768 VisitSubArgument(arguments[i]);
773 void VisitIntervalArgument(
const std::string& arg_name,
774 IntervalVar*
const argument)
override {
775 VisitSubArgument(argument);
778 void VisitIntervalArrayArgument(
779 const std::string& arg_name,
780 const std::vector<IntervalVar*>& arguments)
override {
781 for (
int i = 0; i < arguments.size(); ++i) {
782 VisitSubArgument(arguments[i]);
787 void VisitSequenceArgument(
const std::string& arg_name,
788 SequenceVar*
const argument)
override {
789 VisitSubArgument(argument);
792 void VisitSequenceArrayArgument(
793 const std::string& arg_name,
794 const std::vector<SequenceVar*>& arguments)
override {
795 for (
int i = 0; i < arguments.size(); ++i) {
796 VisitSubArgument(arguments[i]);
800 std::string DebugString()
const override {
return "VariableDegreeVisitor"; }
804 template <
typename T>
805 void VisitSubArgument(T*
object) {
806 object->Accept(
this);
809 absl::flat_hash_map<const IntVar*, int>*
const map_;
814 return RevAlloc(
new PrintModelVisitor);
818 return RevAlloc(
new ModelStatisticsVisitor);
822 absl::flat_hash_map<const IntVar*, int>*
const map) {
823 return RevAlloc(
new VariableDegreeVisitor(map));
829 std::vector<int64_t> result(
input.size());
830 for (
int i = 0; i <
input.size(); ++i) {
831 result[i] =
input[i];
void SetToZero(Solver *const solver, int64_t pos)
Erases the 'pos' bit.
int64_t GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
ModelVisitor * MakeVariableDegreeVisitor(absl::flat_hash_map< const IntVar *, int > *const map)
Compute the number of constraints a variable is attached to.
uint64_t BitLength64(uint64_t size)
bool IsSet(int64_t index) const
Returns whether the 'index' bit is set.
bool RevSubtract(Solver *const solver, const std::vector< uint64_t > &mask)
This method subtracts the mask from the active bitset.
void SetToOne(Solver *const solver, int64_t index)
Sets the 'index' bit.
bool IsCardinalityOne() const
Does it contains only one bit set?
void ClearAll(Solver *const solver)
Cleans all bits.
#define DCHECK_GT(val1, val2)
void ClearAll(Solver *const solver)
Cleans all bits.
void SetToOne(Solver *const solver, int64_t row, int64_t column)
Sets the 'column' bit in the 'row' row.
This class represents a reversible bitset.
void SaveValue(T *o)
reversibility
int64_t Cardinality() const
Returns the number of bits set to one.
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
int64_t GetFirstOne() const
Gets the index of the first bit set starting from 0.
void SetToZero(Solver *const solver, int64_t row, int64_t column)
Erases the 'column' bit in the 'row' row.
void Remove(Solver *const solver, const T &value_index)
bool RevAnd(Solver *const solver, const std::vector< uint64_t > &mask)
This method ANDs the mask with the active bitset.
#define CHECK_LE(val1, val2)
uint64_t BitOffset64(uint64_t pos)
void SetToOne(Solver *const solver, int64_t pos)
Sets the 'pos' bit.
bool ContainsKey(const Collection &collection, const Key &key)
uint64_t stamp() const
The stamp indicates how many moves in the search tree we have performed.
bool IsCardinalityZero() const
Is bitset null?
static int input(yyscan_t yyscanner)
#define DCHECK_GE(val1, val2)
int64_t GetFirstBit(int start) const
Gets the index of the first bit set starting from start.
void SetValue(Solver *const s, int index, const T &val)
#define CHECK_EQ(val1, val2)
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
SmallRevBitSet(int64_t size)
T * RevAlloc(T *object)
Registers the given object as being reversible.
RevBitMatrix(int64_t rows, int64_t columns)
uint64_t BitCountRange64(const uint64_t *const bitset, uint64_t start, uint64_t end)
int LeastSignificantBitPosition64(uint64_t n)
uint64_t BitCount64(uint64_t n)
void Insert(Solver *const solver, const T &elt)
void SetValue(Solver *const s, const T &val)
void Init(Solver *const solver, const std::vector< uint64_t > &mask)
This methods overwrites the active bitset with the mask.
bool Intersects(const std::vector< uint64_t > &mask, int *support_index)
This method returns true iff the mask and the active bitset have a non null intersection.
#define DCHECK_LE(val1, val2)
uint32_t BitPos64(uint64_t pos)
Collection of objects used to extend the Constraint Solver library.
bool IsBitSet64(const uint64_t *const bitset, uint64_t pos)
int64_t Cardinality() const
Returns the number of bits set to one.
bool IsEmptyRange64(const uint64_t *const bitset, uint64_t start, uint64_t end)
ModelVisitor * MakePrintModelVisitor()
Prints the model.
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
uint64_t OneBit64(int pos)
#define DCHECK_LT(val1, val2)
void SetToZero(Solver *const solver, int64_t index)
Erases the 'index' bit.