| 57 | */ |
| 58 | template<class Card> |
| 59 | ExecStatus |
| 60 | postSideConstraints(Home home, ViewArray<IntView>& x, ViewArray<Card>& k) { |
| 61 | CardLess<Card> cl; |
| 62 | Support::quicksort(&k[0], k.size(), cl); |
| 63 | Region r; |
| 64 | |
| 65 | { |
| 66 | int smin = 0; |
| 67 | int smax = 0; |
| 68 | for (int i = k.size(); i--; ) { |
| 69 | GECODE_ME_CHECK((k[i].gq(home, 0))); |
| 70 | GECODE_ME_CHECK((k[i].lq(home, x.size()))); |
| 71 | smin += k[i].min(); |
| 72 | smax += k[i].max(); |
| 73 | } |
| 74 | |
| 75 | // not enough variables to satisfy min req |
| 76 | if ((x.size() < smin) || (smax < x.size())) |
| 77 | return ES_FAILED; |
| 78 | } |
| 79 | |
| 80 | // Remove all values from the x that are not in v |
| 81 | { |
| 82 | int* v = r.alloc<int>(k.size()); |
| 83 | for (int i=k.size(); i--;) |
| 84 | v[i]=k[i].card(); |
| 85 | Support::quicksort(v,k.size()); |
| 86 | for (int i=x.size(); i--; ) { |
| 87 | Iter::Values::Array iv(v,k.size()); |
| 88 | GECODE_ME_CHECK(x[i].inter_v(home, iv, false)); |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | // Remove all values with 0 max occurrence |
| 93 | // and remove corresponding occurrence variables from k |
| 94 | { |
| 95 | // The number of zeroes |
| 96 | int n_z = 0; |
| 97 | for (int i=k.size(); i--;) |
| 98 | if (k[i].max() == 0) |
| 99 | n_z++; |
| 100 | |
| 101 | if (n_z > 0) { |
| 102 | int* z = r.alloc<int>(n_z); |
| 103 | n_z = 0; |
| 104 | int n_k = 0; |
| 105 | for (int i=0; i<k.size(); i++) |
| 106 | if (k[i].max() == 0) { |
| 107 | z[n_z++] = k[i].card(); |
| 108 | } else { |
| 109 | k[n_k++] = k[i]; |
| 110 | } |
| 111 | k.size(n_k); |
| 112 | Support::quicksort(z,n_z); |
| 113 | for (int i=x.size(); i--;) { |
| 114 | Iter::Values::Array zi(z,n_z); |
| 115 | GECODE_ME_CHECK(x[i].minus_v(home,zi,false)); |
| 116 | } |