23 #include "absl/strings/str_format.h"
24 #include "absl/strings/str_join.h"
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"; }
61 return pack_->
IsPossible(var_index, bin_index);
65 return pack_->
AssignVar(var_index, bin_index);
72 void Assign(
int var_index,
int bin_index) {
73 pack_->
Assign(var_index, bin_index);
111 bins_(number_of_bins),
119 for (
int i = 0; i < vars_.size(); ++i) {
120 holes_[i] = vars_[i]->MakeHoleIterator(
true);
127 for (
int i = 0; i < vars_.size(); ++i) {
135 for (
int i = 0; i < dims_.size(); ++i) {
143 for (
int bin_index = 0; bin_index <= bins_; ++bin_index) {
144 forced_[bin_index].clear();
145 removed_[bin_index].clear();
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)
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_;
194 InitialPropagateData* data = s->
RevAlloc(
new InitialPropagateData(bins_));
195 for (
int var_index = 0; var_index < vars_.size(); ++var_index) {
197 var->SetRange(0, bins_);
201 forced_[
value].push_back(var_index);
202 data->PushAssigned(var_index);
204 data->PushUnassigned(var_index);
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));
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) {
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) {
236 "InitialProgateDimension(%s)", dims_[dim_index]->
DebugString()));
238 dims_[dim_index]->InitialPropagate(bin_index, forced_[bin_index],
239 data->undecided(bin_index));
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) {
257 "InitialProgateDimension(%s)", dims_[dim_index]->
DebugString()));
259 dims_[dim_index]->InitialPropagateUnassigned(data->assigned(),
261 dims_[dim_index]->EndInitialPropagate();
278 for (
int bin_index = 0; bin_index < bins_; ++bin_index) {
279 if (!removed_[bin_index].empty() || !forced_[bin_index].empty()) {
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) {
290 "ProgateDimension(%s)", dims_[dim_index]->
DebugString()));
292 dims_[dim_index]->Propagate(bin_index, forced_[bin_index],
293 removed_[bin_index]);
303 if (!removed_[bins_].empty() || !forced_[bins_].empty()) {
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) {
314 "ProgateDimension(%s)", dims_[dim_index]->
DebugString()));
316 dims_[dim_index]->PropagateUnassigned(removed_[bins_], forced_[bins_]);
325 for (
int dim_index = 0; dim_index < dims_.size(); ++dim_index) {
326 dims_[dim_index]->EndPropagate();
338 if (stamp_ < current_stamp) {
339 stamp_ = current_stamp;
350 if (unprocessed_->IsSet(
value, var_index)) {
351 unprocessed_->SetToZero(s,
value, var_index);
352 removed_[
value].push_back(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);
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_);
397 for (
int i = 0; i < dims_.size(); ++i) {
398 dims_[i]->Accept(visitor);
404 return unprocessed_->IsSet(bin_index, var_index);
409 to_unset_.push_back(std::make_pair(var_index, bin_index));
411 vars_[var_index]->RemoveValue(bin_index);
417 to_set_.push_back(std::make_pair(var_index, bin_index));
419 vars_[var_index]->SetValue(bin_index);
424 return !unprocessed_->IsSet(bins_, var_index);
428 return vars_[var_index]->Contains(bin_index);
437 to_unset_.push_back(std::make_pair(var_index, bins_));
439 vars_[var_index]->RemoveValue(bins_);
445 to_set_.push_back(std::make_pair(var_index, bins_));
447 vars_[var_index]->SetValue(bins_);
451 bool Pack::IsInProcess()
const {
456 int var_index = unprocessed_->GetFirstBit(bin_index, 0);
457 while (var_index != -1 && var_index < vars_.size()) {
459 var_index = var_index == vars_.size() - 1
461 : unprocessed_->GetFirstBit(bin_index, var_index + 1);
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);
476 int var_index = unprocessed_->GetFirstBit(bin_index, 0);
477 if (var_index != -1 && var_index < vars_.size()) {
478 Assign(var_index, bin_index);
483 int var_index = unprocessed_->GetFirstBit(bins_, 0);
484 while (var_index != -1 && var_index < vars_.size()) {
486 var_index = var_index == vars_.size() - 1
488 : unprocessed_->GetFirstBit(bins_, var_index + 1);
493 int var_index = unprocessed_->GetFirstBit(bins_, 0);
494 while (var_index != -1 && var_index < vars_.size()) {
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,
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,
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 {
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,
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_) {
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 {
745 const int vars_count_;
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,
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_) {
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 {
849 const int vars_count_;
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_) {
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();
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 {
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,
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_) {
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();
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 {
1125 const int vars_count_;
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) {
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(
1246 visitor->EndVisitExtension(
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) {
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());
1326 unassigned_count_.
Value() + unassigned.size());
1330 void EndPropagate()
override {}
1332 void Accept(ModelVisitor*
const visitor)
const override {
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_),
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 {
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(
1516 visitor->EndVisitExtension(
1521 const std::vector<int64> capacities_;
1522 const std::vector<IntVar*> weights_;
1529 const std::vector<int64>& weights,
const std::vector<int64>&
bounds) {
1530 CHECK_EQ(weights.size(), vars_.size());
1534 s->
RevAlloc(
new DimensionLessThanConstant(s,
this, weights,
bounds));
1535 dims_.push_back(dim);
1540 CHECK(weights !=
nullptr);
1544 s,
this, weights, vars_.size(),
bounds));
1545 dims_.push_back(dim);
1550 CHECK(weights !=
nullptr);
1554 s,
this, weights, vars_.size(),
bounds));
1555 dims_.push_back(dim);
1559 const std::vector<IntVar*>& loads) {
1560 CHECK_EQ(weights.size(), vars_.size());
1564 s->
RevAlloc(
new DimensionWeightedSumEqVar(s,
this, weights, loads));
1565 dims_.push_back(dim);
1569 const std::vector<IntVar*>& loads) {
1570 CHECK(weights !=
nullptr);
1574 s,
this, weights, vars_.size(), loads));
1575 dims_.push_back(dim);
1579 IntVar*
const cost_var) {
1580 CHECK_EQ(weights.size(), vars_.size());
1583 new AssignedWeightedSumDimension(s,
this, weights, bins_, cost_var));
1584 dims_.push_back(dim);
1588 const std::vector<IntVar*>& usage,
const std::vector<int64>&
capacity) {
1589 CHECK_EQ(usage.size(), vars_.size());
1594 dims_.push_back(dim);
1600 new CountUsedBinDimension(s,
this, vars_.size(), bins_, count_var));
1601 dims_.push_back(dim);
1607 new CountAssignedItemsDimension(s,
this, vars_.size(), bins_, count_var));
1608 dims_.push_back(dim);