00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stddef.h>
00017 #include <string.h>
00018 #include <algorithm>
00019 #include <string>
00020 #include <utility>
00021 #include <vector>
00022
00023 #include "base/integral_types.h"
00024 #include "base/logging.h"
00025 #include "base/scoped_ptr.h"
00026 #include "base/stringprintf.h"
00027 #include "base/concise_iterator.h"
00028 #include "constraint_solver/constraint_solver.h"
00029 #include "constraint_solver/constraint_solveri.h"
00030 #include "util/string_array.h"
00031
00032 namespace operations_research {
00033
00034
00035
00036 class Dimension : public BaseObject {
00037 public:
00038 explicit Dimension(Solver* const s, Pack* const pack)
00039 : solver_(s), pack_(pack) {}
00040 virtual ~Dimension() {}
00041
00042 virtual void Post() = 0;
00043 virtual void InitialPropagate(int64 bin_index,
00044 const std::vector<int64>& forced,
00045 const std::vector<int64>& undecided) = 0;
00046 virtual void InitialPropagateUnassigned(const std::vector<int64>& assigned,
00047 const std::vector<int64>& unassigned) = 0;
00048 virtual void EndInitialPropagate() = 0;
00049 virtual void Propagate(int64 bin_index,
00050 const std::vector<int64>& forced,
00051 const std::vector<int64>& removed) = 0;
00052 virtual void PropagateUnassigned(const std::vector<int64>& assigned,
00053 const std::vector<int64>& unassigned) = 0;
00054 virtual void EndPropagate() = 0;
00055 virtual string DebugString() const {
00056 return "Dimension";
00057 }
00058 virtual void Accept(ModelVisitor* const visitor) const = 0;
00059
00060 Solver* solver() const { return solver_; }
00061
00062 bool IsUndecided(int64 var_index, int64 bin_index) const {
00063 return pack_->IsUndecided(var_index, bin_index);
00064 }
00065
00066 bool IsPossible(int64 var_index, int64 bin_index) const {
00067 return pack_->IsPossible(var_index, bin_index);
00068 }
00069
00070 IntVar* AssignVar(int64 var_index, int64 bin_index) const {
00071 return pack_->AssignVar(var_index, bin_index);
00072 }
00073
00074 void SetImpossible(int64 var_index, int64 bin_index) {
00075 pack_->SetImpossible(var_index, bin_index);
00076 }
00077
00078 void Assign(int64 var_index, int64 bin_index) {
00079 pack_->Assign(var_index, bin_index);
00080 }
00081
00082 bool IsAssignedStatusKnown(int64 var_index) const {
00083 return pack_->IsAssignedStatusKnown(var_index);
00084 }
00085
00086 void SetAssigned(int64 var_index) {
00087 pack_->SetAssigned(var_index);
00088 }
00089
00090 void SetUnassigned(int64 var_index) {
00091 pack_->SetUnassigned(var_index);
00092 }
00093
00094 void RemoveAllPossibleFromBin(int64 bin_index) {
00095 pack_->RemoveAllPossibleFromBin(bin_index);
00096 }
00097
00098 void AssignAllPossibleToBin(int64 bin_index) {
00099 pack_->AssignAllPossibleToBin(bin_index);
00100 }
00101
00102 void AssignFirstPossibleToBin(int64 bin_index) {
00103 pack_->AssignFirstPossibleToBin(bin_index);
00104 }
00105
00106 void AssignAllRemainingItems() {
00107 pack_->AssignAllRemainingItems();
00108 }
00109
00110 void UnassignAllRemainingItems() {
00111 pack_->UnassignAllRemainingItems();
00112 }
00113
00114 private:
00115 Solver* const solver_;
00116 Pack* const pack_;
00117 };
00118
00119
00120
00121 Pack::Pack(Solver* const s,
00122 const IntVar* const * vars,
00123 int vsize,
00124 int64 number_of_bins)
00125 : Constraint(s),
00126 vars_(new IntVar*[vsize]),
00127 vsize_(vsize),
00128 bins_(number_of_bins),
00129 unprocessed_(new RevBitMatrix(bins_ + 1, vsize_)),
00130 forced_(bins_ + 1),
00131 removed_(bins_ + 1),
00132 holes_(new IntVarIterator*[vsize_]),
00133 stamp_(GG_ULONGLONG(0)),
00134 demon_(NULL),
00135 in_process_(false) {
00136 memcpy(vars_.get(), vars, vsize_ * sizeof(*vars));
00137 for (int i = 0; i < vsize_; ++i) {
00138 holes_[i] = vars_[i]->MakeHoleIterator(true);
00139 }
00140 }
00141
00142 Pack::~Pack() {}
00143
00144 void Pack::Post() {
00145 for (int i = 0; i < vsize_; ++i) {
00146 IntVar* const var = vars_[i];
00147 if (!var->Bound()) {
00148 Demon* const d = MakeConstraintDemon1(solver(),
00149 this,
00150 &Pack::OneDomain,
00151 "OneDomain",
00152 i);
00153 var->WhenDomain(d);
00154 }
00155 }
00156 for (int i = 0; i < dims_.size(); ++i) {
00157 dims_[i]->Post();
00158 }
00159 demon_ = solver()->RegisterDemon(MakeDelayedConstraintDemon0(
00160 solver(),
00161 this,
00162 &Pack::Propagate,
00163 "Propagate"));
00164 }
00165
00166 void Pack::ClearAll() {
00167 for (int bin_index = 0; bin_index <= bins_; ++bin_index) {
00168 forced_[bin_index].clear();
00169 removed_[bin_index].clear();
00170 }
00171 to_set_.clear();
00172 to_unset_.clear();
00173 in_process_ = false;
00174 stamp_ = solver()->fail_stamp();
00175 }
00176
00177 void Pack::PropagateDelayed() {
00178 for (int i = 0; i < to_set_.size(); ++i) {
00179 vars_[to_set_[i].first]->SetValue(to_set_[i].second);
00180 }
00181 for (int i = 0; i < to_unset_.size(); ++i) {
00182 vars_[to_unset_[i].first]->RemoveValue(to_unset_[i].second);
00183 }
00184 }
00185
00186
00187
00188 namespace {
00189 class InitialPropagateData : public BaseObject {
00190 public:
00191 explicit InitialPropagateData(size_t num_bins)
00192 : BaseObject(), undecided_(num_bins) {}
00193 void PushAssigned(int64 index) { assigned_.push_back(index); }
00194 void PushUnassigned(int64 index) { unassigned_.push_back(index); }
00195 void PushUndecided(int64 bin, int64 index) {
00196 undecided_.at(bin).push_back(index);
00197 }
00198 const std::vector<int64>& undecided(int64 bin) const { return undecided_.at(bin); }
00199 const std::vector<int64>& assigned() const { return assigned_; }
00200 const std::vector<int64>& unassigned() const { return unassigned_; }
00201
00202 private:
00203 std::vector<std::vector<int64> > undecided_;
00204 std::vector<int64> unassigned_;
00205 std::vector<int64> assigned_;
00206 };
00207 }
00208
00209 void Pack::InitialPropagate() {
00210 const bool need_context = solver()->InstrumentsVariables();
00211 ClearAll();
00212 Solver* const s = solver();
00213 in_process_ = true;
00214 InitialPropagateData* data = s->RevAlloc(new InitialPropagateData(bins_));
00215 for (int var_index = 0; var_index < vsize_; ++var_index) {
00216 IntVar* const var = vars_[var_index];
00217 var->SetRange(0, bins_);
00218 if (var->Bound()) {
00219 const int64 value = var->Min();
00220 if (value < bins_) {
00221 forced_[value].push_back(var_index);
00222 data->PushAssigned(var_index);
00223 } else {
00224 data->PushUnassigned(var_index);
00225 }
00226 } else {
00227 DCHECK_GT(bins_, var->Min());
00228 if (var->Max() < bins_) {
00229 data->PushAssigned(var_index);
00230 }
00231 scoped_ptr<IntVarIterator> it(var->MakeDomainIterator(false));
00232 for (it->Init(); it->Ok(); it->Next()) {
00233 const int64 value = it->Value();
00234 if (value >= 0 && value <= bins_) {
00235 unprocessed_->SetToOne(s, value, var_index);
00236 if (value != bins_) {
00237 data->PushUndecided(value, var_index);
00238 }
00239 }
00240 }
00241 }
00242 }
00243 for (int bin_index = 0; bin_index < bins_; ++bin_index) {
00244 if (need_context) {
00245 solver()->GetPropagationMonitor()->PushContext(
00246 StringPrintf(
00247 "Pack(bin %d, forced = [%s], undecided = [%s])",
00248 bin_index,
00249 Int64VectorToString(forced_[bin_index], ", ").c_str(),
00250 Int64VectorToString(data->undecided(bin_index), ", ").c_str()));
00251 }
00252
00253 for (int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
00254 if (need_context) {
00255 solver()->GetPropagationMonitor()->PushContext(
00256 StringPrintf("InitialProgateDimension(%s)",
00257 dims_[dim_index]->DebugString().c_str()));
00258 }
00259 dims_[dim_index]->InitialPropagate(bin_index,
00260 forced_[bin_index],
00261 data->undecided(bin_index));
00262 if (need_context) {
00263 solver()->GetPropagationMonitor()->PopContext();
00264 }
00265 }
00266 if (need_context) {
00267 solver()->GetPropagationMonitor()->PopContext();
00268 }
00269 }
00270 if (need_context) {
00271 solver()->GetPropagationMonitor()->PushContext(
00272 StringPrintf(
00273 "Pack(assigned = [%s], unassigned = [%s])",
00274 Int64VectorToString(data->assigned(), ", ").c_str(),
00275 Int64VectorToString(data->unassigned(), ", ").c_str()));
00276 }
00277 for (int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
00278 if (need_context) {
00279 solver()->GetPropagationMonitor()->PushContext(
00280 StringPrintf("InitialProgateDimension(%s)",
00281 dims_[dim_index]->DebugString().c_str()));
00282 }
00283 dims_[dim_index]->InitialPropagateUnassigned(data->assigned(),
00284 data->unassigned());
00285 dims_[dim_index]->EndInitialPropagate();
00286 if (need_context) {
00287 solver()->GetPropagationMonitor()->PopContext();
00288 }
00289 }
00290 if (need_context) {
00291 solver()->GetPropagationMonitor()->PopContext();
00292 }
00293
00294 PropagateDelayed();
00295 ClearAll();
00296 }
00297
00298 void Pack::Propagate() {
00299 const bool need_context = solver()->InstrumentsVariables();
00300 in_process_ = true;
00301 DCHECK_EQ(stamp_, solver()->fail_stamp());
00302 for (int bin_index = 0; bin_index < bins_; ++bin_index) {
00303 if (!removed_[bin_index].empty() || !forced_[bin_index].empty()) {
00304 if (need_context) {
00305 solver()->GetPropagationMonitor()->PushContext(
00306 StringPrintf(
00307 "Pack(bin %d, forced = [%s], removed = [%s])",
00308 bin_index,
00309 Int64VectorToString(forced_[bin_index], ", ").c_str(),
00310 Int64VectorToString(removed_[bin_index], ", ").c_str()));
00311 }
00312
00313 for (int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
00314 if (need_context) {
00315 solver()->GetPropagationMonitor()->PushContext(
00316 StringPrintf("ProgateDimension(%s)",
00317 dims_[dim_index]->DebugString().c_str()));
00318 }
00319 dims_[dim_index]->Propagate(bin_index,
00320 forced_[bin_index],
00321 removed_[bin_index]);
00322 if (need_context) {
00323 solver()->GetPropagationMonitor()->PopContext();
00324 }
00325 }
00326 if (need_context) {
00327 solver()->GetPropagationMonitor()->PopContext();
00328 }
00329 }
00330 }
00331 if (!removed_[bins_].empty() || !forced_[bins_].empty()) {
00332 if (need_context) {
00333 solver()->GetPropagationMonitor()->PushContext(
00334 StringPrintf(
00335 "Pack(removed = [%s], forced = [%s])",
00336 Int64VectorToString(removed_[bins_], ", ").c_str(),
00337 Int64VectorToString(forced_[bins_], ", ").c_str()));
00338 }
00339
00340 for (int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
00341 if (need_context) {
00342 solver()->GetPropagationMonitor()->PushContext(
00343 StringPrintf("ProgateDimension(%s)",
00344 dims_[dim_index]->DebugString().c_str()));
00345 }
00346 dims_[dim_index]->PropagateUnassigned(removed_[bins_], forced_[bins_]);
00347 if (need_context) {
00348 solver()->GetPropagationMonitor()->PopContext();
00349 }
00350 }
00351 if (need_context) {
00352 solver()->GetPropagationMonitor()->PopContext();
00353 }
00354 }
00355 for (int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
00356 dims_[dim_index]->EndPropagate();
00357 }
00358
00359 PropagateDelayed();
00360 ClearAll();
00361 }
00362
00363 void Pack::OneDomain(int var_index) {
00364
00365
00366 Solver* const s = solver();
00367 const uint64 current_stamp = s->fail_stamp();
00368 if (stamp_ < current_stamp) {
00369 stamp_ = current_stamp;
00370 ClearAll();
00371 }
00372 IntVar* const var = vars_[var_index];
00373 bool bound = var->Bound();
00374 const int64 oldmin = var->OldMin();
00375 const int64 oldmax = var->OldMax();
00376 const int64 vmin = var->Min();
00377 const int64 vmax = var->Max();
00378 for (int64 value = std::max(oldmin, 0LL);
00379 value < std::min(vmin, bins_ + 1);
00380 ++value) {
00381 if (unprocessed_->IsSet(value, var_index)) {
00382 unprocessed_->SetToZero(s, value, var_index);
00383 removed_[value].push_back(var_index);
00384 }
00385 }
00386 if (!bound) {
00387 IntVarIterator* const holes = holes_[var_index];
00388 for (holes->Init(); holes->Ok(); holes->Next()) {
00389 const int64 value = holes->Value();
00390 if (value >= std::max(0LL, vmin) && value <= std::min(bins_, vmax)) {
00391 DCHECK(unprocessed_->IsSet(value, var_index));
00392 unprocessed_->SetToZero(s, value, var_index);
00393 removed_[value].push_back(var_index);
00394 }
00395 }
00396 }
00397 for (int64 value = std::max(vmax + 1, 0LL);
00398 value <= std::min(oldmax, bins_);
00399 ++value) {
00400 if (unprocessed_->IsSet(value, var_index)) {
00401 unprocessed_->SetToZero(s, value, var_index);
00402 removed_[value].push_back(var_index);
00403 }
00404 }
00405 if (bound) {
00406 unprocessed_->SetToZero(s, var->Min(), var_index);
00407 forced_[var->Min()].push_back(var_index);
00408 }
00409 Enqueue(demon_);
00410 }
00411
00412 string Pack::DebugString() const {
00413 string result = "Pack([";
00414 for (int i = 0; i < vsize_; ++i) {
00415 result += vars_[i]->DebugString() + " ";
00416 }
00417 result += "], dimensions = [";
00418 for (int i = 0; i < dims_.size(); ++i) {
00419 result += dims_[i]->DebugString() + " ";
00420 }
00421 StringAppendF(&result, "], bins = %" GG_LL_FORMAT "d)", bins_);
00422 return result;
00423 }
00424
00425 void Pack::Accept(ModelVisitor* const visitor) const {
00426 visitor->BeginVisitConstraint(ModelVisitor::kPack, this);
00427 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
00428 vars_.get(),
00429 vsize_);
00430 visitor->VisitIntegerArgument(ModelVisitor::kSizeArgument, bins_);
00431 for (int i = 0; i < dims_.size(); ++i) {
00432 dims_[i]->Accept(visitor);
00433 }
00434 visitor->EndVisitConstraint(ModelVisitor::kPack, this);
00435 }
00436
00437 bool Pack::IsUndecided(int64 var_index, int64 bin_index) const {
00438 return unprocessed_->IsSet(bin_index, var_index);
00439 }
00440
00441 void Pack::SetImpossible(int64 var_index, int64 bin_index) {
00442 if (IsInProcess()) {
00443 to_unset_.push_back(std::make_pair(var_index, bin_index));
00444 } else {
00445 vars_[var_index]->RemoveValue(bin_index);
00446 }
00447 }
00448
00449 void Pack::Assign(int64 var_index, int64 bin_index) {
00450 if (IsInProcess()) {
00451 to_set_.push_back(std::make_pair(var_index, bin_index));
00452 } else {
00453 vars_[var_index]->SetValue(bin_index);
00454 }
00455 }
00456
00457 bool Pack::IsAssignedStatusKnown(int64 var_index) const {
00458 return !unprocessed_->IsSet(bins_, var_index);
00459 }
00460
00461 bool Pack::IsPossible(int64 var_index, int64 bin_index) const {
00462 return vars_[var_index]->Contains(bin_index);
00463 }
00464
00465 IntVar* Pack::AssignVar(int64 var_index, int64 bin_index) const {
00466 return solver()->MakeIsEqualCstVar(vars_[var_index], bin_index);
00467 }
00468
00469 void Pack::SetAssigned(int64 var_index) {
00470 if (IsInProcess()) {
00471 to_unset_.push_back(std::make_pair(var_index, bins_));
00472 } else {
00473 vars_[var_index]->RemoveValue(bins_);
00474 }
00475 }
00476
00477 void Pack::SetUnassigned(int64 var_index) {
00478 if (IsInProcess()) {
00479 to_set_.push_back(std::make_pair(var_index, bins_));
00480 } else {
00481 vars_[var_index]->SetValue(bins_);
00482 }
00483 }
00484
00485 bool Pack::IsInProcess() const {
00486 return in_process_ && (solver()->fail_stamp() == stamp_);
00487 }
00488
00489 void Pack::RemoveAllPossibleFromBin(int64 bin_index) {
00490 int var_index = unprocessed_->GetFirstBit(bin_index, 0);
00491 while (var_index != -1 && var_index < vsize_) {
00492 SetImpossible(var_index, bin_index);
00493 var_index = var_index == vsize_ - 1 ?
00494 -1 :
00495 unprocessed_->GetFirstBit(bin_index, var_index + 1);
00496 }
00497 }
00498
00499 void Pack::AssignAllPossibleToBin(int64 bin_index) {
00500 int var_index = unprocessed_->GetFirstBit(bin_index, 0);
00501 while (var_index != -1 && var_index < vsize_) {
00502 Assign(var_index, bin_index);
00503 var_index = var_index == vsize_ - 1 ?
00504 -1 :
00505 unprocessed_->GetFirstBit(bin_index, var_index + 1);
00506 }
00507 }
00508
00509 void Pack::AssignFirstPossibleToBin(int64 bin_index) {
00510 int var_index = unprocessed_->GetFirstBit(bin_index, 0);
00511 if (var_index != -1 && var_index < vsize_) {
00512 Assign(var_index, bin_index);
00513 }
00514 }
00515
00516 void Pack::AssignAllRemainingItems() {
00517 int var_index = unprocessed_->GetFirstBit(bins_, 0);
00518 while (var_index != -1 && var_index < vsize_) {
00519 SetAssigned(var_index);
00520 var_index = var_index == vsize_ - 1 ?
00521 -1 :
00522 unprocessed_->GetFirstBit(bins_, var_index + 1);
00523 }
00524 }
00525
00526 void Pack::UnassignAllRemainingItems() {
00527 int var_index = unprocessed_->GetFirstBit(bins_, 0);
00528 while (var_index != -1 && var_index < vsize_) {
00529 SetUnassigned(var_index);
00530 var_index = var_index == vsize_ - 1 ?
00531 -1 :
00532 unprocessed_->GetFirstBit(bins_, var_index + 1);
00533 }
00534 }
00535
00536
00537
00538
00539
00540 namespace {
00541 struct WeightContainer {
00542 int index;
00543 int64 weight;
00544 WeightContainer(int i, int64 w) : index(i), weight(w) {}
00545 bool operator<(const WeightContainer& c) const { return (weight < c.weight); }
00546 };
00547
00548 int SortIndexByWeight(int64* const indices,
00549 const int64* const weights,
00550 int size) {
00551 std::vector<WeightContainer> to_sort;
00552 for (int index = 0; index < size; ++index) {
00553 if (weights[index] != 0) {
00554 to_sort.push_back(WeightContainer(indices[index], weights[index]));
00555 }
00556 }
00557 std::sort(to_sort.begin(), to_sort.end());
00558 for (int index = 0; index < to_sort.size(); ++index) {
00559 indices[index] = to_sort[index].index;
00560 }
00561 for (int index = to_sort.size(); index < size; ++index) {
00562 indices[index] = -1;
00563 }
00564 return to_sort.size();
00565 }
00566
00567 class DimensionLessThanConstant : public Dimension {
00568 public:
00569 DimensionLessThanConstant(Solver* const s,
00570 Pack* const p,
00571 const int64* const weights,
00572 int vars_count,
00573 const int64* const upper_bounds,
00574 int bins_count)
00575 : Dimension(s, p),
00576 vars_count_(vars_count),
00577 weights_(new int64[vars_count_]),
00578 bins_count_(bins_count),
00579 upper_bounds_(new int64[bins_count_]),
00580 first_unbound_backward_vector_(bins_count, 0),
00581 sum_of_bound_variables_vector_(bins_count, 0LL),
00582 ranked_(new int64[vars_count_]),
00583 ranked_size_(vars_count_) {
00584 DCHECK(weights);
00585 DCHECK(upper_bounds);
00586 DCHECK_GT(vars_count, 0);
00587 DCHECK_GT(bins_count, 0);
00588 memcpy(weights_, weights, vars_count * sizeof(*weights));
00589 memcpy(upper_bounds_, upper_bounds, bins_count * sizeof(*upper_bounds));
00590 for (int i = 0; i < vars_count_; ++i) {
00591 ranked_[i] = i;
00592 }
00593 ranked_size_ = SortIndexByWeight(ranked_, weights_, vars_count_);
00594 }
00595
00596 virtual ~DimensionLessThanConstant() {
00597 delete [] weights_;
00598 delete [] upper_bounds_;
00599 delete [] ranked_;
00600 }
00601
00602 virtual void Post() {}
00603
00604 void PushFromTop(int64 bin_index) {
00605 const int64 slack =
00606 upper_bounds_[bin_index] -
00607 sum_of_bound_variables_vector_[bin_index];
00608 if (slack < 0) {
00609 solver()->Fail();
00610 }
00611 int64 last_unbound = first_unbound_backward_vector_[bin_index];
00612 for (; last_unbound >= 0; --last_unbound) {
00613 const int64 var_index = ranked_[last_unbound];
00614 if (IsUndecided(var_index, bin_index)) {
00615 if (weights_[var_index] > slack) {
00616 SetImpossible(var_index, bin_index);
00617 } else {
00618 break;
00619 }
00620 }
00621 }
00622 first_unbound_backward_vector_.SetValue(solver(), bin_index, last_unbound);
00623 }
00624
00625 virtual void InitialPropagate(int64 bin_index,
00626 const std::vector<int64>& forced,
00627 const std::vector<int64>& undecided) {
00628 Solver* const s = solver();
00629 int64 sum = 0LL;
00630 for (ConstIter<std::vector<int64> > it(forced); !it.at_end(); ++it) {
00631 sum += weights_[*it];
00632 }
00633 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
00634 first_unbound_backward_vector_.SetValue(s, bin_index, ranked_size_ - 1);
00635 PushFromTop(bin_index);
00636 }
00637
00638 virtual void EndInitialPropagate() {}
00639
00640 virtual void Propagate(int64 bin_index,
00641 const std::vector<int64>& forced,
00642 const std::vector<int64>& removed) {
00643 if (forced.size() > 0) {
00644 Solver* const s = solver();
00645 int64 sum = sum_of_bound_variables_vector_[bin_index];
00646 for (ConstIter<std::vector<int64> > it(forced); !it.at_end(); ++it) {
00647 sum += weights_[*it];
00648 }
00649 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
00650 PushFromTop(bin_index);
00651 }
00652 }
00653 virtual void InitialPropagateUnassigned(const std::vector<int64>& assigned,
00654 const std::vector<int64>& unassigned) {}
00655 virtual void PropagateUnassigned(const std::vector<int64>& assigned,
00656 const std::vector<int64>& unassigned) {}
00657
00658 virtual void EndPropagate() {}
00659
00660 virtual void Accept(ModelVisitor* const visitor) const {
00661 visitor->BeginVisitExtension(ModelVisitor::kUsageLessConstantExtension);
00662 visitor->VisitIntegerArrayArgument(ModelVisitor::kCoefficientsArgument,
00663 weights_,
00664 vars_count_);
00665 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
00666 upper_bounds_,
00667 bins_count_);
00668 visitor->EndVisitExtension(ModelVisitor::kUsageLessConstantExtension);
00669 }
00670
00671 private:
00672 const int vars_count_;
00673 int64* const weights_;
00674 const int bins_count_;
00675 int64* const upper_bounds_;
00676 RevArray<int> first_unbound_backward_vector_;
00677 RevArray<int64> sum_of_bound_variables_vector_;
00678 int64* const ranked_;
00679 int ranked_size_;
00680 };
00681
00682 class DimensionWeightedSumEqVar : public Dimension {
00683 public:
00684 class VarDemon : public Demon {
00685 public:
00686 VarDemon(DimensionWeightedSumEqVar* const dim, int index)
00687 : dim_(dim), index_(index) {}
00688 virtual ~VarDemon() {}
00689
00690 virtual void Run(Solver* const s) {
00691 dim_->PushFromTop(index_);
00692 }
00693
00694 private:
00695 DimensionWeightedSumEqVar* const dim_;
00696 const int index_;
00697 };
00698
00699 DimensionWeightedSumEqVar(Solver* const s,
00700 Pack* const p,
00701 const int64* const weights,
00702 int vars_count,
00703 IntVar* const* loads,
00704 int bins_count)
00705 : Dimension(s, p),
00706 vars_count_(vars_count),
00707 weights_(new int64[vars_count_]),
00708 bins_count_(bins_count),
00709 loads_(new IntVar*[bins_count_]),
00710 first_unbound_backward_vector_(bins_count, 0),
00711 sum_of_bound_variables_vector_(bins_count, 0LL),
00712 sum_of_all_variables_vector_(bins_count, 0LL),
00713 ranked_(new int64[vars_count_]),
00714 ranked_size_(vars_count_) {
00715 DCHECK(weights);
00716 DCHECK(loads);
00717 DCHECK_GT(vars_count, 0);
00718 DCHECK_GT(bins_count, 0);
00719 memcpy(weights_, weights, vars_count * sizeof(*weights));
00720 memcpy(loads_, loads, bins_count * sizeof(*loads));
00721 for (int i = 0; i < vars_count_; ++i) {
00722 ranked_[i] = i;
00723 }
00724 ranked_size_ = SortIndexByWeight(ranked_, weights_, vars_count_);
00725 }
00726
00727 virtual ~DimensionWeightedSumEqVar() {
00728 delete [] weights_;
00729 delete [] loads_;
00730 delete [] ranked_;
00731 }
00732
00733 virtual string DebugString() const {
00734 return "DimensionWeightedSumEqVar";
00735 }
00736
00737 virtual void Post() {
00738 for (int i = 0; i < bins_count_; ++i) {
00739 Demon* const d = solver()->RevAlloc(new VarDemon(this, i));
00740 loads_[i]->WhenRange(d);
00741 }
00742 }
00743
00744 void PushFromTop(int64 bin_index) {
00745 IntVar* const load = loads_[bin_index];
00746 const int64 sum_min = sum_of_bound_variables_vector_[bin_index];
00747 const int64 sum_max = sum_of_all_variables_vector_[bin_index];
00748 load->SetRange(sum_min, sum_max);
00749 const int64 slack_up = load->Max() - sum_min;
00750 const int64 slack_down = sum_max - load->Min();
00751 DCHECK_GE(slack_down, 0);
00752 DCHECK_GE(slack_up, 0);
00753 int64 last_unbound = first_unbound_backward_vector_[bin_index];
00754 for (; last_unbound >= 0; --last_unbound) {
00755 const int64 var_index = ranked_[last_unbound];
00756 const int64 weight = weights_[var_index];
00757 if (IsUndecided(var_index, bin_index)) {
00758 if (weight > slack_up) {
00759 SetImpossible(var_index, bin_index);
00760 } else if (weight > slack_down) {
00761 Assign(var_index, bin_index);
00762 } else {
00763 break;
00764 }
00765 }
00766 }
00767 first_unbound_backward_vector_.SetValue(solver(), bin_index, last_unbound);
00768 }
00769
00770 virtual void InitialPropagate(int64 bin_index,
00771 const std::vector<int64>& forced,
00772 const std::vector<int64>& undecided) {
00773 Solver* const s = solver();
00774 int64 sum = 0LL;
00775 for (ConstIter<std::vector<int64> > it(forced); !it.at_end(); ++it) {
00776 sum += weights_[*it];
00777 }
00778 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
00779 for (ConstIter<std::vector<int64> > it(undecided); !it.at_end(); ++it) {
00780 sum += weights_[*it];
00781 }
00782 sum_of_all_variables_vector_.SetValue(s, bin_index, sum);
00783 first_unbound_backward_vector_.SetValue(s, bin_index, ranked_size_ - 1);
00784 PushFromTop(bin_index);
00785 }
00786
00787 virtual void EndInitialPropagate() {}
00788
00789 virtual void Propagate(int64 bin_index,
00790 const std::vector<int64>& forced,
00791 const std::vector<int64>& removed) {
00792 Solver* const s = solver();
00793 int64 down = sum_of_bound_variables_vector_[bin_index];
00794 for (ConstIter<std::vector<int64> > it(forced); !it.at_end(); ++it) {
00795 down += weights_[*it];
00796 }
00797 sum_of_bound_variables_vector_.SetValue(s, bin_index, down);
00798 int64 up = sum_of_all_variables_vector_[bin_index];
00799 for (ConstIter<std::vector<int64> > it(removed); !it.at_end(); ++it) {
00800 up -= weights_[*it];
00801 }
00802 sum_of_all_variables_vector_.SetValue(s, bin_index, up);
00803 PushFromTop(bin_index);
00804 }
00805 virtual void InitialPropagateUnassigned(const std::vector<int64>& assigned,
00806 const std::vector<int64>& unassigned) {}
00807 virtual void PropagateUnassigned(const std::vector<int64>& assigned,
00808 const std::vector<int64>& unassigned) {}
00809
00810 virtual void EndPropagate() {}
00811
00812 virtual void Accept(ModelVisitor* const visitor) const {
00813 visitor->BeginVisitExtension(ModelVisitor::kUsageEqualVariableExtension);
00814 visitor->VisitIntegerArrayArgument(ModelVisitor::kCoefficientsArgument,
00815 weights_,
00816 vars_count_);
00817 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
00818 loads_,
00819 bins_count_);
00820 visitor->EndVisitExtension(ModelVisitor::kUsageEqualVariableExtension);
00821 }
00822
00823 private:
00824 const int vars_count_;
00825 int64* const weights_;
00826 const int bins_count_;
00827 IntVar** const loads_;
00828 RevArray<int> first_unbound_backward_vector_;
00829 RevArray<int64> sum_of_bound_variables_vector_;
00830 RevArray<int64> sum_of_all_variables_vector_;
00831 int64* const ranked_;
00832 int ranked_size_;
00833 };
00834
00835 class AssignedWeightedSumDimension : public Dimension {
00836 public:
00837 class VarDemon : public Demon {
00838 public:
00839 explicit VarDemon(AssignedWeightedSumDimension* const dim) : dim_(dim) {}
00840 virtual ~VarDemon() {}
00841
00842 virtual void Run(Solver* const s) {
00843 dim_->PropagateAll();
00844 }
00845
00846 private:
00847 AssignedWeightedSumDimension* const dim_;
00848 };
00849
00850 AssignedWeightedSumDimension(Solver* const s,
00851 Pack* const p,
00852 const int64* const weights,
00853 int vars_count,
00854 int bins_count,
00855 IntVar* const cost_var)
00856 : Dimension(s, p),
00857 vars_count_(vars_count),
00858 weights_(new int64[vars_count_]),
00859 bins_count_(bins_count),
00860 cost_var_(cost_var),
00861 first_unbound_backward_(0),
00862 sum_of_assigned_items_(0LL),
00863 sum_of_unassigned_items_(0LL),
00864 ranked_(new int64[vars_count_]),
00865 ranked_size_(vars_count_),
00866 sum_all_weights_(0LL) {
00867 DCHECK(weights);
00868 DCHECK(cost_var);
00869 DCHECK_GT(vars_count, 0);
00870 DCHECK_GT(bins_count, 0);
00871 memcpy(weights_, weights, vars_count * sizeof(*weights));
00872 for (int i = 0; i < vars_count_; ++i) {
00873 ranked_[i] = i;
00874 }
00875 ranked_size_ = SortIndexByWeight(ranked_, weights_, vars_count_);
00876 first_unbound_backward_.SetValue(s, ranked_size_ - 1);
00877 }
00878
00879 virtual ~AssignedWeightedSumDimension() {
00880 delete [] weights_;
00881 delete [] ranked_;
00882 }
00883
00884 virtual void Post() {
00885 Demon* const uv = solver()->RevAlloc(new VarDemon(this));
00886 cost_var_->WhenRange(uv);
00887 }
00888
00889 void PropagateAll() {
00890 cost_var_->SetRange(sum_of_assigned_items_.Value(),
00891 sum_all_weights_ - sum_of_unassigned_items_.Value());
00892 const int64 slack_up = cost_var_->Max() - sum_of_assigned_items_.Value();
00893 const int64 slack_down = sum_all_weights_ - cost_var_->Min();
00894 int64 last_unbound = first_unbound_backward_.Value();
00895 for (; last_unbound >= 0; --last_unbound) {
00896 const int var_index = ranked_[last_unbound];
00897 if (!IsAssignedStatusKnown(var_index)) {
00898 const int64 coefficient = weights_[var_index];
00899 if (coefficient > slack_up) {
00900 SetUnassigned(var_index);
00901 } else if (coefficient > slack_down) {
00902 SetAssigned(var_index);
00903 } else {
00904 break;
00905 }
00906 }
00907 }
00908 first_unbound_backward_.SetValue(solver(), last_unbound);
00909 }
00910
00911 virtual void InitialPropagate(int64 bin_index,
00912 const std::vector<int64>& forced,
00913 const std::vector<int64>& undecided) {}
00914
00915 virtual void EndInitialPropagate() {}
00916
00917
00918 virtual void InitialPropagateUnassigned(const std::vector<int64>& assigned,
00919 const std::vector<int64>& unassigned) {
00920 for (int index = 0; index < vars_count_; ++index) {
00921 sum_all_weights_ += weights_[index];
00922 }
00923
00924 PropagateUnassigned(assigned, unassigned);
00925 }
00926
00927 virtual void Propagate(int64 bin_index,
00928 const std::vector<int64>& forced,
00929 const std::vector<int64>& removed) {}
00930
00931 virtual void PropagateUnassigned(const std::vector<int64>& assigned,
00932 const std::vector<int64>& unassigned) {
00933 int64 sum_assigned = sum_of_assigned_items_.Value();
00934 for (int index = 0; index < assigned.size(); ++index) {
00935 const int var_index = assigned[index];
00936 sum_assigned += weights_[var_index];
00937 }
00938
00939 int64 sum_unassigned = sum_of_unassigned_items_.Value();
00940 for (int index = 0; index < unassigned.size(); ++index) {
00941 const int var_index = unassigned[index];
00942 sum_unassigned += weights_[var_index];
00943 }
00944
00945 Solver* const s = solver();
00946 sum_of_assigned_items_.SetValue(s, sum_assigned);
00947 sum_of_unassigned_items_.SetValue(s, sum_unassigned);
00948 PropagateAll();
00949 }
00950
00951 virtual void EndPropagate() {}
00952
00953 virtual void Accept(ModelVisitor* const visitor) const {
00954 visitor->BeginVisitExtension(
00955 ModelVisitor::kWeightedSumOfAssignedEqualVariableExtension);
00956 visitor->VisitIntegerArrayArgument(ModelVisitor::kCoefficientsArgument,
00957 weights_,
00958 vars_count_);
00959 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
00960 cost_var_);
00961 visitor->EndVisitExtension(
00962 ModelVisitor::kWeightedSumOfAssignedEqualVariableExtension);
00963 }
00964
00965 private:
00966 const int vars_count_;
00967 int64* const weights_;
00968 const int bins_count_;
00969 IntVar* const cost_var_;
00970 Rev<int> first_unbound_backward_;
00971 Rev<int64> sum_of_assigned_items_;
00972 Rev<int64> sum_of_unassigned_items_;
00973 int64* const ranked_;
00974 int ranked_size_;
00975 int64 sum_all_weights_;
00976 };
00977
00978
00979
00980 class CountAssignedItemsDimension : public Dimension {
00981 public:
00982 class VarDemon : public Demon {
00983 public:
00984 explicit VarDemon(CountAssignedItemsDimension* const dim) : dim_(dim) {}
00985 virtual ~VarDemon() {}
00986
00987 virtual void Run(Solver* const s) {
00988 dim_->PropagateAll();
00989 }
00990
00991 private:
00992 CountAssignedItemsDimension* const dim_;
00993 };
00994
00995 CountAssignedItemsDimension(Solver* const s,
00996 Pack* const p,
00997 int vars_count,
00998 int bins_count,
00999 IntVar* const cost_var)
01000 : Dimension(s, p),
01001 vars_count_(vars_count),
01002 bins_count_(bins_count),
01003 cost_var_(cost_var),
01004 first_unbound_backward_(0),
01005 assigned_count_(0),
01006 unassigned_count_(0) {
01007 DCHECK(cost_var);
01008 DCHECK_GT(vars_count, 0);
01009 DCHECK_GT(bins_count, 0);
01010 }
01011
01012 virtual ~CountAssignedItemsDimension() {}
01013
01014 virtual void Post() {
01015 Demon* const uv = solver()->RevAlloc(new VarDemon(this));
01016 cost_var_->WhenRange(uv);
01017 }
01018
01019 void PropagateAll() {
01020 cost_var_->SetRange(assigned_count_.Value(),
01021 vars_count_- unassigned_count_.Value());
01022 if (assigned_count_.Value() == cost_var_->Max()) {
01023 UnassignAllRemainingItems();
01024 } else if (cost_var_->Min() == vars_count_ - unassigned_count_.Value()) {
01025 AssignAllRemainingItems();
01026 }
01027 }
01028
01029 virtual void InitialPropagate(int64 bin_index,
01030 const std::vector<int64>& forced,
01031 const std::vector<int64>& undecided) {}
01032
01033 virtual void EndInitialPropagate() {}
01034
01035 virtual void InitialPropagateUnassigned(const std::vector<int64>& assigned,
01036 const std::vector<int64>& unassigned) {
01037 PropagateUnassigned(assigned, unassigned);
01038 }
01039
01040 virtual void Propagate(int64 bin_index,
01041 const std::vector<int64>& forced,
01042 const std::vector<int64>& removed) {}
01043
01044 virtual void PropagateUnassigned(const std::vector<int64>& assigned,
01045 const std::vector<int64>& unassigned) {
01046 Solver* const s = solver();
01047 assigned_count_.SetValue(s, assigned_count_.Value() + assigned.size());
01048 unassigned_count_.SetValue(s,
01049 unassigned_count_.Value() + unassigned.size());
01050 PropagateAll();
01051 }
01052
01053 virtual void EndPropagate() {}
01054
01055 virtual void Accept(ModelVisitor* const visitor) const {
01056 visitor->BeginVisitExtension(ModelVisitor::kCountAssignedItemsExtension);
01057 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
01058 cost_var_);
01059 visitor->EndVisitExtension(ModelVisitor::kCountAssignedItemsExtension);
01060 }
01061
01062 private:
01063 const int vars_count_;
01064 const int bins_count_;
01065 IntVar* const cost_var_;
01066 Rev<int> first_unbound_backward_;
01067 Rev<int> assigned_count_;
01068 Rev<int> unassigned_count_;
01069 };
01070
01071
01072
01073 class CountUsedBinDimension : public Dimension {
01074 public:
01075 class VarDemon : public Demon {
01076 public:
01077 explicit VarDemon(CountUsedBinDimension* const dim) : dim_(dim) {}
01078 virtual ~VarDemon() {}
01079
01080 virtual void Run(Solver* const s) {
01081 dim_->PropagateAll();
01082 }
01083
01084 private:
01085 CountUsedBinDimension* const dim_;
01086 };
01087
01088 CountUsedBinDimension(Solver* const s,
01089 Pack* const p,
01090 int vars_count,
01091 int bins_count,
01092 IntVar* const count_var)
01093 : Dimension(s, p),
01094 vars_count_(vars_count),
01095 bins_count_(bins_count),
01096 count_var_(count_var),
01097 used_(bins_count_),
01098 candidates_(bins_count_, 0),
01099 card_min_(0),
01100 card_max_(bins_count_),
01101 initial_min_(0),
01102 initial_max_(0) {
01103 DCHECK(count_var);
01104 DCHECK_GT(vars_count, 0);
01105 DCHECK_GT(bins_count, 0);
01106 }
01107
01108 virtual ~CountUsedBinDimension() {}
01109
01110
01111 virtual void Post() {
01112 Demon* const uv = solver()->RevAlloc(new VarDemon(this));
01113 count_var_->WhenRange(uv);
01114 initial_min_ = 0;
01115 initial_max_ = bins_count_;
01116 }
01117
01118 void PropagateAll() {
01119 count_var_->SetRange(card_min_.Value(), card_max_.Value());
01120 if (card_min_.Value() == count_var_->Max()) {
01121 for (int bin_index = 0; bin_index < bins_count_; ++bin_index) {
01122 if (!used_.IsSet(bin_index) && candidates_[bin_index] > 0) {
01123 RemoveAllPossibleFromBin(bin_index);
01124 }
01125 }
01126 } else if (card_max_.Value() == count_var_->Min()) {
01127 for (int bin_index = 0; bin_index < bins_count_; ++bin_index) {
01128 if (candidates_[bin_index] == 1) {
01129 AssignFirstPossibleToBin(bin_index);
01130 }
01131 }
01132 }
01133 }
01134
01135 virtual void InitialPropagate(int64 bin_index,
01136 const std::vector<int64>& forced,
01137 const std::vector<int64>& undecided) {
01138 if (forced.size() > 0) {
01139 used_.SetToOne(solver(), bin_index);
01140 initial_min_++;
01141 } else if (undecided.size() > 0) {
01142 candidates_.SetValue(solver(), bin_index, undecided.size());
01143 } else {
01144 initial_max_--;
01145 }
01146 }
01147
01148 virtual void EndInitialPropagate() {
01149 card_min_.SetValue(solver(), initial_min_);
01150 card_max_.SetValue(solver(), initial_max_);
01151 PropagateAll();
01152 }
01153
01154 virtual void InitialPropagateUnassigned(const std::vector<int64>& assigned,
01155 const std::vector<int64>& unassigned) {}
01156
01157 virtual void Propagate(int64 bin_index,
01158 const std::vector<int64>& forced,
01159 const std::vector<int64>& removed) {
01160 if (!used_.IsSet(bin_index)) {
01161 if (forced.size() > 0) {
01162 used_.SetToOne(solver(), bin_index);
01163 card_min_.SetValue(solver(), card_min_.Value() + 1);
01164 } else if (removed.size() > 0) {
01165 candidates_.SetValue(solver(),
01166 bin_index,
01167 candidates_.Value(bin_index) - removed.size());
01168 if (candidates_[bin_index] == 0) {
01169 card_max_.SetValue(solver(), card_max_.Value() - 1);
01170 }
01171 }
01172 }
01173 }
01174
01175 virtual void PropagateUnassigned(const std::vector<int64>& assigned,
01176 const std::vector<int64>& unassigned) {
01177 }
01178
01179 virtual void EndPropagate() {
01180 PropagateAll();
01181 }
01182
01183 virtual void Accept(ModelVisitor* const visitor) const {
01184 visitor->BeginVisitExtension(ModelVisitor::kCountUsedBinsExtension);
01185 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
01186 count_var_);
01187 visitor->EndVisitExtension(ModelVisitor::kCountUsedBinsExtension);
01188 }
01189
01190 private:
01191 const int vars_count_;
01192 const int bins_count_;
01193 IntVar* const count_var_;
01194 RevBitSet used_;
01195 RevArray<int> candidates_;
01196 Rev<int> card_min_;
01197 Rev<int> card_max_;
01198 int initial_min_;
01199 int initial_max_;
01200 };
01201
01202
01203
01204
01205 class VariableUsageDimension : public Dimension {
01206 public:
01207 VariableUsageDimension(Solver* const solver,
01208 Pack* const pack,
01209 const std::vector<int64>& capacities,
01210 const std::vector<IntVar*>& weights)
01211 : Dimension(solver, pack), capacities_(capacities), weights_(weights) {}
01212
01213 virtual ~VariableUsageDimension() {}
01214
01215 virtual void Post() {
01216 Solver* const s = solver();
01217 const int num_bins = capacities_.size();
01218 const int num_items = weights_.size();
01219
01220 for (int bin_index = 0; bin_index < num_bins; ++bin_index) {
01221 std::vector<IntVar*> terms;
01222 for (int item_index = 0; item_index < num_items; ++item_index) {
01223 IntVar* const assign_var = AssignVar(item_index, bin_index);
01224 terms.push_back(s->MakeProd(assign_var, weights_[item_index])->Var());
01225 }
01226 s->AddConstraint(s->MakeSumLessOrEqual(terms, capacities_[bin_index]));
01227 }
01228 }
01229
01230 virtual void InitialPropagate(int64 bin_index,
01231 const std::vector<int64>& forced,
01232 const std::vector<int64>& undecided) {}
01233 virtual void InitialPropagateUnassigned(const std::vector<int64>& assigned,
01234 const std::vector<int64>& unassigned) {}
01235 virtual void EndInitialPropagate() {}
01236 virtual void Propagate(int64 bin_index,
01237 const std::vector<int64>& forced,
01238 const std::vector<int64>& removed) {}
01239 virtual void PropagateUnassigned(const std::vector<int64>& assigned,
01240 const std::vector<int64>& unassigned) {}
01241 virtual void EndPropagate() {}
01242
01243 virtual string DebugString() const {
01244 return "VariableUsageDimension";
01245 }
01246
01247 virtual void Accept(ModelVisitor* const visitor) const {
01248 visitor->BeginVisitExtension(
01249 ModelVisitor::kVariableUsageLessConstantExtension);
01250 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
01251 capacities_.data(),
01252 capacities_.size());
01253 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
01254 weights_.data(),
01255 weights_.size());
01256 visitor->EndVisitExtension(
01257 ModelVisitor::kVariableUsageLessConstantExtension);
01258 }
01259
01260
01261
01262 private:
01263 const std::vector<int64> capacities_;
01264 const std::vector<IntVar*> weights_;
01265 };
01266 }
01267
01268
01269
01270 void Pack::AddWeightedSumLessOrEqualConstantDimension(
01271 const std::vector<int64>& weights,
01272 const std::vector<int64>& bounds) {
01273 CHECK_EQ(weights.size(), vsize_);
01274 CHECK_EQ(bounds.size(), bins_);
01275 Solver* const s = solver();
01276 Dimension* const dim =
01277 s->RevAlloc(new DimensionLessThanConstant(s,
01278 this,
01279 weights.data(),
01280 weights.size(),
01281 bounds.data(),
01282 bounds.size()));
01283 dims_.push_back(dim);
01284 }
01285
01286 void Pack::AddWeightedSumEqualVarDimension(const std::vector<int64>& weights,
01287 const std::vector<IntVar*>& loads) {
01288 CHECK_EQ(weights.size(), vsize_);
01289 CHECK_EQ(loads.size(), bins_);
01290 Solver* const s = solver();
01291 Dimension* const dim =
01292 s->RevAlloc(new DimensionWeightedSumEqVar(s,
01293 this,
01294 weights.data(),
01295 weights.size(),
01296 loads.data(),
01297 loads.size()));
01298 dims_.push_back(dim);
01299 }
01300
01301 void Pack::AddWeightedSumOfAssignedDimension(const std::vector<int64>& weights,
01302 IntVar* const cost_var) {
01303 CHECK_EQ(weights.size(), vsize_);
01304 Solver* const s = solver();
01305 Dimension* const dim =
01306 s->RevAlloc(new AssignedWeightedSumDimension(s,
01307 this,
01308 weights.data(),
01309 weights.size(),
01310 bins_,
01311 cost_var));
01312 dims_.push_back(dim);
01313 }
01314
01315 void Pack::AddSumVariableWeightsLessOrEqualConstantDimension(
01316 const std::vector<IntVar*>& usage,
01317 const std::vector<int64>& capacity) {
01318 CHECK_EQ(usage.size(), vsize_);
01319 CHECK_EQ(capacity.size(), bins_);
01320 Solver* const s = solver();
01321 Dimension* const dim =
01322 s->RevAlloc(new VariableUsageDimension(s,
01323 this,
01324 capacity,
01325 usage));
01326 dims_.push_back(dim);
01327 }
01328
01329
01330 void Pack::AddCountUsedBinDimension(IntVar* const count_var) {
01331 Solver* const s = solver();
01332 Dimension* const dim =
01333 s->RevAlloc(new CountUsedBinDimension(s, this, vsize_, bins_, count_var));
01334 dims_.push_back(dim);
01335 }
01336
01337 void Pack::AddCountAssignedItemsDimension(IntVar* const count_var) {
01338 Solver* const s = solver();
01339 Dimension* const dim =
01340 s->RevAlloc(new CountAssignedItemsDimension(s, this, vsize_,
01341 bins_, count_var));
01342 dims_.push_back(dim);
01343 }
01344
01345 Pack* Solver::MakePack(const std::vector<IntVar*>& vars, int number_of_bins) {
01346 return RevAlloc(new Pack(this, vars.data(), vars.size(), number_of_bins));
01347 }
01348 }