00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string.h>
00015 #include "base/hash.h"
00016 #include "base/hash.h"
00017 #include <string>
00018
00019 #include "base/integral_types.h"
00020 #include "base/logging.h"
00021 #include "base/stringprintf.h"
00022 #include "base/concise_iterator.h"
00023 #include "base/map-util.h"
00024 #include "base/hash.h"
00025 #include "constraint_solver/constraint_solver.h"
00026 #include "constraint_solver/constraint_solveri.h"
00027 #include "util/bitset.h"
00028
00029 namespace operations_research {
00030
00031
00032
00033 SmallRevBitSet::SmallRevBitSet(int64 size) : bits_(0LL) {
00034 DCHECK_GT(size, 0);
00035 DCHECK_LE(size, 64);
00036 }
00037
00038 void SmallRevBitSet::SetToOne(Solver* const solver, int64 pos) {
00039 DCHECK_GE(pos, 0);
00040 bits_.SetValue(solver, bits_.Value() | OneBit64(pos));
00041 }
00042
00043 void SmallRevBitSet::SetToZero(Solver* const solver, int64 pos) {
00044 DCHECK_GE(pos, 0);
00045 bits_.SetValue(solver, bits_.Value() & ~OneBit64(pos));
00046 }
00047
00048 int64 SmallRevBitSet::Cardinality() const {
00049 return BitCount64(bits_.Value());
00050 }
00051
00052 int64 SmallRevBitSet::GetFirstOne() const {
00053 if (bits_.Value() == 0) {
00054 return -1;
00055 }
00056 return LeastSignificantBitPosition64(bits_.Value());
00057 }
00058
00059
00060
00061 RevBitSet::RevBitSet(int64 size)
00062 : size_(size),
00063 length_(BitLength64(size)),
00064 bits_(new uint64[length_]),
00065 stamps_(new uint64[length_]) {
00066 DCHECK_GE(size, 1);
00067 memset(bits_, 0, sizeof(*bits_) * length_);
00068 memset(stamps_, 0, sizeof(*stamps_) * length_);
00069 }
00070
00071 RevBitSet::~RevBitSet() {
00072 delete [] bits_;
00073 delete [] stamps_;
00074 }
00075
00076 void RevBitSet::Save(Solver* const solver, int offset) {
00077 const uint64 current_stamp = solver->stamp();
00078 if (current_stamp > stamps_[offset]) {
00079 stamps_[offset] = current_stamp;
00080 solver->SaveValue(&bits_[offset]);
00081 }
00082 }
00083
00084 void RevBitSet::SetToOne(Solver* const solver, int64 index) {
00085 DCHECK_GE(index, 0);
00086 DCHECK_LT(index, size_);
00087 const int64 offset = BitOffset64(index);
00088 const int64 pos = BitPos64(index);
00089 if (!(bits_[offset] & OneBit64(pos))) {
00090 Save(solver, offset);
00091 bits_[offset] |= OneBit64(pos);
00092 }
00093 }
00094
00095 void RevBitSet::SetToZero(Solver* const solver, int64 index) {
00096 DCHECK_GE(index, 0);
00097 DCHECK_LT(index, size_);
00098 const int64 offset = BitOffset64(index);
00099 const int64 pos = BitPos64(index);
00100 if (bits_[offset] & OneBit64(pos)) {
00101 Save(solver, offset);
00102 bits_[offset] &= ~OneBit64(pos);
00103 }
00104 }
00105
00106 bool RevBitSet::IsSet(int64 index) const {
00107 DCHECK_GE(index, 0);
00108 DCHECK_LT(index, size_);
00109 return IsBitSet64(bits_, index);
00110 }
00111
00112 int64 RevBitSet::Cardinality() const {
00113 int64 card = 0;
00114 for (int i = 0; i < length_; ++i) {
00115 card += BitCount64(bits_[i]);
00116 }
00117 return card;
00118 }
00119
00120 bool RevBitSet::IsCardinalityZero() const {
00121 for (int i = 0; i < length_; ++i) {
00122 if (bits_[i]) {
00123 return false;
00124 }
00125 }
00126 return true;
00127 }
00128
00129 bool RevBitSet::IsCardinalityOne() const {
00130 bool found_one = false;
00131 for (int i = 0; i < length_; ++i) {
00132 const uint64 partial = bits_[i];
00133 if (partial) {
00134 if (!(partial & (partial - 1))) {
00135 if (found_one) {
00136 return false;
00137 }
00138 found_one = true;
00139 } else {
00140 return false;
00141 }
00142 }
00143 }
00144 return found_one;
00145 }
00146
00147 int64 RevBitSet::GetFirstBit(int start) const {
00148 return LeastSignificantBitPosition64(bits_, start, size_ - 1);
00149 }
00150
00151 void RevBitSet::ClearAll(Solver* const solver) {
00152 for (int offset = 0; offset < length_; ++offset) {
00153 if (bits_[offset]) {
00154 Save(solver, offset);
00155 bits_[offset] = GG_ULONGLONG(0);
00156 }
00157 }
00158 }
00159
00160
00161
00162 RevBitMatrix::RevBitMatrix(int64 rows, int64 columns)
00163 : RevBitSet(rows * columns), rows_(rows), columns_(columns) {
00164 DCHECK_GE(rows, 1);
00165 DCHECK_GE(columns, 1);
00166 }
00167
00168 RevBitMatrix::~RevBitMatrix() {}
00169
00170 void RevBitMatrix::SetToOne(Solver* const solver, int64 row, int64 column) {
00171 DCHECK_GE(row, 0);
00172 DCHECK_LT(row, rows_);
00173 DCHECK_GE(column, 0);
00174 DCHECK_LT(column, columns_);
00175 RevBitSet::SetToOne(solver, row * columns_ + column);
00176 }
00177
00178 void RevBitMatrix::SetToZero(Solver* const solver, int64 row, int64 column) {
00179 DCHECK_GE(row, 0);
00180 DCHECK_LT(row, rows_);
00181 DCHECK_GE(column, 0);
00182 DCHECK_LT(column, columns_);
00183 RevBitSet::SetToZero(solver, row * columns_ + column);
00184 }
00185
00186 int64 RevBitMatrix::Cardinality(int row) const {
00187 DCHECK_GE(row, 0);
00188 DCHECK_LT(row, rows_);
00189 const int start = row * columns_;
00190 return BitCountRange64(bits_, start, start + columns_ - 1);
00191 }
00192
00193 bool RevBitMatrix::IsCardinalityOne(int row) const {
00194
00195 return Cardinality(row) == 1;
00196 }
00197
00198 bool RevBitMatrix::IsCardinalityZero(int row) const {
00199 const int start = row * columns_;
00200 return IsEmptyRange64(bits_, start, start + columns_ - 1);
00201 }
00202
00203 int64 RevBitMatrix::GetFirstBit(int row, int start) const {
00204 DCHECK_GE(start, 0);
00205 DCHECK_GE(row, 0);
00206 DCHECK_LT(row, rows_);
00207 DCHECK_LT(start, columns_);
00208 const int beginning = row * columns_;
00209 const int end = beginning + columns_ - 1;
00210 int64 position = LeastSignificantBitPosition64(bits_, beginning + start, end);
00211 if (position == -1) {
00212 return -1;
00213 } else {
00214 return position - beginning;
00215 }
00216 }
00217
00218 void RevBitMatrix::ClearAll(Solver* const solver) {
00219 RevBitMatrix::ClearAll(solver);
00220 }
00221
00222
00223
00224 namespace {
00225 class PrintModelVisitor : public ModelVisitor {
00226 public:
00227 PrintModelVisitor() : indent_(0) {}
00228 virtual ~PrintModelVisitor() {}
00229
00230
00231 virtual void BeginVisitModel(const string& solver_name) {
00232 LOG(INFO) << "Model " << solver_name << " {";
00233 Increase();
00234 }
00235
00236 virtual void EndVisitModel(const string& solver_name) {
00237 LOG(INFO) << "}";
00238 Decrease();
00239 CHECK_EQ(0, indent_);
00240 }
00241
00242 virtual void BeginVisitConstraint(const string& type_name,
00243 const Constraint* const constraint) {
00244 LOG(INFO) << Spaces() << type_name;
00245 Increase();
00246 }
00247
00248 virtual void EndVisitConstraint(const string& type_name,
00249 const Constraint* const constraint) {
00250 Decrease();
00251 }
00252
00253 virtual void BeginVisitIntegerExpression(const string& type_name,
00254 const IntExpr* const expr) {
00255 LOG(INFO) << Spaces() << type_name;
00256 Increase();
00257 }
00258
00259 virtual void EndVisitIntegerExpression(const string& type_name,
00260 const IntExpr* const expr) {
00261 Decrease();
00262 }
00263
00264 virtual void BeginVisitExtension(const string& type_name) {
00265 LOG(INFO) << Spaces() << type_name;
00266 Increase();
00267 }
00268
00269 virtual void EndVisitExtension(const string& type_name) {
00270 Decrease();
00271 }
00272
00273 virtual void VisitIntegerVariable(const IntVar* const variable,
00274 const IntExpr* const delegate) {
00275 if (delegate != NULL) {
00276 delegate->Accept(this);
00277 } else {
00278 if (variable->Bound() && variable->name().empty()) {
00279 LOG(INFO) << Spaces() << variable->Min();
00280 } else {
00281 LOG(INFO) << Spaces() << variable->DebugString();
00282 }
00283 }
00284 }
00285
00286 virtual void VisitIntegerVariable(const IntVar* const variable,
00287 const string& operation,
00288 int64 value,
00289 const IntVar* const delegate) {
00290 LOG(INFO) << Spaces() << "IntVar";
00291 Increase();
00292 LOG(INFO) << Spaces() << value;
00293 LOG(INFO) << Spaces() << operation;
00294 delegate->Accept(this);
00295 Decrease();
00296 }
00297
00298 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00299 const string& operation,
00300 const IntervalVar* const delegate) {
00301 if (delegate != NULL) {
00302 LOG(INFO) << Spaces() << operation << " <";
00303 Increase();
00304 delegate->Accept(this);
00305 Decrease();
00306 LOG(INFO) << Spaces() << ">";
00307 } else {
00308 LOG(INFO) << Spaces() << variable->DebugString();
00309 }
00310 }
00311
00312 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00313 const string& operation,
00314 const IntervalVar* const * delegates,
00315 int size) {
00316 LOG(INFO) << Spaces() << operation << " <";
00317 Increase();
00318 for (int i = 0; i < size; ++i) {
00319 delegates[i]->Accept(this);
00320 }
00321 Decrease();
00322 LOG(INFO) << Spaces() << ">";
00323 }
00324
00325 virtual void VisitSequenceVariable(const SequenceVar* const sequence) {
00326 LOG(INFO) << Spaces() << sequence->DebugString();
00327 }
00328
00329
00330 virtual void VisitIntegerArgument(const string& arg_name, int64 value) {
00331 LOG(INFO) << Spaces() << arg_name << ": " << value;
00332 }
00333
00334 virtual void VisitIntegerArrayArgument(const string& arg_name,
00335 const int64* const values,
00336 int size) {
00337 string array = "[";
00338 for (int i = 0; i < size; ++i) {
00339 if (i != 0) {
00340 array.append(", ");
00341 }
00342 StringAppendF(&array, "%lld", values[i]);
00343 }
00344 array.append("]");
00345 LOG(INFO) << Spaces() << arg_name << ": " << array;
00346 }
00347
00348 virtual void VisitIntegerMatrixArgument(const string& arg_name,
00349 const IntTupleSet& values) {
00350 const int rows = values.NumTuples();
00351 const int columns = values.Arity();
00352 string array = "[";
00353 for (int i = 0; i < rows; ++i) {
00354 if (i != 0) {
00355 array.append(", ");
00356 }
00357 array.append("[");
00358 for (int j = 0; j < columns; ++j) {
00359 if (j != 0) {
00360 array.append(", ");
00361 }
00362 StringAppendF(&array, "%lld", values.Value(i, j));
00363 }
00364 array.append("]");
00365 }
00366 array.append("]");
00367 LOG(INFO) << Spaces() << arg_name << ": " << array;
00368 }
00369
00370 virtual void VisitIntegerExpressionArgument(
00371 const string& arg_name,
00372 const IntExpr* const argument) {
00373 set_prefix(StringPrintf("%s: ", arg_name.c_str()));
00374 Increase();
00375 argument->Accept(this);
00376 Decrease();
00377 }
00378
00379 virtual void VisitIntegerVariableArrayArgument(
00380 const string& arg_name,
00381 const IntVar* const * arguments,
00382 int size) {
00383 LOG(INFO) << Spaces() << arg_name << ": [";
00384 Increase();
00385 for (int i = 0; i < size; ++i) {
00386 arguments[i]->Accept(this);
00387 }
00388 Decrease();
00389 LOG(INFO) << Spaces() << "]";
00390 }
00391
00392
00393 virtual void VisitIntervalArgument(const string& arg_name,
00394 const IntervalVar* const argument) {
00395 set_prefix(StringPrintf("%s: ", arg_name.c_str()));
00396 Increase();
00397 argument->Accept(this);
00398 Decrease();
00399 }
00400
00401 virtual void VisitIntervalArgumentArray(const string& arg_name,
00402 const IntervalVar* const * arguments,
00403 int size) {
00404 LOG(INFO) << Spaces() << arg_name << ": [";
00405 Increase();
00406 for (int i = 0; i < size; ++i) {
00407 arguments[i]->Accept(this);
00408 }
00409 Decrease();
00410 LOG(INFO) << Spaces() << "]";
00411 }
00412
00413
00414 virtual void VisitSequenceArgument(const string& arg_name,
00415 const SequenceVar* const argument) {
00416 set_prefix(StringPrintf("%s: ", arg_name.c_str()));
00417 Increase();
00418 argument->Accept(this);
00419 Decrease();
00420 }
00421
00422 virtual void VisitSequenceArgumentArray(const string& arg_name,
00423 const SequenceVar* const * arguments,
00424 int size) {
00425 LOG(INFO) << Spaces() << arg_name << ": [";
00426 Increase();
00427 for (int i = 0; i < size; ++i) {
00428 arguments[i]->Accept(this);
00429 }
00430 Decrease();
00431 LOG(INFO) << Spaces() << "]";
00432 }
00433
00434 private:
00435 void Increase() {
00436 indent_ += 2;
00437 }
00438
00439 void Decrease() {
00440 indent_ -= 2;
00441 }
00442
00443 string Spaces() {
00444 string result;
00445 for (int i = 0; i < indent_ - 2 * (!prefix_.empty()); ++i) {
00446 result.append(" ");
00447 }
00448 if (!prefix_.empty()) {
00449 result.append(prefix_);
00450 prefix_ = "";
00451 }
00452 return result;
00453 }
00454
00455 void set_prefix(const string& prefix) {
00456 prefix_ = prefix;
00457 }
00458
00459 int indent_;
00460 string prefix_;
00461 };
00462 }
00463
00464 ModelVisitor* Solver::MakePrintModelVisitor() {
00465 return RevAlloc(new PrintModelVisitor);
00466 }
00467
00468
00469
00470 namespace {
00471 class ModelStatisticsVisitor : public ModelVisitor {
00472 public:
00473 ModelStatisticsVisitor()
00474 : num_constraints_(0),
00475 num_variables_(0),
00476 num_expressions_(0),
00477 num_casts_(0),
00478 num_intervals_(0),
00479 num_sequences_(0),
00480 num_extensions_(0) {}
00481
00482 virtual ~ModelStatisticsVisitor() {}
00483
00484
00485 virtual void BeginVisitModel(const string& solver_name) {
00486
00487 num_constraints_ = 0;
00488 num_variables_ = 0;
00489 num_expressions_ = 0;
00490 num_casts_ = 0;
00491 num_intervals_ = 0;
00492 num_sequences_ = 0;
00493 num_extensions_ = 0;
00494 already_visited_.clear();
00495 constraint_types_.clear();
00496 expression_types_.clear();
00497 extension_types_.clear();
00498 }
00499
00500 virtual void EndVisitModel(const string& solver_name) {
00501
00502 LOG(INFO) << "Model has:";
00503 LOG(INFO) << " - " << num_constraints_ << " constraints.";
00504 for (ConstIter<hash_map<string, int> > it(constraint_types_);
00505 !it.at_end();
00506 ++it) {
00507 LOG(INFO) << " * " << it->second << " " << it->first;
00508 }
00509 LOG(INFO) << " - " << num_variables_ << " integer variables.";
00510 LOG(INFO) << " - " << num_expressions_ << " integer expressions.";
00511 for (ConstIter<hash_map<string, int> > it(expression_types_);
00512 !it.at_end();
00513 ++it) {
00514 LOG(INFO) << " * " << it->second << " " << it->first;
00515 }
00516 LOG(INFO) << " - " << num_casts_ << " expressions casted into variables.";
00517 LOG(INFO) << " - " << num_intervals_ << " interval variables.";
00518 LOG(INFO) << " - " << num_sequences_ << " sequence variables.";
00519 LOG(INFO) << " - " << num_extensions_ << " model extensions.";
00520 for (ConstIter<hash_map<string, int> > it(extension_types_);
00521 !it.at_end();
00522 ++it) {
00523 LOG(INFO) << " * " << it->second << " " << it->first;
00524 }
00525 }
00526
00527 virtual void BeginVisitConstraint(const string& type_name,
00528 const Constraint* const constraint) {
00529 num_constraints_++;
00530 AddConstraintType(type_name);
00531 }
00532
00533 virtual void BeginVisitIntegerExpression(const string& type_name,
00534 const IntExpr* const expr) {
00535 AddExpressionType(type_name);
00536 num_expressions_++;
00537 }
00538
00539 virtual void BeginVisitExtension(const string& type_name) {
00540 AddExtensionType(type_name);
00541 num_extensions_++;
00542 }
00543
00544 virtual void VisitIntegerVariable(const IntVar* const variable,
00545 const IntExpr* const delegate) {
00546 num_variables_++;
00547 Register(variable);
00548 if (delegate) {
00549 num_casts_++;
00550 VisitSubArgument(delegate);
00551 }
00552 }
00553
00554 virtual void VisitIntegerVariable(const IntVar* const variable,
00555 const string& operation,
00556 int64 value,
00557 const IntVar* const delegate) {
00558 num_variables_++;
00559 Register(variable);
00560 num_casts_++;
00561 VisitSubArgument(delegate);
00562 }
00563
00564 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00565 const string& operation,
00566 const IntervalVar* const delegate) {
00567 num_intervals_++;
00568 if (delegate) {
00569 VisitSubArgument(delegate);
00570 }
00571 }
00572
00573 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00574 const string& operation,
00575 const IntervalVar* const * delegates,
00576 int size) {
00577 num_intervals_++;
00578 for (int i = 0; i < size; ++i) {
00579 VisitSubArgument(delegates[i]);
00580 }
00581 }
00582
00583 virtual void VisitSequenceVariable(const SequenceVar* const sequence) {
00584 num_sequences_++;
00585 for (int i = 0; i < sequence->size(); ++i) {
00586 VisitSubArgument(sequence->Interval(i));
00587 }
00588 }
00589
00590
00591 virtual void VisitIntegerExpressionArgument(
00592 const string& arg_name,
00593 const IntExpr* const argument) {
00594 VisitSubArgument(argument);
00595 }
00596
00597 virtual void VisitIntegerVariableArrayArgument(
00598 const string& arg_name,
00599 const IntVar* const * arguments,
00600 int size) {
00601 for (int i = 0; i < size; ++i) {
00602 VisitSubArgument(arguments[i]);
00603 }
00604 }
00605
00606
00607 virtual void VisitIntervalArgument(const string& arg_name,
00608 const IntervalVar* const argument) {
00609 VisitSubArgument(argument);
00610 }
00611
00612 virtual void VisitIntervalArrayArgument(const string& arg_name,
00613 const IntervalVar* const * arguments,
00614 int size) {
00615 for (int i = 0; i < size; ++i) {
00616 VisitSubArgument(arguments[i]);
00617 }
00618 }
00619
00620
00621 virtual void VisitSequenceArgument(const string& arg_name,
00622 const SequenceVar* const argument) {
00623 VisitSubArgument(argument);
00624 }
00625
00626 virtual void VisitSequenceArrayArgument(const string& arg_name,
00627 const SequenceVar* const * arguments,
00628 int size) {
00629 for (int i = 0; i < size; ++i) {
00630 VisitSubArgument(arguments[i]);
00631 }
00632 }
00633
00634 private:
00635 void Register(const BaseObject* const object) {
00636 already_visited_.insert(object);
00637 }
00638
00639 bool AlreadyVisited(const BaseObject* const object) {
00640 return ContainsKey(already_visited_, object);
00641 }
00642
00643
00644 template<typename T> void VisitSubArgument(T* object) {
00645 if (!AlreadyVisited(object)) {
00646 Register(object);
00647 object->Accept(this);
00648 }
00649 }
00650
00651
00652 void AddConstraintType(const string& constraint_type) {
00653 constraint_types_[constraint_type]++;
00654 }
00655
00656 void AddExpressionType(const string& expression_type) {
00657 expression_types_[expression_type]++;
00658 }
00659
00660 void AddExtensionType(const string& extension_type) {
00661 extension_types_[extension_type]++;
00662 }
00663
00664 hash_map<string, int> constraint_types_;
00665 hash_map<string, int> expression_types_;
00666 hash_map<string, int> extension_types_;
00667 int num_constraints_;
00668 int num_variables_;
00669 int num_expressions_;
00670 int num_casts_;
00671 int num_intervals_;
00672 int num_sequences_;
00673 int num_extensions_;
00674 hash_set<const BaseObject*> already_visited_;
00675 };
00676 }
00677
00678 ModelVisitor* Solver::MakeStatisticsModelVisitor() {
00679 return RevAlloc(new ModelStatisticsVisitor);
00680 }
00681 }