Post constraints
| 78 | }; |
| 79 | /// Post constraints |
| 80 | MagicSquare(const SizeOptions& opt) |
| 81 | : Script(opt), spec(specs[opt.size()]), |
| 82 | n_filled(spec[1]), n(spec[0]), x(*this,n*n,1,n*n) { |
| 83 | // Number of fields on square |
| 84 | const int nn = n*n; |
| 85 | |
| 86 | // Sum of all a row, column, or diagonal |
| 87 | const int s = nn*(nn+1) / (2*n); |
| 88 | |
| 89 | // Matrix-wrapper for the square |
| 90 | Matrix<IntVarArray> m(x, n, n); |
| 91 | |
| 92 | for (int i=0; i<n_filled; i++) { |
| 93 | int row, col, num; |
| 94 | { |
| 95 | int idx = 3 * i + 2; |
| 96 | row = spec[idx] - 1; |
| 97 | col = spec[idx + 1] - 1; |
| 98 | num = spec[idx + 2]; |
| 99 | } |
| 100 | rel(*this, m(col,row), IRT_EQ, num); |
| 101 | } |
| 102 | |
| 103 | for (int i = n; i--; ) { |
| 104 | linear(*this, m.row(i), IRT_EQ, s, opt.ipl()); |
| 105 | linear(*this, m.col(i), IRT_EQ, s, opt.ipl()); |
| 106 | } |
| 107 | // Both diagonals must have sum s |
| 108 | { |
| 109 | IntVarArgs d1y(n); |
| 110 | IntVarArgs d2y(n); |
| 111 | for (int i = n; i--; ) { |
| 112 | d1y[i] = m(i,i); |
| 113 | d2y[i] = m(n-i-1,i); |
| 114 | } |
| 115 | linear(*this, d1y, IRT_EQ, s, opt.ipl()); |
| 116 | linear(*this, d2y, IRT_EQ, s, opt.ipl()); |
| 117 | } |
| 118 | |
| 119 | // All fields must be distinct |
| 120 | distinct(*this, x, opt.ipl()); |
| 121 | |
| 122 | switch (opt.branching()) { |
| 123 | case BRANCH_CBS_MAX_SD: |
| 124 | #ifdef GECODE_HAS_CBS |
| 125 | cbsbranch(*this, x); |
| 126 | #endif |
| 127 | case BRANCH_SIZE: |
| 128 | branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_SPLIT_MIN()); |
| 129 | break; |
| 130 | case BRANCH_AFC_SIZE: |
| 131 | branch(*this, x, INT_VAR_AFC_SIZE_MAX(opt.decay()), INT_VAL_SPLIT_MIN()); |
| 132 | break; |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | /// Constructor for cloning \a s |
| 137 | MagicSquare(MagicSquare& s) |
nothing calls this directly
no test coverage detected