Actual model
| 117 | |
| 118 | /// Actual model |
| 119 | BACP(const SizeOptions& opt) |
| 120 | : IntMinimizeScript(opt), curr(curriculum[opt.size()]) { |
| 121 | std::map<std::string, int> courseMap; // Map names to course numbers |
| 122 | int maxCredit = 0; |
| 123 | int numberOfCourses = 0; |
| 124 | for (const Course* co=curr.courses; co->name != 0; co++) { |
| 125 | courseMap[co->name] = numberOfCourses++; |
| 126 | maxCredit += co->credit; |
| 127 | } |
| 128 | |
| 129 | int p = curr.p; |
| 130 | int a = curr.a; |
| 131 | int b = curr.b; |
| 132 | int c = curr.c; |
| 133 | int d = curr.d; |
| 134 | |
| 135 | l = IntVarArray(*this, p, a, b); |
| 136 | u = IntVar(*this, 0, maxCredit); |
| 137 | q = IntVarArray(*this, p, c, d); |
| 138 | x = IntVarArray(*this, numberOfCourses, 0, p-1); |
| 139 | |
| 140 | for (int j=0; j<p; j++) { |
| 141 | BoolVarArgs xij(*this, numberOfCourses, 0, 1); |
| 142 | IntArgs t(numberOfCourses); |
| 143 | for (int i=0; i<numberOfCourses; i++) { |
| 144 | rel(*this, (x[i]==j) == xij[i]); |
| 145 | t[i] = curr.courses[i].credit; |
| 146 | } |
| 147 | // sum over all t*(xi==j) is load of period i |
| 148 | linear(*this, t, xij, IRT_EQ, l[j]); |
| 149 | // sum over all (xi==j) is number of courses in period i |
| 150 | linear(*this, xij, IRT_EQ, q[j]); |
| 151 | } |
| 152 | |
| 153 | // Precedence |
| 154 | for (const char** prereq = curr.prereqs; *prereq != 0; prereq+=2) |
| 155 | rel(*this, x[courseMap[*prereq]] < x[courseMap[*(prereq+1)]]); |
| 156 | |
| 157 | // Optimization criterion: minimize u |
| 158 | max(*this, l, u); |
| 159 | |
| 160 | // Redundant constraints |
| 161 | linear(*this, l, IRT_EQ, maxCredit); |
| 162 | linear(*this, q, IRT_EQ, numberOfCourses); |
| 163 | |
| 164 | switch (opt.branching()) { |
| 165 | case BRANCHING_NAIVE: |
| 166 | branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN()); |
| 167 | break; |
| 168 | case BRANCHING_LOAD: |
| 169 | branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL(&load)); |
| 170 | break; |
| 171 | case BRANCHING_LOAD_REV: |
| 172 | branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL(&load_rev)); |
| 173 | break; |
| 174 | } |
| 175 | } |
| 176 | /// Value selection function for load branching |
nothing calls this directly
no test coverage detected