20 YAML::Node config = YAML::LoadFile(file);
22 YAML::Node instructorsConfig = config[
"instructors"];
23 for (YAML::Node instructorNode : instructorsConfig) {
24 Instructor instructor(instructorNode.as<std::string>());
28 YAML::Node classroomsConfig = config[
"classrooms"];
29 for (YAML::Node classroomNode : classroomsConfig) {
30 Classroom classroom(classroomNode[
"number"].as<std::string>(),
31 classroomNode[
"size"].as<unsigned>());
35 YAML::Node segmentsConfig = config[
"segments"];
36 unsigned segmentStart = segmentsConfig[
"start"].as<
unsigned>();
37 unsigned segmentEnd = segmentsConfig[
"end"].as<
unsigned>();
38 for (
unsigned i = segmentStart; i <= segmentEnd; ++i) {
39 for (
unsigned j = i; j <= segmentEnd; ++j) {
44 YAML::Node slotsConfig = config[
"slots"];
45 for (YAML::Node slotNode : slotsConfig) {
46 std::vector<SlotElement> slotElements;
47 IsMinor isMinor = (slotNode[
"is_minor"].as<
bool>())
50 for (YAML::Node periodNode : slotNode[
"time_periods"]) {
51 Time start(periodNode[
"start"].as<std::string>());
52 Time end(periodNode[
"end"].as<std::string>());
53 Day day = getDayFromString(periodNode[
"day"].as<std::string>());
54 slotElements.push_back(
SlotElement(start, end, day));
57 Slot(slotNode[
"name"].as<std::string>(), isMinor, slotElements));
63 YAML::Node programsConfig = config[
"programs"];
64 for (YAML::Node programNode : programsConfig) {
65 std::string name = programNode.as<std::string>();
70 YAML::Node weightsConfig = config[
"weights"];
72 weightsConfig[
"instructor"][0].as<
int>();
74 2 * weightsConfig[
"instructor"][1].as<
int>();
76 weightsConfig[
"segment"][0].as<
int>();
78 2 * weightsConfig[
"segment"][1].as<
int>();
80 weightsConfig[
"is_minor"][0].as<
int>();
82 2 * weightsConfig[
"is_minor"][1].as<
int>();
84 weightsConfig[
"program"].as<
int>();
86 weightsConfig[
"classroom"][0].as<
int>();
88 2 * weightsConfig[
"classroom"][1].as<
int>();
90 weightsConfig[
"slot"][0].as<
int>();
92 2 * weightsConfig[
"slot"][1].as<
int>();
94 YAML::Node predefinedWeightsConfig = config[
"predefined_weights"];
95 for (YAML::Node predefinedWeightNode : predefinedWeightsConfig) {
96 unsigned clauseNo = predefinedWeightNode[
"clause"].as<
int>();
97 int weight = predefinedWeightNode[
"weight"].as<
int>();
112 Day Parser::getDayFromString(std::string day) {
113 if (day ==
"Monday")
return Day::Monday;
114 if (day ==
"Tuesday")
return Day::Tuesday;
115 if (day ==
"Wednesday")
return Day::Wednesday;
116 if (day ==
"Thursday")
return Day::Thursday;
117 if (day ==
"Friday")
return Day::Friday;
118 if (day ==
"Saturday")
return Day::Saturday;
119 if (day ==
"Sunday")
return Day::Sunday;
120 assert(
false &&
"Incorrect day");
130 csv::Parser parser(file);
132 for (
unsigned i = 0; i < parser.rowCount(); ++i) {
135 std::string name = parser[i][
"name"];
136 std::string classSizeStr = parser[i][
"class_size"];
137 unsigned classSize = unsigned(std::stoi(classSizeStr));
139 std::string instructorStr = parser[i][
"instructor"];
144 assignmentsThisCourse[FieldType::instructor].push_back(l_True);
147 assignmentsThisCourse[FieldType::instructor].push_back(l_False);
149 if (instructor == -1) {
150 LOG(ERROR) <<
"Input contains invalid Instructor name";
152 std::string segmentStr = parser[i][
"segment"];
157 assignmentsThisCourse[FieldType::segment].push_back(l_True);
160 assignmentsThisCourse[FieldType::segment].push_back(l_False);
163 LOG(ERROR) <<
"Input contains invalid Segment name";
165 std::string isMinorStr = parser[i][
"is_minor"];
167 if (isMinorStr ==
"Yes" || isMinorStr ==
"Y") {
169 assignmentsThisCourse[FieldType::isMinor].push_back(l_True);
170 }
else if (isMinorStr ==
"No" || isMinorStr ==
"N" || isMinorStr ==
"") {
172 assignmentsThisCourse[FieldType::isMinor].push_back(l_False);
174 LOG(ERROR) <<
"Input contains invalid IsMinor value (should be " 177 Course course(name, classSize, instructor, segment, isMinor);
181 if (parser[i][s] ==
"Core" || parser[i][s] ==
"C" ||
182 parser[i][s] ==
"Y") {
184 assignmentsThisCourse[FieldType::program].push_back(l_True);
185 assignmentsThisCourse[FieldType::program].push_back(l_False);
186 }
else if (parser[i][s] ==
"Elective" || parser[i][s] ==
"E") {
188 assignmentsThisCourse[FieldType::program].push_back(l_False);
189 assignmentsThisCourse[FieldType::program].push_back(l_True);
190 }
else if (parser[i][s] ==
"No" || parser[i][s] ==
"N" ||
191 parser[i][s] ==
"") {
192 assignmentsThisCourse[FieldType::program].push_back(l_False);
193 assignmentsThisCourse[FieldType::program].push_back(l_False);
195 LOG(ERROR) <<
"Input contains invalid Program type (should be " 196 "'Core', 'Elective', or 'No')";
200 std::string classroomStr = parser[i][
"classroom"];
201 std::string slotStr = parser[i][
"slot"];
202 bool foundClassroom =
false;
203 bool foundSlot =
false;
204 assignmentsThisCourse[FieldType::classroom].resize(
208 if (classroomStr !=
"") {
211 assignmentsThisCourse[FieldType::classroom][j] = l_True;
212 foundClassroom =
true;
216 assignmentsThisCourse[FieldType::classroom][j] = l_False;
218 if (!foundClassroom) {
219 LOG(ERROR) <<
"Input contains invalid Classroom name";
225 assignmentsThisCourse[FieldType::slot][j] = l_True;
230 assignmentsThisCourse[FieldType::slot][j] = l_False;
233 LOG(ERROR) <<
"Input contains invalid Slot name";
250 course1.getSlot() != -1) {
253 [PredefinedClauses::minorInMinorTime] != 0) {
256 <<
" which is minor course is scheduled in non minor slot.";
259 [PredefinedClauses::minorInMinorTime] == -1) {
260 LOG(WARNING) <<
"Hard constraint unsatisfied";
267 if (course1.getName() == course2.getName())
continue;
268 bool segementIntersecting =
271 bool classroomSame = (course1.getClassroom() != -1 &&
272 course1.getClassroom() == course2.getClassroom());
276 bool slotIntersecting =
277 (course1.getSlot() != -1 && course2.getSlot() != -1)
281 if (segementIntersecting && slotIntersecting) {
282 if (course1.getInstructor() == course2.getInstructor()) {
284 [PredefinedClauses::instructorSingleCourseAtATime] != 0) {
285 LOG(WARNING) << course1.getName() <<
" and " << course2.getName()
286 <<
" having same instructor clash.";
289 [PredefinedClauses::instructorSingleCourseAtATime] == -1) {
290 LOG(WARNING) <<
"Hard constraint unsatisfied";
297 [PredefinedClauses::classroomSingleCourseAtATime] != 0) {
298 LOG(WARNING) << course1.getName() <<
" and " << course2.getName()
299 <<
" having same classroom clash.";
302 [PredefinedClauses::classroomSingleCourseAtATime] == -1) {
303 LOG(WARNING) <<
"Hard constraint unsatisfied";
308 for (
auto program1 : course1.getPrograms()) {
309 for (
auto program2 : course2.getPrograms()) {
310 if (program1 == program2) {
314 [PredefinedClauses::programSingleCoreCourseAtATime] !=
317 << course1.getName() <<
" and " << course2.getName()
318 <<
" which have common core program " 323 [PredefinedClauses::programSingleCoreCourseAtATime] ==
325 LOG(WARNING) <<
"Hard constraint unsatisfied";
344 std::vector<std::vector<Var>> courseVars;
348 courseVars[FieldType::classroom].push_back(v);
352 courseVars[FieldType::instructor].push_back(v);
356 courseVars[FieldType::isMinor].push_back(v);
360 courseVars[FieldType::program].push_back(v);
364 courseVars[FieldType::segment].push_back(v);
368 courseVars[FieldType::slot].push_back(v);
372 std::vector<Var> highLevelCourseVars;
375 highLevelCourseVars.push_back(v);
383 if (i == PredefinedClauses::instructorSingleCourseAtATime ||
384 i == PredefinedClauses::classroomSingleCourseAtATime ||
385 i == PredefinedClauses::programSingleCoreCourseAtATime) {
std::vector< int > predefinedClausesWeights
Class for a slot element.
std::vector< Segment > segments
void addClassroom(int)
Adds a classroom that is applicable to the Course.
std::vector< int > highLevelVarWeights
void addProgram(int)
Adds a program that is applicable to the Course.
std::vector< Classroom > classrooms
std::vector< Slot > slots
std::vector< IsMinor > isMinors
Day
Enum Class to represent a day of the week.
std::vector< Instructor > instructors
std::vector< std::vector< Var > > predefinedConstraintVars
std::vector< int > existingAssignmentWeights
MinorType
Enum to represent the types of "Is Minor".
void parseFields(std::string file)
Parse the fields given in a file.
void parseInput(std::string file)
Parses the input given in a file.
std::vector< std::vector< std::vector< lbool > > > existingAssignmentVars
void addSlot(int)
Adds a slot that is applicable to the Course.
std::vector< Course > courses
static const int PREDEFINED_CLAUSES_COUNT
bool verify()
Verifies if the input is valid.
std::vector< std::vector< Var > > highLevelVars
void addVars()
Requests for variables to be added to the solver and stores the data.
static const int FIELD_COUNT
Parser(Timetabler *)
Constructs the Parser object.
std::vector< Program > programs
std::vector< std::vector< std::vector< Var > > > fieldValueVars