Skip to content

Commit 6041f1d

Browse files
committed
[FZ] add global cardinality native support; bypass expansion
1 parent 0e7b4c6 commit 6041f1d

File tree

8 files changed

+669
-246
lines changed

8 files changed

+669
-246
lines changed

ortools/flatzinc/checker.cc

Lines changed: 16 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -665,92 +665,51 @@ std::vector<int64_t> ComputeGlobalCardinalityCards(
665665
return cards;
666666
}
667667

668-
bool CheckGlobalCardinality(
668+
bool CheckOrToolsGlobalCardinality(
669669
const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator,
670670
const std::function<std::vector<int64_t>(Variable*)>& set_evaluator) {
671671
const std::vector<int64_t> cards =
672672
ComputeGlobalCardinalityCards(ct, evaluator);
673673
CHECK_EQ(cards.size(), Length(ct.arguments[2]));
674+
const bool is_closed = Eval(ct.arguments[3], evaluator) != 0;
674675
for (int i = 0; i < Length(ct.arguments[2]); ++i) {
675676
const int64_t card = EvalAt(ct.arguments[2], i, evaluator);
676677
if (card != cards[i]) {
677678
return false;
678679
}
679680
}
680-
return true;
681-
}
682681

683-
bool CheckGlobalCardinalityClosed(
684-
const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator,
685-
const std::function<std::vector<int64_t>(Variable*)>& set_evaluator) {
686-
const std::vector<int64_t> cards =
687-
ComputeGlobalCardinalityCards(ct, evaluator);
688-
CHECK_EQ(cards.size(), Length(ct.arguments[2]));
689-
for (int i = 0; i < Length(ct.arguments[2]); ++i) {
690-
const int64_t card = EvalAt(ct.arguments[2], i, evaluator);
691-
if (card != cards[i]) {
692-
return false;
693-
}
694-
}
695-
int64_t sum_of_cards = 0;
696-
for (int64_t card : cards) {
697-
sum_of_cards += card;
698-
}
699-
return sum_of_cards == Length(ct.arguments[0]);
700-
}
701-
702-
bool CheckGlobalCardinalityLowUp(
703-
const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator,
704-
const std::function<std::vector<int64_t>(Variable*)>& set_evaluator) {
705-
const std::vector<int64_t> cards =
706-
ComputeGlobalCardinalityCards(ct, evaluator);
707-
CHECK_EQ(cards.size(), ct.arguments[2].values.size());
708-
CHECK_EQ(cards.size(), ct.arguments[3].values.size());
709-
for (int i = 0; i < cards.size(); ++i) {
710-
const int64_t card = cards[i];
711-
if (card < ct.arguments[2].values[i] || card > ct.arguments[3].values[i]) {
712-
return false;
682+
if (is_closed) {
683+
int64_t sum_of_cards = 0;
684+
for (int64_t card : cards) {
685+
sum_of_cards += card;
713686
}
687+
return sum_of_cards == Length(ct.arguments[0]);
714688
}
715689
return true;
716690
}
717691

718-
bool CheckGlobalCardinalityLowUpClosed(
692+
bool CheckOrToolsGlobalCardinalityLowUp(
719693
const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator,
720694
const std::function<std::vector<int64_t>(Variable*)>& set_evaluator) {
721695
const std::vector<int64_t> cards =
722696
ComputeGlobalCardinalityCards(ct, evaluator);
723697
CHECK_EQ(cards.size(), ct.arguments[2].values.size());
724698
CHECK_EQ(cards.size(), ct.arguments[3].values.size());
699+
const bool is_closed = Eval(ct.arguments[4], evaluator) != 0;
725700
for (int i = 0; i < cards.size(); ++i) {
726701
const int64_t card = cards[i];
727702
if (card < ct.arguments[2].values[i] || card > ct.arguments[3].values[i]) {
728703
return false;
729704
}
730705
}
731-
int64_t sum_of_cards = 0;
732-
for (int64_t card : cards) {
733-
sum_of_cards += card;
734-
}
735-
return sum_of_cards == Length(ct.arguments[0]);
736-
}
737706

738-
bool CheckGlobalCardinalityOld(
739-
const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator,
740-
const std::function<std::vector<int64_t>(Variable*)>& set_evaluator) {
741-
const int size = Length(ct.arguments[1]);
742-
std::vector<int64_t> cards(size, 0);
743-
for (int i = 0; i < Length(ct.arguments[0]); ++i) {
744-
const int64_t value = EvalAt(ct.arguments[0], i, evaluator);
745-
if (value >= 0 && value < size) {
746-
cards[value]++;
747-
}
748-
}
749-
for (int i = 0; i < size; ++i) {
750-
const int64_t card = EvalAt(ct.arguments[1], i, evaluator);
751-
if (card != cards[i]) {
752-
return false;
707+
if (is_closed) {
708+
int64_t sum_of_cards = 0;
709+
for (int64_t card : cards) {
710+
sum_of_cards += card;
753711
}
712+
return sum_of_cards == Length(ct.arguments[0]);
754713
}
755714
return true;
756715
}
@@ -1678,11 +1637,6 @@ CallMap CreateCallMap() {
16781637
m["fzn_diffn"] = CheckDiffn;
16791638
m["fzn_disjunctive_strict"] = CheckDisjunctiveStrict;
16801639
m["fzn_disjunctive"] = CheckDisjunctive;
1681-
m["global_cardinality_closed"] = CheckGlobalCardinalityClosed;
1682-
m["global_cardinality_low_up_closed"] = CheckGlobalCardinalityLowUpClosed;
1683-
m["global_cardinality_low_up"] = CheckGlobalCardinalityLowUp;
1684-
m["global_cardinality_old"] = CheckGlobalCardinalityOld;
1685-
m["global_cardinality"] = CheckGlobalCardinality;
16861640
m["int_abs"] = CheckIntAbs;
16871641
m["int_div"] = CheckIntDiv;
16881642
m["int_eq_imp"] = CheckIntEqImp;
@@ -1740,6 +1694,8 @@ CallMap CreateCallMap() {
17401694
m["ortools_count_eq"] = CheckOrToolsCountEq;
17411695
m["ortools_cumulative_opt"] = CheckOrToolsCumulativeOpt;
17421696
m["ortools_disjunctive_strict_opt"] = CheckOrToolsDisjunctiveStrictOpt;
1697+
m["ortools_global_cardinality_low_up"] = CheckOrToolsGlobalCardinalityLowUp;
1698+
m["ortools_global_cardinality"] = CheckOrToolsGlobalCardinality;
17431699
m["ortools_inverse"] = CheckOrToolsInverse;
17441700
m["ortools_lex_less_bool"] = CheckOrToolsLexLessInt;
17451701
m["ortools_lex_less_int"] = CheckOrToolsLexLessInt;

0 commit comments

Comments
 (0)