Timetabler
constraint_encoder.cpp
1 #include "constraint_encoder.h"
2 
3 #include <cassert>
4 #include <iostream>
5 #include <vector>
6 #include "cclause.h"
7 #include "clauses.h"
8 #include "core/SolverTypes.h"
9 #include "global.h"
10 #include "timetabler.h"
11 
12 using namespace NSPACE;
13 
20  this->timetabler = timetabler;
21  this->vars = timetabler->data.fieldValueVars;
22 }
23 
39  FieldType fieldType) {
40  Clauses result;
41  for (unsigned i = 0; i < vars[course1][fieldType].size(); i++) {
42  CClause field1, field2;
43  field1.createLitAndAdd(vars[course1][fieldType][i]);
44  field2.createLitAndAdd(vars[course2][fieldType][i]);
45  Clauses conjunction(field1 & field2);
46  if (i == 0)
47  result = conjunction;
48  else
49  result = result | conjunction;
50  }
51  return result;
52 }
53 
69  int course2,
70  FieldType fieldType) {
71  Clauses result;
72  for (unsigned i = 0; i < vars[course1][fieldType].size(); i++) {
73  CClause resultClause;
74  resultClause.addLits(~mkLit(vars[course1][fieldType][i], false));
75  resultClause.addLits(~mkLit(vars[course2][fieldType][i], false));
76  result.addClauses(resultClause);
77  }
78  return result;
79 }
80 
90 Clauses ConstraintEncoder::hasCommonProgram(int course1, int course2) {
91  Clauses result;
92  for (unsigned i = 0; i < vars[course1][FieldType::program].size(); i++) {
93  if (timetabler->data.programs[i].isCoreProgram()) {
94  CClause field1, field2;
95  field1.createLitAndAdd(vars[course1][FieldType::program][i]);
96  field2.createLitAndAdd(vars[course2][FieldType::program][i]);
97  Clauses conjunction(field1 & field2);
98  if (i == 0)
99  result = conjunction;
100  else
101  result = result | conjunction;
102  }
103  }
104  return result;
105 }
106 
120  Clauses result;
121  for (unsigned i = 0; i < vars[course1][FieldType::program].size(); i++) {
122  if (timetabler->data.programs[i].isCoreProgram()) {
123  CClause resultClause;
124  resultClause.addLits(~mkLit(vars[course1][FieldType::program][i], false));
125  resultClause.addLits(~mkLit(vars[course2][FieldType::program][i], false));
126  result.addClauses(resultClause);
127  }
128  }
129  return result;
130 }
131 
145  Clauses notSegmentIntersecting =
146  Clauses(notIntersectingTimeField(course1, course2, FieldType::segment));
147  Clauses notSlotIntersecting =
148  Clauses(notIntersectingTimeField(course1, course2, FieldType::slot));
149  return (notSegmentIntersecting | notSlotIntersecting);
150 }
151 
164  FieldType fieldType) {
165  assert(fieldType == FieldType::segment || fieldType == FieldType::slot);
166  assert(vars[course1][fieldType].size() == vars[course2][fieldType].size());
167  assert(course1 != course2);
168  Clauses result;
169  for (unsigned i = 0; i < vars[course1][fieldType].size(); i++) {
170  Clauses hasFieldValue1(vars[course1][fieldType][i]);
171  Clauses notIntersecting1;
172  for (unsigned j = 0; j < vars[course1][fieldType].size(); j++) {
173  if ((fieldType == FieldType::segment &&
174  timetabler->data.segments[i].isIntersecting(
175  timetabler->data.segments[j])) ||
176  (fieldType == FieldType::slot &&
177  timetabler->data.slots[i].isIntersecting(
178  timetabler->data.slots[j]))) {
179  notIntersecting1.addClauses(~Clauses(vars[course2][fieldType][j]));
180  }
181  }
182  result.addClauses(hasFieldValue1 >> notIntersecting1);
183  }
184  return result;
185 }
186 
200  FieldType fieldType) {
201  Clauses atLeastOne = Clauses(hasAtLeastOneFieldValueTrue(course, fieldType));
202  Clauses atMostOne = Clauses(hasAtMostOneFieldValueTrue(course, fieldType));
203  return (atLeastOne & atMostOne);
204 }
205 
216  FieldType fieldType) {
217  std::vector<Var> varsToUse = getAllowedVars(course, fieldType);
218  CClause resultClause;
219  for (unsigned i = 0; i < varsToUse.size(); i++) {
220  resultClause.createLitAndAdd(varsToUse[i]);
221  }
222  Clauses result(resultClause);
223  return result;
224 }
225 
243  FieldType fieldType) {
244  std::vector<Var> varsToUse = getAllowedVars(course, fieldType);
245  Clauses result;
246  for (unsigned i = 0; i < vars[course][fieldType].size(); i++) {
247  for (unsigned j = i + 1; j < vars[course][fieldType].size(); j++) {
248  Clauses first(vars[course][fieldType][i]);
249  Clauses second(vars[course][fieldType][j]);
250  Clauses negSecond = ~second;
251  result.addClauses(~first | negSecond);
252  }
253  }
254  return result;
255 }
256 
271 std::vector<Var> ConstraintEncoder::getAllowedVars(int course,
272  FieldType fieldType) {
273  std::vector<Var> varsToUse;
274  varsToUse.clear();
275  if (fieldType != FieldType::classroom) {
276  varsToUse = vars[course][fieldType];
277  } else {
278  for (unsigned i = 0; i < vars[course][fieldType].size(); i++) {
279  if (timetabler->data.courses[course].getClassSize() <=
280  timetabler->data.classrooms[i].getSize()) {
281  varsToUse.push_back(vars[course][fieldType][i]);
282  }
283  }
284  }
285  return varsToUse;
286 }
287 
297  Clauses result(vars[course][FieldType::isMinor]
298  [static_cast<unsigned>(MinorType::isMinorCourse)]);
299  return result;
300 }
301 
311  CClause resultClause;
312  for (unsigned i = 0; i < vars[course][FieldType::slot].size(); i++) {
313  if (timetabler->data.slots[i].isMinorSlot()) {
314  resultClause.createLitAndAdd(vars[course][FieldType::slot][i]);
315  }
316  }
317  Clauses result(resultClause);
318  return result;
319 }
320 
329  CClause resultClause;
330  for (unsigned i = 0; i < vars[course][FieldType::program].size(); i++) {
331  if (timetabler->data.programs[i].isCoreProgram()) {
332  resultClause.createLitAndAdd(vars[course][FieldType::program][i]);
333  }
334  }
335  Clauses result(resultClause);
336  return result;
337 }
338 
347  CClause resultClause;
348  for (unsigned i = 0; i < vars[course][FieldType::program].size(); i++) {
349  if (!(timetabler->data.programs[i].isCoreProgram())) {
350  resultClause.createLitAndAdd(vars[course][FieldType::program][i]);
351  }
352  }
353  Clauses result(resultClause);
354  return result;
355 }
356 
366  CClause resultClause;
367  for (unsigned i = 0; i < vars[course][FieldType::slot].size(); i++) {
368  if (timetabler->data.slots[i].isMorningSlot()) {
369  resultClause.createLitAndAdd(vars[course][FieldType::slot][i]);
370  }
371  }
372  Clauses result(resultClause);
373  return result;
374 }
375 
386  Clauses result;
387  for (unsigned i = 0; i < vars[course][FieldType::program].size(); i += 2) {
388  CClause resultClause;
389  resultClause.addLits(~mkLit(vars[course][FieldType::program][i], false));
390  resultClause.addLits(
391  ~mkLit(vars[course][FieldType::program][i + 1], false));
392  result.addClauses(resultClause);
393  }
394  return result;
395 }
396 
411  int course, FieldType fieldType, std::vector<int> indexList) {
412  CClause resultClause;
413  for (unsigned i = 0; i < indexList.size(); i++) {
414  resultClause.createLitAndAdd(vars[course][fieldType][indexList[i]]);
415  }
416  Clauses result(resultClause);
417  return result;
418 }
Class for representing a clause.
Definition: cclause.h:21
void createLitAndAdd(const Var &)
Creates a Lit, a literal, given a variable, a Var, and adds it to the clause.
Definition: cclause.cpp:213
Clauses isCoreCourse(int)
Gives Clauses that represent that a Course is a core Course.
std::vector< Segment > segments
Definition: data.h:52
Clauses hasSameFieldTypeAndValue(int, int, FieldType)
Gives Clauses that represent that a pair of courses have the same field value for a given FieldType...
std::vector< Classroom > classrooms
Definition: data.h:44
std::vector< Slot > slots
Definition: data.h:56
Clauses programAtMostOneOfCoreOrElective(int)
Gives Clauses that represent that for a Course, it can be a part of a Program as at most one out of c...
Clauses isMinorCourse(int)
Gives Clauses that represent that a given Course is a minor Course.
Class for time tabler.
Definition: timetabler.h:44
Clauses slotInMinorTime(int)
Gives Clauses that represent that a given Course must have a minor Slot.
Clauses notIntersectingTimeField(int, int, FieldType)
Gives Clauses that represent that a pair of courses cannot have an intersecting value for a given Fie...
Clauses hasExactlyOneFieldValueTrue(int, FieldType)
Gives Clauses that represent that a Course can have exactly one field value of a given FieldType to b...
Clauses hasCommonProgram(int, int)
Gives Clauses that represent that a pair of courses are core for a given Program. ...
Clauses hasFieldTypeListedValues(int, FieldType, std::vector< int >)
Gives Clauses that represent that a Course has a field value for a given FieldType out of a list of p...
Clauses courseInMorningTime(int)
Gives Clauses that represent that a Course is scheduled in a morning Slot.
Timetabler * timetabler
Definition: main.cpp:90
FieldType
Enum that represents all the field types.
Definition: global.h:9
Clauses isElectiveCourse(int)
Gives Clauses that represent that a Course is an elective Course.
void addClauses(const CClause &)
Adds a CClause to the set of clauses.
Definition: clauses.cpp:238
std::vector< Course > courses
Definition: data.h:36
void addLits(const Lit &)
Adds a Lit, a literal, to the clause.
Definition: cclause.cpp:251
Clauses hasSameFieldTypeNotSameValue(int, int, FieldType)
Gives Clauses that represent that a pair of courses do not have the same field value for a given Fiel...
Clauses hasNoCommonCoreProgram(int, int)
Gives Clauses that represent that at least one out of a pair of courses is not core for a given Progr...
Class for representing a set of clauses.
Definition: clauses.h:23
Clauses notIntersectingTime(int, int)
Gives Clauses that represent that a pair of courses cannot have an intersecting schedule.
ConstraintEncoder(Timetabler *)
Constructs the ConstraintEncoder object.
Data data
Definition: timetabler.h:63
std::vector< Program > programs
Definition: data.h:48
std::vector< std::vector< std::vector< Var > > > fieldValueVars
Definition: data.h:73
Clauses hasAtLeastOneFieldValueTrue(int, FieldType)
Gives Clauses that represent that a Course can have at least one field value of a given FieldType to ...
Clauses hasAtMostOneFieldValueTrue(int, FieldType)
Gives Clauses that represent that a Course can have at most one field value of a given FieldType to b...