23 #include "absl/strings/str_format.h"
24 #include "absl/strings/str_join.h"
36 explicit Dimension(Solver*
const s, Pack*
const pack)
37 : solver_(s), pack_(pack) {}
42 const std::vector<int>& undecided) = 0;
44 const std::vector<int>& assigned,
const std::vector<int>& unassigned) = 0;
46 virtual void Propagate(
int bin_index,
const std::vector<int>& forced,
47 const std::vector<int>& removed) = 0;
49 const std::vector<int>& unassigned) = 0;
51 std::string
DebugString()
const override {
return "Dimension"; }
52 virtual void Accept(ModelVisitor*
const visitor)
const = 0;
54 Solver*
solver()
const {
return solver_; }
57 return pack_->IsUndecided(var_index, bin_index);
61 return pack_->IsPossible(var_index, bin_index);
64 IntVar*
AssignVar(
int var_index,
int bin_index)
const {
65 return pack_->AssignVar(var_index, bin_index);
69 pack_->SetImpossible(var_index, bin_index);
72 void Assign(
int var_index,
int bin_index) {
73 pack_->Assign(var_index, bin_index);
77 return pack_->IsAssignedStatusKnown(var_index);
80 void SetAssigned(
int var_index) { pack_->SetAssigned(var_index); }
85 pack_->RemoveAllPossibleFromBin(bin_index);
89 pack_->AssignAllPossibleToBin(bin_index);
93 pack_->AssignFirstPossibleToBin(bin_index);
101 Solver*
const solver_;
107 Pack::Pack(Solver*
const s,
const std::vector<IntVar*>& vars,
111 bins_(number_of_bins),
112 unprocessed_(new RevBitMatrix(bins_ + 1,
vars_.size())),
119 for (
int i = 0; i <
vars_.size(); ++i) {
127 for (
int i = 0; i <
vars_.size(); ++i) {
135 for (
int i = 0; i < dims_.size(); ++i) {
139 solver(),
this, &Pack::Propagate,
"Propagate"));
142 void Pack::ClearAll() {
143 for (
int bin_index = 0; bin_index <= bins_; ++bin_index) {
144 forced_[bin_index].clear();
145 removed_[bin_index].clear();
150 stamp_ = solver()->fail_stamp();
153 void Pack::PropagateDelayed() {
154 for (
int i = 0; i < to_set_.size(); ++i) {
155 vars_[to_set_[i].first]->SetValue(to_set_[i].second);
157 for (
int i = 0; i < to_unset_.size(); ++i) {
158 vars_[to_unset_[i].first]->RemoveValue(to_unset_[i].second);
165 class InitialPropagateData :
public BaseObject {
167 explicit InitialPropagateData(
size_t num_bins)
168 : BaseObject(), undecided_(num_bins) {}
169 void PushAssigned(
int index) { assigned_.push_back(
index); }
170 void PushUnassigned(
int index) { unassigned_.push_back(
index); }
171 void PushUndecided(
int bin,
int index) {
172 undecided_.at(bin).push_back(
index);
174 const std::vector<int>& undecided(
int bin)
const {
175 return undecided_.at(bin);
177 const std::vector<int>& assigned()
const {
return assigned_; }
178 const std::vector<int>& unassigned()
const {
return unassigned_; }
180 std::string DebugString()
const override {
return "InitialPropagateData"; }
183 std::vector<std::vector<int>> undecided_;
184 std::vector<int> unassigned_;
185 std::vector<int> assigned_;
189 void Pack::InitialPropagate() {
190 const bool need_context = solver()->InstrumentsVariables();
192 Solver*
const s = solver();
194 InitialPropagateData* data = s->RevAlloc(
new InitialPropagateData(bins_));
195 for (
int var_index = 0; var_index <
vars_.size(); ++var_index) {
196 IntVar*
const var =
vars_[var_index];
197 var->SetRange(0, bins_);
201 forced_[
value].push_back(var_index);
202 data->PushAssigned(var_index);
204 data->PushUnassigned(var_index);
207 DCHECK_GT(bins_,
var->Min())
208 <<
"The variable maximum should be at most " << bins_
209 <<
", and it should be unbound, so its min is expected to be less "
211 if (
var->Max() < bins_) {
212 data->PushAssigned(var_index);
214 std::unique_ptr<IntVarIterator> it(
var->MakeDomainIterator(
false));
215 for (
const int64 value : InitAndGetValues(it.get())) {
217 unprocessed_->SetToOne(s,
value, var_index);
218 if (
value != bins_) {
219 data->PushUndecided(
value, var_index);
225 for (
int bin_index = 0; bin_index < bins_; ++bin_index) {
227 solver()->GetPropagationMonitor()->PushContext(
228 absl::StrFormat(
"Pack(bin %d, forced = [%s], undecided = [%s])",
229 bin_index, absl::StrJoin(forced_[bin_index],
", "),
230 absl::StrJoin(data->undecided(bin_index),
", ")));
233 for (
int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
235 solver()->GetPropagationMonitor()->PushContext(absl::StrFormat(
236 "InitialProgateDimension(%s)", dims_[dim_index]->DebugString()));
238 dims_[dim_index]->InitialPropagate(bin_index, forced_[bin_index],
239 data->undecided(bin_index));
241 solver()->GetPropagationMonitor()->PopContext();
245 solver()->GetPropagationMonitor()->PopContext();
249 solver()->GetPropagationMonitor()->PushContext(
250 absl::StrFormat(
"Pack(assigned = [%s], unassigned = [%s])",
251 absl::StrJoin(data->assigned(),
", "),
252 absl::StrJoin(data->unassigned(),
", ")));
254 for (
int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
256 solver()->GetPropagationMonitor()->PushContext(absl::StrFormat(
257 "InitialProgateDimension(%s)", dims_[dim_index]->DebugString()));
259 dims_[dim_index]->InitialPropagateUnassigned(data->assigned(),
261 dims_[dim_index]->EndInitialPropagate();
263 solver()->GetPropagationMonitor()->PopContext();
267 solver()->GetPropagationMonitor()->PopContext();
274 void Pack::Propagate() {
275 const bool need_context = solver()->InstrumentsVariables();
277 DCHECK_EQ(
stamp_, solver()->fail_stamp());
278 for (
int bin_index = 0; bin_index < bins_; ++bin_index) {
279 if (!removed_[bin_index].empty() || !forced_[bin_index].empty()) {
281 solver()->GetPropagationMonitor()->PushContext(
282 absl::StrFormat(
"Pack(bin %d, forced = [%s], removed = [%s])",
283 bin_index, absl::StrJoin(forced_[bin_index],
", "),
284 absl::StrJoin(removed_[bin_index],
", ")));
287 for (
int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
289 solver()->GetPropagationMonitor()->PushContext(absl::StrFormat(
290 "ProgateDimension(%s)", dims_[dim_index]->DebugString()));
292 dims_[dim_index]->Propagate(bin_index, forced_[bin_index],
293 removed_[bin_index]);
295 solver()->GetPropagationMonitor()->PopContext();
299 solver()->GetPropagationMonitor()->PopContext();
303 if (!removed_[bins_].empty() || !forced_[bins_].empty()) {
305 solver()->GetPropagationMonitor()->PushContext(
306 absl::StrFormat(
"Pack(removed = [%s], forced = [%s])",
307 absl::StrJoin(removed_[bins_],
", "),
308 absl::StrJoin(forced_[bins_],
", ")));
311 for (
int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
313 solver()->GetPropagationMonitor()->PushContext(absl::StrFormat(
314 "ProgateDimension(%s)", dims_[dim_index]->DebugString()));
316 dims_[dim_index]->PropagateUnassigned(removed_[bins_], forced_[bins_]);
318 solver()->GetPropagationMonitor()->PopContext();
322 solver()->GetPropagationMonitor()->PopContext();
325 for (
int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
326 dims_[dim_index]->EndPropagate();
333 void Pack::OneDomain(
int var_index) {
336 Solver*
const s = solver();
337 const uint64 current_stamp = s->fail_stamp();
338 if (
stamp_ < current_stamp) {
342 IntVar*
const var =
vars_[var_index];
350 if (unprocessed_->IsSet(
value, var_index)) {
351 unprocessed_->SetToZero(s,
value, var_index);
352 removed_[
value].push_back(var_index);
359 DCHECK(unprocessed_->IsSet(
value, var_index));
360 unprocessed_->SetToZero(s,
value, var_index);
361 removed_[
value].push_back(var_index);
366 value <= std::min(oldmax, static_cast<int64>(bins_)); ++
value) {
367 if (unprocessed_->IsSet(
value, var_index)) {
368 unprocessed_->SetToZero(s,
value, var_index);
369 removed_[
value].push_back(var_index);
373 unprocessed_->SetToZero(s,
var->Min(), var_index);
374 forced_[
var->Min()].push_back(var_index);
376 EnqueueDelayedDemon(demon_);
379 std::string Pack::DebugString()
const {
380 std::string result =
"Pack([";
381 for (
int i = 0; i <
vars_.size(); ++i) {
382 result +=
vars_[i]->DebugString() +
" ";
384 result +=
"], dimensions = [";
385 for (
int i = 0; i < dims_.size(); ++i) {
386 result += dims_[i]->DebugString() +
" ";
388 absl::StrAppendFormat(&result,
"], bins = %d)", bins_);
392 void Pack::Accept(ModelVisitor*
const visitor)
const {
393 visitor->BeginVisitConstraint(ModelVisitor::kPack,
this);
394 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
396 visitor->VisitIntegerArgument(ModelVisitor::kSizeArgument, bins_);
397 for (
int i = 0; i < dims_.size(); ++i) {
398 dims_[i]->Accept(visitor);
400 visitor->EndVisitConstraint(ModelVisitor::kPack,
this);
403 bool Pack::IsUndecided(
int var_index,
int bin_index)
const {
404 return unprocessed_->IsSet(bin_index, var_index);
407 void Pack::SetImpossible(
int var_index,
int bin_index) {
409 to_unset_.push_back(std::make_pair(var_index, bin_index));
411 vars_[var_index]->RemoveValue(bin_index);
415 void Pack::Assign(
int var_index,
int bin_index) {
417 to_set_.push_back(std::make_pair(var_index, bin_index));
419 vars_[var_index]->SetValue(bin_index);
423 bool Pack::IsAssignedStatusKnown(
int var_index)
const {
424 return !unprocessed_->IsSet(bins_, var_index);
427 bool Pack::IsPossible(
int var_index,
int bin_index)
const {
428 return vars_[var_index]->Contains(bin_index);
431 IntVar* Pack::AssignVar(
int var_index,
int bin_index)
const {
432 return solver()->MakeIsEqualCstVar(
vars_[var_index], bin_index);
435 void Pack::SetAssigned(
int var_index) {
437 to_unset_.push_back(std::make_pair(var_index, bins_));
439 vars_[var_index]->RemoveValue(bins_);
443 void Pack::SetUnassigned(
int var_index) {
445 to_set_.push_back(std::make_pair(var_index, bins_));
447 vars_[var_index]->SetValue(bins_);
451 bool Pack::IsInProcess()
const {
455 void Pack::RemoveAllPossibleFromBin(
int bin_index) {
456 int var_index = unprocessed_->GetFirstBit(bin_index, 0);
457 while (var_index != -1 && var_index <
vars_.size()) {
458 SetImpossible(var_index, bin_index);
459 var_index = var_index ==
vars_.size() - 1
461 : unprocessed_->GetFirstBit(bin_index, var_index + 1);
465 void Pack::AssignAllPossibleToBin(
int bin_index) {
466 int var_index = unprocessed_->GetFirstBit(bin_index, 0);
467 while (var_index != -1 && var_index <
vars_.size()) {
468 Assign(var_index, bin_index);
469 var_index = var_index ==
vars_.size() - 1
471 : unprocessed_->GetFirstBit(bin_index, var_index + 1);
475 void Pack::AssignFirstPossibleToBin(
int bin_index) {
476 int var_index = unprocessed_->GetFirstBit(bin_index, 0);
477 if (var_index != -1 && var_index <
vars_.size()) {
478 Assign(var_index, bin_index);
482 void Pack::AssignAllRemainingItems() {
483 int var_index = unprocessed_->GetFirstBit(bins_, 0);
484 while (var_index != -1 && var_index <
vars_.size()) {
485 SetAssigned(var_index);
486 var_index = var_index ==
vars_.size() - 1
488 : unprocessed_->GetFirstBit(bins_, var_index + 1);
492 void Pack::UnassignAllRemainingItems() {
493 int var_index = unprocessed_->GetFirstBit(bins_, 0);
494 while (var_index != -1 && var_index <
vars_.size()) {
495 SetUnassigned(var_index);
496 var_index = var_index ==
vars_.size() - 1
498 : unprocessed_->GetFirstBit(bins_, var_index + 1);
507 struct WeightContainer {
511 bool operator<(
const WeightContainer& c)
const {
return (
weight < c.weight); }
514 void SortWeightVector(std::vector<int>*
const indices,
515 std::vector<WeightContainer>*
const to_sort) {
516 std::sort(to_sort->begin(), to_sort->end());
520 indices->resize(to_sort->size());
523 void SortIndexByWeight(std::vector<int>*
const indices,
524 const std::vector<int64>& weights) {
525 std::vector<WeightContainer> to_sort;
527 if (weights[
index] != 0) {
528 to_sort.push_back(WeightContainer((*indices)[
index], weights[
index]));
531 SortWeightVector(indices, &to_sort);
534 void SortIndexByWeight(std::vector<int>*
const indices,
535 const Solver::IndexEvaluator1& weights) {
536 std::vector<WeightContainer> to_sort;
538 const int w = weights(
index);
540 to_sort.push_back(WeightContainer((*indices)[
index], w));
543 SortWeightVector(indices, &to_sort);
546 void SortIndexByWeight(std::vector<int>*
const indices,
547 const Solver::IndexEvaluator2& weights,
int bin_index) {
548 std::vector<WeightContainer> to_sort;
550 const int w = weights(
index, bin_index);
552 to_sort.push_back(WeightContainer((*indices)[
index], w));
555 SortWeightVector(indices, &to_sort);
558 class DimensionLessThanConstant :
public Dimension {
560 DimensionLessThanConstant(Solver*
const s, Pack*
const p,
561 const std::vector<int64>& weights,
564 vars_count_(weights.size()),
568 first_unbound_backward_vector_(bins_count_, 0),
569 sum_of_bound_variables_vector_(bins_count_, 0LL),
570 ranked_(vars_count_) {
571 for (
int i = 0; i < vars_count_; ++i) {
574 SortIndexByWeight(&ranked_, weights_);
577 ~DimensionLessThanConstant()
override {}
579 void Post()
override {}
581 void PushFromTop(
int bin_index) {
583 upper_bounds_[bin_index] - sum_of_bound_variables_vector_[bin_index];
587 int last_unbound = first_unbound_backward_vector_[bin_index];
588 for (; last_unbound >= 0; --last_unbound) {
589 const int var_index = ranked_[last_unbound];
590 if (IsUndecided(var_index, bin_index)) {
591 if (weights_[var_index] > slack) {
592 SetImpossible(var_index, bin_index);
598 first_unbound_backward_vector_.SetValue(solver(), bin_index, last_unbound);
601 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
602 const std::vector<int>& undecided)
override {
603 Solver*
const s = solver();
605 for (
const int value : forced) {
606 sum += weights_[
value];
608 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
609 first_unbound_backward_vector_.SetValue(s, bin_index, ranked_.size() - 1);
610 PushFromTop(bin_index);
613 void EndInitialPropagate()
override {}
615 void Propagate(
int bin_index,
const std::vector<int>& forced,
616 const std::vector<int>& removed)
override {
617 if (!forced.empty()) {
618 Solver*
const s = solver();
619 int64 sum = sum_of_bound_variables_vector_[bin_index];
620 for (
const int value : forced) {
621 sum += weights_[
value];
623 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
624 PushFromTop(bin_index);
627 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
628 const std::vector<int>& unassigned)
override {
630 void PropagateUnassigned(
const std::vector<int>& assigned,
631 const std::vector<int>& unassigned)
override {}
633 void EndPropagate()
override {}
635 void Accept(ModelVisitor*
const visitor)
const override {
636 visitor->BeginVisitExtension(ModelVisitor::kUsageLessConstantExtension);
637 visitor->VisitIntegerArrayArgument(ModelVisitor::kCoefficientsArgument,
639 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
641 visitor->EndVisitExtension(ModelVisitor::kUsageLessConstantExtension);
645 const int vars_count_;
646 const std::vector<int64> weights_;
647 const int bins_count_;
648 const std::vector<int64> upper_bounds_;
649 RevArray<int> first_unbound_backward_vector_;
650 RevArray<int64> sum_of_bound_variables_vector_;
651 std::vector<int> ranked_;
654 class DimensionSumCallbackLessThanConstant :
public Dimension {
656 DimensionSumCallbackLessThanConstant(Solver*
const s, Pack*
const p,
657 const Solver::IndexEvaluator1& weights,
661 vars_count_(vars_count),
665 first_unbound_backward_vector_(bins_count_, 0),
666 sum_of_bound_variables_vector_(bins_count_, 0LL),
667 ranked_(vars_count_) {
669 DCHECK_GT(vars_count, 0);
670 for (
int i = 0; i < vars_count_; ++i) {
673 SortIndexByWeight(&ranked_, weights_);
676 ~DimensionSumCallbackLessThanConstant()
override {}
678 void Post()
override {}
680 void PushFromTop(
int bin_index) {
682 upper_bounds_[bin_index] - sum_of_bound_variables_vector_[bin_index];
686 int last_unbound = first_unbound_backward_vector_[bin_index];
687 for (; last_unbound >= 0; --last_unbound) {
688 const int var_index = ranked_[last_unbound];
689 if (IsUndecided(var_index, bin_index)) {
690 if (weights_(var_index) > slack) {
691 SetImpossible(var_index, bin_index);
697 first_unbound_backward_vector_.SetValue(solver(), bin_index, last_unbound);
700 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
701 const std::vector<int>& undecided)
override {
702 Solver*
const s = solver();
704 for (
const int value : forced) {
705 sum += weights_(
value);
707 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
708 first_unbound_backward_vector_.SetValue(s, bin_index, ranked_.size() - 1);
709 PushFromTop(bin_index);
712 void EndInitialPropagate()
override {}
714 void Propagate(
int bin_index,
const std::vector<int>& forced,
715 const std::vector<int>& removed)
override {
716 if (!forced.empty()) {
717 Solver*
const s = solver();
718 int64 sum = sum_of_bound_variables_vector_[bin_index];
719 for (
const int value : forced) {
720 sum += weights_(
value);
722 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
723 PushFromTop(bin_index);
726 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
727 const std::vector<int>& unassigned)
override {
729 void PropagateUnassigned(
const std::vector<int>& assigned,
730 const std::vector<int>& unassigned)
override {}
732 void EndPropagate()
override {}
734 void Accept(ModelVisitor*
const visitor)
const override {
735 visitor->BeginVisitExtension(ModelVisitor::kUsageLessConstantExtension);
739 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
741 visitor->EndVisitExtension(ModelVisitor::kUsageLessConstantExtension);
745 const int vars_count_;
746 Solver::IndexEvaluator1 weights_;
747 const int bins_count_;
748 const std::vector<int64> upper_bounds_;
749 RevArray<int> first_unbound_backward_vector_;
750 RevArray<int64> sum_of_bound_variables_vector_;
751 std::vector<int> ranked_;
754 class DimensionLessThanConstantCallback2 :
public Dimension {
756 DimensionLessThanConstantCallback2(Solver*
const s, Pack*
const p,
757 const Solver::IndexEvaluator2& weights,
761 vars_count_(vars_count),
765 first_unbound_backward_vector_(bins_count_, 0),
766 sum_of_bound_variables_vector_(bins_count_, 0LL),
767 ranked_(bins_count_) {
769 DCHECK_GT(vars_count, 0);
770 for (
int b = 0;
b < bins_count_; ++
b) {
771 ranked_[
b].resize(vars_count);
772 for (
int i = 0; i < vars_count_; ++i) {
775 SortIndexByWeight(&ranked_[
b], weights_,
b);
779 ~DimensionLessThanConstantCallback2()
override {}
781 void Post()
override {}
783 void PushFromTop(
int bin_index) {
785 upper_bounds_[bin_index] - sum_of_bound_variables_vector_[bin_index];
789 int last_unbound = first_unbound_backward_vector_[bin_index];
790 for (; last_unbound >= 0; --last_unbound) {
791 const int var_index = ranked_[bin_index][last_unbound];
792 if (IsUndecided(var_index, bin_index)) {
793 if (weights_(var_index, bin_index) > slack) {
794 SetImpossible(var_index, bin_index);
800 first_unbound_backward_vector_.SetValue(solver(), bin_index, last_unbound);
803 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
804 const std::vector<int>& undecided)
override {
805 Solver*
const s = solver();
807 for (
const int value : forced) {
808 sum += weights_(
value, bin_index);
810 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
811 first_unbound_backward_vector_.SetValue(s, bin_index,
812 ranked_[bin_index].size() - 1);
813 PushFromTop(bin_index);
816 void EndInitialPropagate()
override {}
818 void Propagate(
int bin_index,
const std::vector<int>& forced,
819 const std::vector<int>& removed)
override {
820 if (!forced.empty()) {
821 Solver*
const s = solver();
822 int64 sum = sum_of_bound_variables_vector_[bin_index];
823 for (
const int value : forced) {
824 sum += weights_(
value, bin_index);
826 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
827 PushFromTop(bin_index);
830 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
831 const std::vector<int>& unassigned)
override {
833 void PropagateUnassigned(
const std::vector<int>& assigned,
834 const std::vector<int>& unassigned)
override {}
836 void EndPropagate()
override {}
838 void Accept(ModelVisitor*
const visitor)
const override {
839 visitor->BeginVisitExtension(ModelVisitor::kUsageLessConstantExtension);
843 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
845 visitor->EndVisitExtension(ModelVisitor::kUsageLessConstantExtension);
849 const int vars_count_;
850 Solver::IndexEvaluator2 weights_;
851 const int bins_count_;
852 const std::vector<int64> upper_bounds_;
853 RevArray<int> first_unbound_backward_vector_;
854 RevArray<int64> sum_of_bound_variables_vector_;
855 std::vector<std::vector<int>> ranked_;
858 class DimensionWeightedSumEqVar :
public Dimension {
860 class VarDemon :
public Demon {
862 VarDemon(DimensionWeightedSumEqVar*
const dim,
int index)
863 : dim_(dim), index_(
index) {}
864 ~VarDemon()
override {}
866 void Run(Solver*
const s)
override { dim_->PushFromTop(index_); }
869 DimensionWeightedSumEqVar*
const dim_;
873 DimensionWeightedSumEqVar(Solver*
const s, Pack*
const p,
874 const std::vector<int64>& weights,
875 const std::vector<IntVar*>& loads)
877 vars_count_(weights.size()),
879 bins_count_(loads.size()),
881 first_unbound_backward_vector_(bins_count_, 0),
882 sum_of_bound_variables_vector_(bins_count_, 0LL),
883 sum_of_all_variables_vector_(bins_count_, 0LL),
884 ranked_(vars_count_) {
885 DCHECK_GT(vars_count_, 0);
886 DCHECK_GT(bins_count_, 0);
887 for (
int i = 0; i < vars_count_; ++i) {
890 SortIndexByWeight(&ranked_, weights_);
893 ~DimensionWeightedSumEqVar()
override {}
895 std::string DebugString()
const override {
896 return "DimensionWeightedSumEqVar";
899 void Post()
override {
900 for (
int i = 0; i < bins_count_; ++i) {
901 Demon*
const d = solver()->RevAlloc(
new VarDemon(
this, i));
902 loads_[i]->WhenRange(d);
906 void PushFromTop(
int bin_index) {
907 IntVar*
const load = loads_[bin_index];
908 const int64 sum_min = sum_of_bound_variables_vector_[bin_index];
909 const int64 sum_max = sum_of_all_variables_vector_[bin_index];
910 load->SetRange(sum_min, sum_max);
911 const int64 slack_up = load->Max() - sum_min;
912 const int64 slack_down = sum_max - load->Min();
913 DCHECK_GE(slack_down, 0);
914 DCHECK_GE(slack_up, 0);
915 int last_unbound = first_unbound_backward_vector_[bin_index];
916 for (; last_unbound >= 0; --last_unbound) {
917 const int var_index = ranked_[last_unbound];
919 if (IsUndecided(var_index, bin_index)) {
921 SetImpossible(var_index, bin_index);
922 }
else if (
weight > slack_down) {
923 Assign(var_index, bin_index);
929 first_unbound_backward_vector_.SetValue(solver(), bin_index, last_unbound);
932 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
933 const std::vector<int>& undecided)
override {
934 Solver*
const s = solver();
936 for (
const int value : forced) {
937 sum += weights_[
value];
939 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
940 for (
const int value : undecided) {
941 sum += weights_[
value];
943 sum_of_all_variables_vector_.SetValue(s, bin_index, sum);
944 first_unbound_backward_vector_.SetValue(s, bin_index, ranked_.size() - 1);
945 PushFromTop(bin_index);
948 void EndInitialPropagate()
override {}
950 void Propagate(
int bin_index,
const std::vector<int>& forced,
951 const std::vector<int>& removed)
override {
952 Solver*
const s = solver();
953 int64 down = sum_of_bound_variables_vector_[bin_index];
954 for (
const int value : forced) {
955 down += weights_[
value];
957 sum_of_bound_variables_vector_.SetValue(s, bin_index, down);
958 int64 up = sum_of_all_variables_vector_[bin_index];
959 for (
const int value : removed) {
960 up -= weights_[
value];
962 sum_of_all_variables_vector_.SetValue(s, bin_index, up);
963 PushFromTop(bin_index);
965 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
966 const std::vector<int>& unassigned)
override {
968 void PropagateUnassigned(
const std::vector<int>& assigned,
969 const std::vector<int>& unassigned)
override {}
971 void EndPropagate()
override {}
973 void Accept(ModelVisitor*
const visitor)
const override {
974 visitor->BeginVisitExtension(ModelVisitor::kUsageEqualVariableExtension);
975 visitor->VisitIntegerArrayArgument(ModelVisitor::kCoefficientsArgument,
977 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
979 visitor->EndVisitExtension(ModelVisitor::kUsageEqualVariableExtension);
983 const int vars_count_;
984 const std::vector<int64> weights_;
985 const int bins_count_;
986 const std::vector<IntVar*> loads_;
987 RevArray<int> first_unbound_backward_vector_;
988 RevArray<int64> sum_of_bound_variables_vector_;
989 RevArray<int64> sum_of_all_variables_vector_;
990 std::vector<int> ranked_;
993 class DimensionWeightedCallback2SumEqVar :
public Dimension {
995 class VarDemon :
public Demon {
997 VarDemon(DimensionWeightedCallback2SumEqVar*
const dim,
int index)
998 : dim_(dim), index_(
index) {}
999 ~VarDemon()
override {}
1001 void Run(Solver*
const s)
override { dim_->PushFromTop(index_); }
1004 DimensionWeightedCallback2SumEqVar*
const dim_;
1008 DimensionWeightedCallback2SumEqVar(Solver*
const s, Pack*
const p,
1009 const Solver::IndexEvaluator2& weights,
1011 const std::vector<IntVar*>& loads)
1013 vars_count_(vars_count),
1015 bins_count_(loads.size()),
1017 first_unbound_backward_vector_(bins_count_, 0),
1018 sum_of_bound_variables_vector_(bins_count_, 0LL),
1019 sum_of_all_variables_vector_(bins_count_, 0LL),
1020 ranked_(bins_count_) {
1022 DCHECK_GT(vars_count_, 0);
1023 DCHECK_GT(bins_count_, 0);
1024 for (
int b = 0;
b < bins_count_; ++
b) {
1025 ranked_[
b].resize(vars_count);
1026 for (
int i = 0; i < vars_count_; ++i) {
1029 SortIndexByWeight(&ranked_[
b], weights_,
b);
1033 ~DimensionWeightedCallback2SumEqVar()
override {}
1035 std::string DebugString()
const override {
1036 return "DimensionWeightedCallback2SumEqVar";
1039 void Post()
override {
1040 for (
int i = 0; i < bins_count_; ++i) {
1041 Demon*
const d = solver()->RevAlloc(
new VarDemon(
this, i));
1042 loads_[i]->WhenRange(d);
1046 void PushFromTop(
int bin_index) {
1047 IntVar*
const load = loads_[bin_index];
1048 const int64 sum_min = sum_of_bound_variables_vector_[bin_index];
1049 const int64 sum_max = sum_of_all_variables_vector_[bin_index];
1050 load->SetRange(sum_min, sum_max);
1051 const int64 slack_up = load->Max() - sum_min;
1052 const int64 slack_down = sum_max - load->Min();
1053 DCHECK_GE(slack_down, 0);
1054 DCHECK_GE(slack_up, 0);
1055 int last_unbound = first_unbound_backward_vector_[bin_index];
1056 for (; last_unbound >= 0; --last_unbound) {
1057 const int var_index = ranked_[bin_index][last_unbound];
1058 const int64 weight = weights_(var_index, bin_index);
1059 if (IsUndecided(var_index, bin_index)) {
1061 SetImpossible(var_index, bin_index);
1062 }
else if (
weight > slack_down) {
1063 Assign(var_index, bin_index);
1069 first_unbound_backward_vector_.SetValue(solver(), bin_index, last_unbound);
1072 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
1073 const std::vector<int>& undecided)
override {
1074 Solver*
const s = solver();
1076 for (
const int value : forced) {
1077 sum += weights_(
value, bin_index);
1079 sum_of_bound_variables_vector_.SetValue(s, bin_index, sum);
1080 for (
const int value : undecided) {
1081 sum += weights_(
value, bin_index);
1083 sum_of_all_variables_vector_.SetValue(s, bin_index, sum);
1084 first_unbound_backward_vector_.SetValue(s, bin_index,
1085 ranked_[bin_index].size() - 1);
1086 PushFromTop(bin_index);
1089 void EndInitialPropagate()
override {}
1091 void Propagate(
int bin_index,
const std::vector<int>& forced,
1092 const std::vector<int>& removed)
override {
1093 Solver*
const s = solver();
1094 int64 down = sum_of_bound_variables_vector_[bin_index];
1095 for (
const int value : forced) {
1096 down += weights_(
value, bin_index);
1098 sum_of_bound_variables_vector_.SetValue(s, bin_index, down);
1099 int64 up = sum_of_all_variables_vector_[bin_index];
1100 for (
const int value : removed) {
1101 up -= weights_(
value, bin_index);
1103 sum_of_all_variables_vector_.SetValue(s, bin_index, up);
1104 PushFromTop(bin_index);
1106 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
1107 const std::vector<int>& unassigned)
override {
1109 void PropagateUnassigned(
const std::vector<int>& assigned,
1110 const std::vector<int>& unassigned)
override {}
1112 void EndPropagate()
override {}
1114 void Accept(ModelVisitor*
const visitor)
const override {
1115 visitor->BeginVisitExtension(ModelVisitor::kUsageEqualVariableExtension);
1119 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
1121 visitor->EndVisitExtension(ModelVisitor::kUsageEqualVariableExtension);
1125 const int vars_count_;
1126 Solver::IndexEvaluator2 weights_;
1127 const int bins_count_;
1128 const std::vector<IntVar*> loads_;
1129 RevArray<int> first_unbound_backward_vector_;
1130 RevArray<int64> sum_of_bound_variables_vector_;
1131 RevArray<int64> sum_of_all_variables_vector_;
1132 std::vector<std::vector<int>> ranked_;
1135 class AssignedWeightedSumDimension :
public Dimension {
1137 class VarDemon :
public Demon {
1139 explicit VarDemon(AssignedWeightedSumDimension*
const dim) : dim_(dim) {}
1140 ~VarDemon()
override {}
1142 void Run(Solver*
const s)
override { dim_->PropagateAll(); }
1145 AssignedWeightedSumDimension*
const dim_;
1148 AssignedWeightedSumDimension(Solver*
const s, Pack*
const p,
1149 const std::vector<int64>& weights,
1150 int bins_count, IntVar*
const cost_var)
1152 vars_count_(weights.size()),
1154 bins_count_(bins_count),
1155 cost_var_(cost_var),
1156 first_unbound_backward_(0),
1157 sum_of_assigned_items_(0LL),
1158 sum_of_unassigned_items_(0LL),
1159 ranked_(vars_count_),
1160 sum_all_weights_(0LL) {
1162 DCHECK_GT(vars_count_, 0);
1163 DCHECK_GT(bins_count_, 0);
1164 for (
int i = 0; i < vars_count_; ++i) {
1167 SortIndexByWeight(&ranked_, weights_);
1168 first_unbound_backward_.SetValue(s, ranked_.size() - 1);
1171 ~AssignedWeightedSumDimension()
override {}
1173 void Post()
override {
1174 Demon*
const uv = solver()->RevAlloc(
new VarDemon(
this));
1175 cost_var_->WhenRange(uv);
1178 void PropagateAll() {
1179 cost_var_->SetRange(sum_of_assigned_items_.Value(),
1180 sum_all_weights_ - sum_of_unassigned_items_.Value());
1181 const int64 slack_up = cost_var_->Max() - sum_of_assigned_items_.Value();
1182 const int64 slack_down = sum_all_weights_ - cost_var_->Min();
1183 int last_unbound = first_unbound_backward_.Value();
1184 for (; last_unbound >= 0; --last_unbound) {
1185 const int var_index = ranked_[last_unbound];
1186 if (!IsAssignedStatusKnown(var_index)) {
1189 SetUnassigned(var_index);
1191 SetAssigned(var_index);
1197 first_unbound_backward_.SetValue(solver(), last_unbound);
1200 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
1201 const std::vector<int>& undecided)
override {}
1203 void EndInitialPropagate()
override {}
1205 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
1206 const std::vector<int>& unassigned)
override {
1208 sum_all_weights_ += weights_[
index];
1211 PropagateUnassigned(assigned, unassigned);
1214 void Propagate(
int bin_index,
const std::vector<int>& forced,
1215 const std::vector<int>& removed)
override {}
1217 void PropagateUnassigned(
const std::vector<int>& assigned,
1218 const std::vector<int>& unassigned)
override {
1219 int64 sum_assigned = sum_of_assigned_items_.Value();
1221 const int var_index = assigned[
index];
1222 sum_assigned += weights_[var_index];
1225 int64 sum_unassigned = sum_of_unassigned_items_.Value();
1227 const int var_index = unassigned[
index];
1228 sum_unassigned += weights_[var_index];
1231 Solver*
const s = solver();
1232 sum_of_assigned_items_.SetValue(s, sum_assigned);
1233 sum_of_unassigned_items_.SetValue(s, sum_unassigned);
1237 void EndPropagate()
override {}
1239 void Accept(ModelVisitor*
const visitor)
const override {
1240 visitor->BeginVisitExtension(
1241 ModelVisitor::kWeightedSumOfAssignedEqualVariableExtension);
1242 visitor->VisitIntegerArrayArgument(ModelVisitor::kCoefficientsArgument,
1244 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
1246 visitor->EndVisitExtension(
1247 ModelVisitor::kWeightedSumOfAssignedEqualVariableExtension);
1251 const int vars_count_;
1252 const std::vector<int64> weights_;
1253 const int bins_count_;
1254 IntVar*
const cost_var_;
1255 Rev<int> first_unbound_backward_;
1256 Rev<int64> sum_of_assigned_items_;
1257 Rev<int64> sum_of_unassigned_items_;
1258 std::vector<int> ranked_;
1259 int64 sum_all_weights_;
1264 class CountAssignedItemsDimension :
public Dimension {
1266 class VarDemon :
public Demon {
1268 explicit VarDemon(CountAssignedItemsDimension*
const dim) : dim_(dim) {}
1269 ~VarDemon()
override {}
1271 void Run(Solver*
const s)
override { dim_->PropagateAll(); }
1274 CountAssignedItemsDimension*
const dim_;
1277 CountAssignedItemsDimension(Solver*
const s, Pack*
const p,
int vars_count,
1278 int bins_count, IntVar*
const cost_var)
1280 vars_count_(vars_count),
1281 bins_count_(bins_count),
1282 cost_var_(cost_var),
1283 first_unbound_backward_(0),
1285 unassigned_count_(0) {
1287 DCHECK_GT(vars_count, 0);
1288 DCHECK_GT(bins_count, 0);
1291 ~CountAssignedItemsDimension()
override {}
1293 void Post()
override {
1294 Demon*
const uv = solver()->RevAlloc(
new VarDemon(
this));
1295 cost_var_->WhenRange(uv);
1298 void PropagateAll() {
1299 cost_var_->SetRange(assigned_count_.Value(),
1300 vars_count_ - unassigned_count_.Value());
1301 if (assigned_count_.Value() == cost_var_->Max()) {
1302 UnassignAllRemainingItems();
1303 }
else if (cost_var_->Min() == vars_count_ - unassigned_count_.Value()) {
1304 AssignAllRemainingItems();
1308 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
1309 const std::vector<int>& undecided)
override {}
1311 void EndInitialPropagate()
override {}
1313 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
1314 const std::vector<int>& unassigned)
override {
1315 PropagateUnassigned(assigned, unassigned);
1318 void Propagate(
int bin_index,
const std::vector<int>& forced,
1319 const std::vector<int>& removed)
override {}
1321 void PropagateUnassigned(
const std::vector<int>& assigned,
1322 const std::vector<int>& unassigned)
override {
1323 Solver*
const s = solver();
1324 assigned_count_.SetValue(s, assigned_count_.Value() + assigned.size());
1325 unassigned_count_.SetValue(s,
1326 unassigned_count_.Value() + unassigned.size());
1330 void EndPropagate()
override {}
1332 void Accept(ModelVisitor*
const visitor)
const override {
1333 visitor->BeginVisitExtension(ModelVisitor::kCountAssignedItemsExtension);
1334 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
1336 visitor->EndVisitExtension(ModelVisitor::kCountAssignedItemsExtension);
1340 const int vars_count_;
1341 const int bins_count_;
1342 IntVar*
const cost_var_;
1343 Rev<int> first_unbound_backward_;
1344 Rev<int> assigned_count_;
1345 Rev<int> unassigned_count_;
1350 class CountUsedBinDimension :
public Dimension {
1352 class VarDemon :
public Demon {
1354 explicit VarDemon(CountUsedBinDimension*
const dim) : dim_(dim) {}
1355 ~VarDemon()
override {}
1357 void Run(Solver*
const s)
override { dim_->PropagateAll(); }
1360 CountUsedBinDimension*
const dim_;
1363 CountUsedBinDimension(Solver*
const s, Pack*
const p,
int vars_count,
1364 int bins_count, IntVar*
const count_var)
1366 vars_count_(vars_count),
1367 bins_count_(bins_count),
1368 count_var_(count_var),
1370 candidates_(bins_count_, 0),
1372 card_max_(bins_count_),
1376 DCHECK_GT(vars_count, 0);
1377 DCHECK_GT(bins_count, 0);
1380 ~CountUsedBinDimension()
override {}
1382 void Post()
override {
1383 Demon*
const uv = solver()->RevAlloc(
new VarDemon(
this));
1384 count_var_->WhenRange(uv);
1386 initial_max_ = bins_count_;
1389 void PropagateAll() {
1390 count_var_->SetRange(card_min_.Value(), card_max_.Value());
1391 if (card_min_.Value() == count_var_->Max()) {
1392 for (
int bin_index = 0; bin_index < bins_count_; ++bin_index) {
1393 if (!used_.IsSet(bin_index) && candidates_[bin_index] > 0) {
1394 RemoveAllPossibleFromBin(bin_index);
1397 }
else if (card_max_.Value() == count_var_->Min()) {
1398 for (
int bin_index = 0; bin_index < bins_count_; ++bin_index) {
1399 if (candidates_[bin_index] == 1) {
1400 AssignFirstPossibleToBin(bin_index);
1406 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
1407 const std::vector<int>& undecided)
override {
1408 if (!forced.empty()) {
1409 used_.SetToOne(solver(), bin_index);
1411 }
else if (!undecided.empty()) {
1412 candidates_.SetValue(solver(), bin_index, undecided.size());
1418 void EndInitialPropagate()
override {
1419 card_min_.SetValue(solver(), initial_min_);
1420 card_max_.SetValue(solver(), initial_max_);
1424 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
1425 const std::vector<int>& unassigned)
override {
1428 void Propagate(
int bin_index,
const std::vector<int>& forced,
1429 const std::vector<int>& removed)
override {
1430 if (!used_.IsSet(bin_index)) {
1431 if (!forced.empty()) {
1432 used_.SetToOne(solver(), bin_index);
1433 card_min_.SetValue(solver(), card_min_.Value() + 1);
1434 }
else if (!removed.empty()) {
1435 candidates_.SetValue(solver(), bin_index,
1436 candidates_.Value(bin_index) - removed.size());
1437 if (candidates_[bin_index] == 0) {
1438 card_max_.SetValue(solver(), card_max_.Value() - 1);
1444 void PropagateUnassigned(
const std::vector<int>& assigned,
1445 const std::vector<int>& unassigned)
override {}
1447 void EndPropagate()
override { PropagateAll(); }
1449 void Accept(ModelVisitor*
const visitor)
const override {
1450 visitor->BeginVisitExtension(ModelVisitor::kCountUsedBinsExtension);
1451 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
1453 visitor->EndVisitExtension(ModelVisitor::kCountUsedBinsExtension);
1457 const int vars_count_;
1458 const int bins_count_;
1459 IntVar*
const count_var_;
1461 RevArray<int> candidates_;
1471 class VariableUsageDimension :
public Dimension {
1473 VariableUsageDimension(Solver*
const solver, Pack*
const pack,
1474 const std::vector<int64>& capacities,
1475 const std::vector<IntVar*>& weights)
1476 : Dimension(solver, pack), capacities_(capacities), weights_(weights) {}
1478 ~VariableUsageDimension()
override {}
1480 void Post()
override {
1481 Solver*
const s = solver();
1482 const int num_bins = capacities_.size();
1483 const int num_items = weights_.size();
1485 for (
int bin_index = 0; bin_index < num_bins; ++bin_index) {
1486 std::vector<IntVar*> terms;
1487 for (
int item_index = 0; item_index < num_items; ++item_index) {
1488 IntVar*
const assign_var = AssignVar(item_index, bin_index);
1489 terms.push_back(s->MakeProd(assign_var, weights_[item_index])->Var());
1491 s->AddConstraint(s->MakeSumLessOrEqual(terms, capacities_[bin_index]));
1495 void InitialPropagate(
int bin_index,
const std::vector<int>& forced,
1496 const std::vector<int>& undecided)
override {}
1497 void InitialPropagateUnassigned(
const std::vector<int>& assigned,
1498 const std::vector<int>& unassigned)
override {
1500 void EndInitialPropagate()
override {}
1501 void Propagate(
int bin_index,
const std::vector<int>& forced,
1502 const std::vector<int>& removed)
override {}
1503 void PropagateUnassigned(
const std::vector<int>& assigned,
1504 const std::vector<int>& unassigned)
override {}
1505 void EndPropagate()
override {}
1507 std::string DebugString()
const override {
return "VariableUsageDimension"; }
1509 void Accept(ModelVisitor*
const visitor)
const override {
1510 visitor->BeginVisitExtension(
1511 ModelVisitor::kVariableUsageLessConstantExtension);
1512 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
1514 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
1516 visitor->EndVisitExtension(
1517 ModelVisitor::kVariableUsageLessConstantExtension);
1521 const std::vector<int64> capacities_;
1522 const std::vector<IntVar*> weights_;
1528 void Pack::AddWeightedSumLessOrEqualConstantDimension(
1529 const std::vector<int64>& weights,
const std::vector<int64>&
bounds) {
1530 CHECK_EQ(weights.size(),
vars_.size());
1531 CHECK_EQ(
bounds.size(), bins_);
1532 Solver*
const s = solver();
1533 Dimension*
const dim =
1534 s->RevAlloc(
new DimensionLessThanConstant(s,
this, weights,
bounds));
1535 dims_.push_back(dim);
1538 void Pack::AddWeightedSumLessOrEqualConstantDimension(
1539 Solver::IndexEvaluator1 weights,
const std::vector<int64>&
bounds) {
1540 CHECK(weights !=
nullptr);
1541 CHECK_EQ(
bounds.size(), bins_);
1542 Solver*
const s = solver();
1543 Dimension*
const dim = s->RevAlloc(
new DimensionSumCallbackLessThanConstant(
1545 dims_.push_back(dim);
1548 void Pack::AddWeightedSumLessOrEqualConstantDimension(
1549 Solver::IndexEvaluator2 weights,
const std::vector<int64>&
bounds) {
1550 CHECK(weights !=
nullptr);
1551 CHECK_EQ(
bounds.size(), bins_);
1552 Solver*
const s = solver();
1553 Dimension*
const dim = s->RevAlloc(
new DimensionLessThanConstantCallback2(
1555 dims_.push_back(dim);
1558 void Pack::AddWeightedSumEqualVarDimension(
const std::vector<int64>& weights,
1559 const std::vector<IntVar*>& loads) {
1560 CHECK_EQ(weights.size(),
vars_.size());
1561 CHECK_EQ(loads.size(), bins_);
1562 Solver*
const s = solver();
1563 Dimension*
const dim =
1564 s->RevAlloc(
new DimensionWeightedSumEqVar(s,
this, weights, loads));
1565 dims_.push_back(dim);
1568 void Pack::AddWeightedSumEqualVarDimension(Solver::IndexEvaluator2 weights,
1569 const std::vector<IntVar*>& loads) {
1570 CHECK(weights !=
nullptr);
1571 CHECK_EQ(loads.size(), bins_);
1572 Solver*
const s = solver();
1573 Dimension*
const dim = s->RevAlloc(
new DimensionWeightedCallback2SumEqVar(
1574 s,
this, weights,
vars_.size(), loads));
1575 dims_.push_back(dim);
1578 void Pack::AddWeightedSumOfAssignedDimension(
const std::vector<int64>& weights,
1579 IntVar*
const cost_var) {
1580 CHECK_EQ(weights.size(),
vars_.size());
1581 Solver*
const s = solver();
1582 Dimension*
const dim = s->RevAlloc(
1583 new AssignedWeightedSumDimension(s,
this, weights, bins_, cost_var));
1584 dims_.push_back(dim);
1587 void Pack::AddSumVariableWeightsLessOrEqualConstantDimension(
1588 const std::vector<IntVar*>& usage,
const std::vector<int64>&
capacity) {
1589 CHECK_EQ(usage.size(),
vars_.size());
1591 Solver*
const s = solver();
1592 Dimension*
const dim =
1593 s->RevAlloc(
new VariableUsageDimension(s,
this,
capacity, usage));
1594 dims_.push_back(dim);
1597 void Pack::AddCountUsedBinDimension(IntVar*
const count_var) {
1598 Solver*
const s = solver();
1599 Dimension*
const dim = s->RevAlloc(
1600 new CountUsedBinDimension(s,
this,
vars_.size(), bins_, count_var));
1601 dims_.push_back(dim);
1604 void Pack::AddCountAssignedItemsDimension(IntVar*
const count_var) {
1605 Solver*
const s = solver();
1606 Dimension*
const dim = s->RevAlloc(
1607 new CountAssignedItemsDimension(s,
this,
vars_.size(), bins_, count_var));
1608 dims_.push_back(dim);
1611 Pack* Solver::MakePack(
const std::vector<IntVar*>& vars,
int number_of_bins) {
1612 return RevAlloc(
new Pack(
this, vars, number_of_bins));