Actual model
| 105 | |
| 106 | /// Actual model |
| 107 | BIBD(const BIBDOptions& o) |
| 108 | : Script(o), opt(o), _p(*this,opt.v*opt.b,0,1) { |
| 109 | Matrix<BoolVarArray> p(_p,opt.b,opt.v); |
| 110 | |
| 111 | // r ones per row |
| 112 | for (int i=0; i<opt.v; i++) |
| 113 | linear(*this, p.row(i), IRT_EQ, opt.r); |
| 114 | |
| 115 | // k ones per column |
| 116 | for (int j=0; j<opt.b; j++) |
| 117 | linear(*this, p.col(j), IRT_EQ, opt.k); |
| 118 | |
| 119 | // Exactly lambda ones in scalar product between two different rows |
| 120 | for (int i1=0; i1<opt.v; i1++) |
| 121 | for (int i2=i1+1; i2<opt.v; i2++) { |
| 122 | BoolVarArgs row(opt.b); |
| 123 | for (int j=0; j<opt.b; j++) |
| 124 | row[j] = expr(*this, p(j,i1) && p(j,i2)); |
| 125 | linear(*this, row, IRT_EQ, opt.lambda); |
| 126 | } |
| 127 | |
| 128 | if (opt.symmetry() == SYMMETRY_LDSB) { |
| 129 | Symmetries s; |
| 130 | s << rows_interchange(p); |
| 131 | s << columns_interchange(p); |
| 132 | branch(*this, _p, BOOL_VAR_NONE(), BOOL_VAL_MIN(), s); |
| 133 | } else { |
| 134 | if (opt.symmetry() == SYMMETRY_LEX) { |
| 135 | for (int i=1; i<opt.v; i++) |
| 136 | rel(*this, p.row(i-1), IRT_GQ, p.row(i)); |
| 137 | for (int j=1; j<opt.b; j++) |
| 138 | rel(*this, p.col(j-1), IRT_GQ, p.col(j)); |
| 139 | } |
| 140 | branch(*this, _p, BOOL_VAR_NONE(), BOOL_VAL_MIN()); |
| 141 | } |
| 142 | |
| 143 | } |
| 144 | |
| 145 | /// Print solution |
| 146 | virtual void |
nothing calls this directly
no test coverage detected