Actual model
| 125 | public: |
| 126 | /// Actual model |
| 127 | EFPA(const EFPAOptions& opt) |
| 128 | : Script(opt), |
| 129 | v(opt.v()), |
| 130 | q(opt.q()), |
| 131 | l(opt.l()), |
| 132 | d(opt.d()), |
| 133 | n(q*l), |
| 134 | nseqpair((v*(v-1))/2), |
| 135 | c(*this, n*v, 1,q), |
| 136 | diff(*this, n*nseqpair, 0, 1) |
| 137 | { |
| 138 | // Matrix access |
| 139 | // q*lambda=n columns, and v rows |
| 140 | Matrix<IntVarArray> cm(c, n, v); |
| 141 | // q*lambda=n columns, and nseqpair rows |
| 142 | Matrix<BoolVarArray> diffm(diff, n, nseqpair); |
| 143 | |
| 144 | // Counting symbols in rows |
| 145 | { |
| 146 | IntArgs values(q); |
| 147 | for (int i = q; i--; ) values[i] = i+1; |
| 148 | IntSet cardinality(l, l); |
| 149 | for (int i = v; i--; ) |
| 150 | count(*this, cm.row(i), cardinality, values, opt.ipl()); |
| 151 | } |
| 152 | |
| 153 | // Difference variables |
| 154 | { |
| 155 | int nseqi = 0; |
| 156 | for (int a = 0; a < v; ++a) { |
| 157 | for (int b = a+1; b < v; ++b) { |
| 158 | for (int i = n; i--; ) { |
| 159 | rel(*this, cm(i, a), IRT_NQ, cm(i, b), diffm(i, nseqi)); |
| 160 | } |
| 161 | ++nseqi; |
| 162 | } |
| 163 | } |
| 164 | assert(nseqi == nseqpair); |
| 165 | } |
| 166 | |
| 167 | // Counting the Hamming difference |
| 168 | { |
| 169 | for (int i = nseqpair; i--; ) { |
| 170 | linear(*this, diffm.row(i), IRT_EQ, d); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | // Symmetry breaking |
| 175 | if (opt.symmetry()) { |
| 176 | IntRelType row_less = d==0 ? IRT_EQ : IRT_LE; |
| 177 | // order rows |
| 178 | for (int r = 0; r<v-1; ++r) { |
| 179 | rel(*this, cm.row(r), row_less, cm.row(r+1)); |
| 180 | } |
| 181 | // order columns |
| 182 | for (int c = 0; c<n-1; ++c) { |
| 183 | rel(*this, cm.col(c), IRT_LQ, cm.col(c+1)); |
| 184 | } |
nothing calls this directly
no test coverage detected