Google OR-Tools: ortools/constraint_solver/utilities.cc Source File
18#include "absl/container/flat_hash_map.h"
19#include "absl/container/flat_hash_set.h"
21#include "absl/strings/str_format.h"
22#include "absl/strings/str_join.h"
23#include "absl/strings/string_view.h"
65 bits_(new uint64_t[length_]),
66 stamps_(new uint64_t[length_]) {
68 memset(bits_.get(), 0, sizeof(bits_[0]) * length_);
72void RevBitSet::Save(Solver* const solver, int offset) {
73 const uint64_t current_stamp = solver->stamp();
74 if (current_stamp > stamps_[offset]) {
75 stamps_[offset] = current_stamp;
76 solver->SaveValue(&bits_[offset]);
83 const int64_t offset = BitOffset64(index);
84 const int64_t pos = BitPos64(index);
85 if (!(bits_[offset] & OneBit64(pos))) {
87 bits_[offset] |= OneBit64(pos);
94 const int64_t offset = BitOffset64(index);
95 const int64_t pos = BitPos64(index);
96 if (bits_[offset] & OneBit64(pos)) {
105 return IsBitSet64(bits_.get(), index);
127 for (int i = 0; i < length_; ++i) {
128 const uint64_t partial = bits_[i];
159 : RevBitSet(rows * columns), rows_(rows), columns_(columns) {
186 const int start = row * columns_;
187 return BitCountRange64(bits_.get(), start, start + columns_ - 1);
196 const int start = row * columns_;
197 return IsEmptyRange64(bits_.get(), start, start + columns_ - 1);
204 DCHECK_LT(start, columns_);
205 const int beginning = row * columns_;
206 const int end = beginning + columns_ - 1;
229 const std::vector<uint64_t>& mask) {
230 CHECK_LE(mask.size(), word_size_);
231 for (int i = 0; i < mask.size(); ++i) {
233 bits_.SetValue(solver, i, mask[i]);
240 const std::vector<uint64_t>& mask) {
243 for (int index : active_words_) {
244 if (index < mask.size() && (bits_[index] & mask[index]) != 0) {
246 const uint64_t result = bits_[index] & ~mask[index];
247 bits_.SetValue(solver, index, result);
258void UnsortedNullableRevBitset::CleanUpActives(Solver* const solver) {
261 for (int i = to_remove_.size() - 1; i >= 0; --i) {
262 active_words_.Remove(solver, to_remove_[i]);
267 const std::vector<uint64_t>& mask) {
270 for (int index : active_words_) {
271 if (index < mask.size()) {
272 if ((bits_[index] & ~mask[index]) != 0) {
274 const uint64_t result = bits_[index] & mask[index];
275 bits_.SetValue(solver, index, result);
277 to_remove_.push_back(index);
283 bits_.SetValue(solver, index, 0);
293 DCHECK_GE(*support_index, 0);
294 DCHECK_LT(*support_index, word_size_);
295 if (mask[*support_index] & bits_[*support_index]) {
298 for (int index : active_words_) {
310class PrintModelVisitor : public ModelVisitor {
312 PrintModelVisitor() : indent_(0) {}
313 ~PrintModelVisitor() override {}
316 void BeginVisitModel(const std::string& solver_name) override {
317 LOG(INFO) << "Model " << solver_name << " {";
321 void EndVisitModel(const std::string& solver_name) override {
327 void BeginVisitConstraint(const std::string& type_name,
328 const Constraint* const constraint) override {
329 LOG(INFO) << Spaces() << type_name;
333 void EndVisitConstraint(const std::string& type_name,
334 const Constraint* const constraint) override {
338 void BeginVisitIntegerExpression(const std::string& type_name,
339 const IntExpr* const expr) override {
340 LOG(INFO) << Spaces() << type_name;
344 void EndVisitIntegerExpression(const std::string& type_name,
345 const IntExpr* const expr) override {
349 void BeginVisitExtension(const std::string& type_name) override {
350 LOG(INFO) << Spaces() << type_name;
354 void EndVisitExtension(const std::string& type_name) override { Decrease(); }
356 void VisitIntegerVariable(const IntVar* const variable,
357 IntExpr* const delegate) override {
358 if (delegate != nullptr) {
361 if (variable->Bound() && variable->name().empty()) {
362 LOG(INFO) << Spaces() << variable->Min();
364 LOG(INFO) << Spaces() << variable->DebugString();
369 void VisitIntegerVariable(const IntVar* const variable,
370 const std::string& operation, int64_t value,
371 IntVar* const delegate) override {
372 LOG(INFO) << Spaces() << "IntVar";
374 LOG(INFO) << Spaces() << value;
375 LOG(INFO) << Spaces() << operation;
380 void VisitIntervalVariable(const IntervalVar* const variable,
381 const std::string& operation, int64_t value,
382 IntervalVar* const delegate) override {
383 if (delegate != nullptr) {
384 LOG(INFO) << Spaces() << operation << " <" << value << ", ";
388 LOG(INFO) << Spaces() << ">";
390 LOG(INFO) << Spaces() << variable->DebugString();
394 void VisitSequenceVariable(const SequenceVar* const sequence) override {
395 LOG(INFO) << Spaces() << sequence->DebugString();
399 void VisitIntegerArgument(const std::string& arg_name,
401 LOG(INFO) << Spaces() << arg_name << ": " << value;
404 void VisitIntegerArrayArgument(const std::string& arg_name,
405 const std::vector<int64_t>& values) override {
406 LOG(INFO) << Spaces() << arg_name << ": [" << absl::StrJoin(values, ", ")
410 void VisitIntegerMatrixArgument(const std::string& arg_name,
411 const IntTupleSet& values) override {
412 const int rows = values.NumTuples();
413 const int columns = values.Arity();
415 for (int i = 0; i < rows; ++i) {
420 for (int j = 0; j < columns; ++j) {
424 absl::StrAppendFormat(&array, "%d", values.Value(i, j));
429 LOG(INFO) << Spaces() << arg_name << ": " << array;
432 void VisitIntegerExpressionArgument(const std::string& arg_name,
433 IntExpr* const argument) override {
434 set_prefix(absl::StrFormat("%s: ", arg_name));
440 void VisitIntegerVariableArrayArgument(
441 const std::string& arg_name,
442 const std::vector<IntVar*>& arguments) override {
443 LOG(INFO) << Spaces() << arg_name << ": [";
445 for (int i = 0; i < arguments.size(); ++i) {
446 arguments[i]->Accept(this);
449 LOG(INFO) << Spaces() << "]";
453 void VisitIntervalArgument(const std::string& arg_name,
454 IntervalVar* const argument) override {
455 set_prefix(absl::StrFormat("%s: ", arg_name));
461 virtual void VisitIntervalArgumentArray(
462 const std::string& arg_name, const std::vector<IntervalVar*>& arguments) {
463 LOG(INFO) << Spaces() << arg_name << ": [";
465 for (int i = 0; i < arguments.size(); ++i) {
466 arguments[i]->Accept(this);
469 LOG(INFO) << Spaces() << "]";
473 void VisitSequenceArgument(const std::string& arg_name,
474 SequenceVar* const argument) override {
475 set_prefix(absl::StrFormat("%s: ", arg_name));
481 virtual void VisitSequenceArgumentArray(
482 const std::string& arg_name, const std::vector<SequenceVar*>& arguments) {
483 LOG(INFO) << Spaces() << arg_name << ": [";
485 for (int i = 0; i < arguments.size(); ++i) {
486 arguments[i]->Accept(this);
489 LOG(INFO) << Spaces() << "]";
492 std::string DebugString() const override { return "PrintModelVisitor"; }
495 void Increase() { indent_ += 2; }
497 void Decrease() { indent_ -= 2; }
501 for (int i = 0; i < indent_ - 2 * (!prefix_.empty()); ++i) {
511 void set_prefix(absl::string_view prefix) { prefix_ = prefix; }
519class ModelStatisticsVisitor : public ModelVisitor {
530 ~ModelStatisticsVisitor() override {}
533 void BeginVisitModel(const std::string& solver_name) override {
543 constraint_types_.clear();
544 expression_types_.clear();
548 void EndVisitModel(const std::string& solver_name) override {
550 LOG(INFO) << "Model has:";
551 LOG(INFO) << " - " << num_constraints_ << " constraints.";
552 for (const auto& it : constraint_types_) {
553 LOG(INFO) << " * " << it.second << " " << it.first;
555 LOG(INFO) << " - " << num_variables_ << " integer variables.";
556 LOG(INFO) << " - " << num_expressions_ << " integer expressions.";
557 for (const auto& it : expression_types_) {
558 LOG(INFO) << " * " << it.second << " " << it.first;
560 LOG(INFO) << " - " << num_casts_ << " expressions casted into variables.";
561 LOG(INFO) << " - " << num_intervals_ << " interval variables.";
562 LOG(INFO) << " - " << num_sequences_ << " sequence variables.";
563 LOG(INFO) << " - " << num_extensions_ << " model extensions.";
564 for (const auto& it : extension_types_) {
565 LOG(INFO) << " * " << it.second << " " << it.first;
569 void BeginVisitConstraint(const std::string& type_name,
570 const Constraint* const constraint) override {
572 AddConstraintType(type_name);
575 void BeginVisitIntegerExpression(const std::string& type_name,
576 const IntExpr* const expr) override {
577 AddExpressionType(type_name);
581 void BeginVisitExtension(const std::string& type_name) override {
582 AddExtensionType(type_name);
586 void VisitIntegerVariable(const IntVar* const variable,
587 IntExpr* const delegate) override {
592 VisitSubArgument(delegate);
596 void VisitIntegerVariable(const IntVar* const variable,
597 const std::string& operation, int64_t value,
598 IntVar* const delegate) override {
602 VisitSubArgument(delegate);
605 void VisitIntervalVariable(const IntervalVar* const variable,
606 const std::string& operation, int64_t value,
607 IntervalVar* const delegate) override {
610 VisitSubArgument(delegate);
614 void VisitSequenceVariable(const SequenceVar* const sequence) override {
616 for (int i = 0; i < sequence->size(); ++i) {
617 VisitSubArgument(sequence->Interval(i));
622 void VisitIntegerExpressionArgument(const std::string& arg_name,
623 IntExpr* const argument) override {
624 VisitSubArgument(argument);
627 void VisitIntegerVariableArrayArgument(
628 const std::string& arg_name,
629 const std::vector<IntVar*>& arguments) override {
630 for (int i = 0; i < arguments.size(); ++i) {
631 VisitSubArgument(arguments[i]);
636 void VisitIntervalArgument(const std::string& arg_name,
637 IntervalVar* const argument) override {
638 VisitSubArgument(argument);
641 void VisitIntervalArrayArgument(
642 const std::string& arg_name,
643 const std::vector<IntervalVar*>& arguments) override {
644 for (int i = 0; i < arguments.size(); ++i) {
645 VisitSubArgument(arguments[i]);
650 void VisitSequenceArgument(const std::string& arg_name,
651 SequenceVar* const argument) override {
652 VisitSubArgument(argument);
655 void VisitSequenceArrayArgument(
656 const std::string& arg_name,
657 const std::vector<SequenceVar*>& arguments) override {
658 for (int i = 0; i < arguments.size(); ++i) {
659 VisitSubArgument(arguments[i]);
663 std::string DebugString() const override { return "ModelStatisticsVisitor"; }
666 void Register(const BaseObject* const object) {
667 already_visited_.insert(object);
670 bool AlreadyVisited(const BaseObject* const object) {
671 return already_visited_.contains(object);
676 void VisitSubArgument(T* object) {
677 if (!AlreadyVisited(object)) {
683 void AddConstraintType(absl::string_view constraint_type) {
684 constraint_types_[constraint_type]++;
687 void AddExpressionType(absl::string_view expression_type) {
688 expression_types_[expression_type]++;
691 void AddExtensionType(absl::string_view extension_type) {
692 extension_types_[extension_type]++;
695 absl::flat_hash_map<std::string, int> constraint_types_;
696 absl::flat_hash_map<std::string, int> expression_types_;
697 absl::flat_hash_map<std::string, int> extension_types_;
705 absl::flat_hash_set<const BaseObject*> already_visited_;
710class VariableDegreeVisitor : public ModelVisitor {
712 explicit VariableDegreeVisitor(
713 absl::flat_hash_map<const IntVar*, int>* const map)
716 ~VariableDegreeVisitor() override {}
719 void VisitIntegerVariable(const IntVar* const variable,
720 IntExpr* const delegate) override {
721 IntVar* const var = const_cast<IntVar*>(variable);
722 if (map_->contains(var)) {
726 VisitSubArgument(delegate);
730 void VisitIntegerVariable(const IntVar* const variable,
731 const std::string& operation, int64_t value,
732 IntVar* const delegate) override {
733 IntVar* const var = const_cast<IntVar*>(variable);
734 if (map_->contains(var)) {
737 VisitSubArgument(delegate);
740 void VisitIntervalVariable(const IntervalVar* const variable,
741 const std::string& operation, int64_t value,
742 IntervalVar* const delegate) override {
744 VisitSubArgument(delegate);
748 void VisitSequenceVariable(const SequenceVar* const sequence) override {
749 for (int i = 0; i < sequence->size(); ++i) {
750 VisitSubArgument(sequence->Interval(i));
755 void VisitIntegerExpressionArgument(const std::string& arg_name,
756 IntExpr* const argument) override {
757 VisitSubArgument(argument);
760 void VisitIntegerVariableArrayArgument(
761 const std::string& arg_name,
762 const std::vector<IntVar*>& arguments) override {
763 for (int i = 0; i < arguments.size(); ++i) {
764 VisitSubArgument(arguments[i]);
769 void VisitIntervalArgument(const std::string& arg_name,
770 IntervalVar* const argument) override {
771 VisitSubArgument(argument);
774 void VisitIntervalArrayArgument(
775 const std::string& arg_name,
776 const std::vector<IntervalVar*>& arguments) override {
777 for (int i = 0; i < arguments.size(); ++i) {
778 VisitSubArgument(arguments[i]);
783 void VisitSequenceArgument(const std::string& arg_name,
784 SequenceVar* const argument) override {
785 VisitSubArgument(argument);
788 void VisitSequenceArrayArgument(
789 const std::string& arg_name,
790 const std::vector<SequenceVar*>& arguments) override {
791 for (int i = 0; i < arguments.size(); ++i) {
792 VisitSubArgument(arguments[i]);
796 std::string DebugString() const override { return "VariableDegreeVisitor"; }
801 void VisitSubArgument(T* object) {
805 absl::flat_hash_map<const IntVar*, int>* const map_;
810 return RevAlloc(new PrintModelVisitor);
814 return RevAlloc(new ModelStatisticsVisitor);
818 absl::flat_hash_map<const IntVar*, int>* const map) {
819 return RevAlloc(new VariableDegreeVisitor(map));
825 std::vector<int64_t> result(input.size());
826 for (int i = 0; i < input.size(); ++i) {
827 result[i] = input[i];
~RevBitMatrix()
Definition utilities.cc:164
int64_t GetFirstBit(int row, int start) const
Definition utilities.cc:200
void SetToZero(Solver *solver, int64_t row, int64_t column)
Erases the 'column' bit in the 'row' row.
Definition utilities.cc:174
void SetToOne(Solver *solver, int64_t row, int64_t column)
Sets the 'column' bit in the 'row' row.
Definition utilities.cc:166
RevBitSet(int64_t size)
Definition utilities.cc:62
friend class RevBitMatrix
int64_t GetFirstBit(int start) const
Definition utilities.cc:143
void Remove(Solver *const solver, const T &value_index)
SmallRevBitSet(int64_t size)
Definition utilities.cc:34
int64_t GetFirstOne() const
Definition utilities.cc:53
ModelVisitor * MakeVariableDegreeVisitor(absl::flat_hash_map< const IntVar *, int > *map)
Compute the number of constraints a variable is attached to.
Definition utilities.cc:817
void SaveValue(T *o)
reversibility
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
Definition utilities.cc:813
bool Intersects(const std::vector< uint64_t > &mask, int *support_index)
Definition utilities.cc:291
bool RevSubtract(Solver *solver, const std::vector< uint64_t > &mask)
Definition utilities.cc:239
void Init(Solver *solver, const std::vector< uint64_t > &mask)
Definition utilities.cc:228
int64_t bit_size() const
Returns the number of bits given in the constructor of the bitset.
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
Definition utilities.cc:222
bool RevAnd(Solver *solver, const std::vector< uint64_t > &mask)
Definition utilities.cc:266
ClosedInterval::Iterator end(ClosedInterval interval)
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
Definition utilities.cc:824
uint32_t BitPos64(uint64_t pos)
uint64_t BitCountRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
uint64_t BitCount64(uint64_t n)
bool IsBitSet64(const uint64_t *const bitset, uint64_t pos)
uint64_t OneBit64(int pos)
uint64_t BitOffset64(uint64_t pos)
bool IsEmptyRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
uint64_t BitLength64(uint64_t size)
int LeastSignificantBitPosition64(uint64_t n)
static int input(yyscan_t yyscanner)