private List <ExamEntity> normalArrange(CourseEntity ce, List <SessionEntity> remainSessions, TimeValueInterval timeData) { List <ExamEntity> ret = new List <ExamEntity>(); int sessionCt = remainSessions.Count; int sessionIndex = 0; foreach (RoomEntity r in allRoom) { if (r.roomType == ce.requiredRoomType && getConflictTimeData(r.occupied, timeData) == null) { ExamEntity entity = new ExamEntity(); entity.courseId = ce.courseId; entity.roomId = r.roomId; entity.roomType = r.roomType; entity.startMinute = TimeValueInterval.value2Min(timeData.startValue); entity.startHour = TimeValueInterval.value2Hour(timeData.startValue); entity.weekDay = TimeValueInterval.value2Weekday(timeData.startValue); entity.endMinute = TimeValueInterval.value2Min(timeData.endValue); entity.endHour = TimeValueInterval.value2Hour(timeData.endValue); r.arrangeExam(timeData); // Jane: added null check 20180426 if (allLevelTimeLine[ce.level] != null) if (allLevelTimeLine[ce.level] != null) { allLevelTimeLine[ce.level].Add(timeData); } int sessionsThisRoom = r.roomCapacity / SESSION_CAPACITY; for (int i = 0; i < sessionsThisRoom; ++i, ++sessionIndex) { if (sessionIndex >= remainSessions.Count) { break; } entity.sessionIds.Add(remainSessions[sessionIndex]); //if (protorId <= 0) protorId = remainSessions[sessionIndex].facultyId; } bool hasProtor = false; ProtorEntity sessionFaculty = null; foreach (SessionEntity se in entity.sessionIds) { int protorId = se.facultyId; foreach (ProtorEntity pe in allProtor) { if (pe.protorId == protorId) { sessionFaculty = pe; break; } } if (sessionFaculty != null) { if (getConflictTimeData(sessionFaculty.occupied, timeData) == null) { entity.protorId = sessionFaculty.protorId; sessionFaculty.arrangeExam(timeData); hasProtor = true; break; } } } if (!hasProtor) { bool valid = true; foreach (ProtorEntity pe in allProtor) { valid = true; foreach (SessionEntity ss in ce.sessionIds) { if (pe.protorId == ss.sessionId && pe.protorId > 0) { valid = false; break; } } if (!valid) { continue; } if (getConflictTimeData(pe.occupied, timeData) == null) { entity.protorId = pe.protorId; pe.arrangeExam(timeData); break; } } Console.WriteLine("DOES NOT use teacher as protor!!!"); } ret.Add(entity); } if (sessionCt <= sessionIndex) { break; } } remainSessions.Clear(); return(ret); }
private ExamEntity specialArrange(CourseEntity course, SpecialEntity special, TimeValueInterval timeData, List <SessionEntity> remainSessions, List <SpecialEntity> specialsOfThisCourse) { int sessionCt = remainSessions.Count; int sessionIndex = 0; RoomEntity room = null; foreach (RoomEntity r in allRoom) { if (special.roomId > 0) { if (r.roomId == special.roomId) { room = r; break; } } else { if (r.roomType == course.requiredRoomType && getConflictTimeData(r.occupied, timeData) == null) { room = r; foreach (SpecialEntity sot in specialsOfThisCourse) { if (sot.roomId <= 0) { continue; } if (r.roomId == sot.roomId) { room = null; break; } } if (room != null) { break; } } } } if (room == null) { return(null); } bool hasSpecialProtor = special.protorId > 0; ExamEntity exam = new ExamEntity(); exam.courseId = special.courseId; exam.roomId = special.roomId; exam.roomType = room.roomType; exam.startMinute = TimeValueInterval.value2Min(timeData.startValue); exam.startHour = TimeValueInterval.value2Hour(timeData.startValue); exam.weekDay = TimeValueInterval.value2Weekday(timeData.startValue); exam.endMinute = TimeValueInterval.value2Min(timeData.endValue); exam.endHour = TimeValueInterval.value2Hour(timeData.endValue); int sessionsThisRoom = room.roomCapacity / SESSION_CAPACITY; if (special.sessionId > 0) { SessionEntity target = null; foreach (SessionEntity s in remainSessions) { if (s.sessionId == special.sessionId) { target = s; break; } } if (target != null) { exam.sessionIds.Add(target); remainSessions.Remove(target); } --sessionsThisRoom; } for (int i = 0; i < sessionsThisRoom; ++sessionIndex) { if (sessionIndex >= remainSessions.Count) { break; } bool sessionInSpecial = false; foreach (SpecialEntity e in specialsOfThisCourse) { if (e.courseId == course.courseId && e.roomId != room.roomId && e.sessionId == remainSessions[sessionIndex].sessionId) { sessionInSpecial = true; break; } } if (!sessionInSpecial) { exam.sessionIds.Add(remainSessions[sessionIndex]); ++i; } } remainSessions.RemoveRange(0, sessionIndex); if (hasSpecialProtor) { exam.protorId = special.protorId; ProtorEntity pe = null; foreach (ProtorEntity p in allProtor) { if (p.protorId == special.protorId) { pe = p; break; } } if (pe != null) { pe.arrangeExam(timeData); } } else { ProtorEntity sessionFaculty = null; foreach (SessionEntity ss in exam.sessionIds) { foreach (ProtorEntity pe in allProtor) { if (ss.facultyId == pe.protorId) { sessionFaculty = pe; break; } } if (sessionFaculty != null) { if (getConflictTimeData(sessionFaculty.occupied, timeData) == null) { break; } else { sessionFaculty = null; } } } if (sessionFaculty != null) { exam.protorId = sessionFaculty.protorId; sessionFaculty.arrangeExam(timeData); } else { foreach (ProtorEntity pe in allProtor) { sessionFaculty = pe; foreach (SpecialEntity e in specialsOfThisCourse) { if (sessionFaculty.protorId == e.protorId) { sessionFaculty = null; break; } } if (sessionFaculty == null) { continue; } if (getConflictTimeData(sessionFaculty.occupied, timeData) == null && sessionFaculty.protorId != special.protorId) { exam.protorId = sessionFaculty.protorId; sessionFaculty.arrangeExam(timeData); break; } } } } room.arrangeExam(timeData); // Jane: added null check 20180426 if (allLevelTimeLine[ce.level] != null) if (allLevelTimeLine[course.level] != null) { allLevelTimeLine[course.level].Add(timeData); } return(exam); }
private TimeValueInterval getEarlistTimeData(CourseEntity ce) { TimeValueInterval earlist = getEarliest(allLevelTimeLine[ce.level], ce.duration); TimeValueInterval ret = null; int count = 0, sessionCt = ce.sessionIds.Count, roomCt = 0; for (int value = earlist.startValue; ; value += 100) { TimeValueInterval t = new TimeValueInterval(value, ce.duration); if (!t.isValid()) { continue; } count = 0; foreach (RoomEntity re in allRoom) { if (re.roomType == ce.requiredRoomType && getConflictTimeData(re.occupied, t) == null) { count += re.roomCapacity / SESSION_CAPACITY; ++roomCt; if (count >= sessionCt) { ret = t; break; } } } if (ret == null) { continue; } count = 0; foreach (SessionEntity se in ce.sessionIds) { if (se.facultyId <= 0) { continue; } ProtorEntity specialProtor = null; foreach (ProtorEntity pe in allProtor) { if (pe.protorId == se.facultyId) { specialProtor = pe; break; } } if (specialProtor != null) { if (getConflictTimeData(specialProtor.occupied, t) == null) { ++count; } else { count = -1; break; } } } if (count < 0) { continue; } if (count < roomCt) { foreach (ProtorEntity pe in allProtor) { if (getConflictTimeData(pe.occupied, t) == null) { ++count; if (count >= roomCt) { break; } } } } if (count < roomCt) { continue; } if (getConflictTimeData(allLevelTimeLine[ce.level], ret) == null) { break; } if (value >= MAX_EXAM_DAYS * 10000) { ret = null; break; } } return(ret); }
private void sortExamCourse() { foreach (course_exam ce in context.course_exam) { if (context.courses.Find(ce.course_id).is_deleted == false) { double d = ce.exam_length ?? 0; if (ce.have_final_exam.ToUpper().Equals("YES") && ce.course_id != null && ce.required_room_type_id != null && d > 0 && ce.course != null) { CourseEntity course = new CourseEntity(); course.courseId = ce.course_id ?? 0; course.requiredRoomType = ce.required_room_type_id ?? 0; course.duration = d; course.level = ce.course.hours ?? -1; maxLevel = Math.Max(maxLevel, course.level); if (course.level == 9) { course.level = 5; } else if (course.level == 10) { course.level = 6; } allExamCourse.Add(course); } else { CourseEntity course = new CourseEntity(); course.courseId = ce.course_id ?? 0; course.requiredRoomType = ce.required_room_type_id ?? 0; course.duration = ce.exam_length ?? 0; course.level = ce.course.hours ?? -1; nonExamCourse.Add(course); } } } foreach (section sessions in context.sections.Where(w => w.is_deleted == false)) { int courseId = sessions.course_id ?? 0; int sId = sessions.id; foreach (CourseEntity ce in allExamCourse) { if (courseId == ce.courseId) { ce.sessionIds.Add(new SessionEntity(sId, sessions.faculty_id, sessions.class_weekday, sessions.class_start_time, sessions.room_id, ce.duration)); } } foreach (CourseEntity ce in nonExamCourse) { if (courseId == ce.courseId && ce.sessionIds.Count <= 0) { ce.sessionIds.Add(new SessionEntity(sId, sessions.faculty_id, sessions.class_weekday, sessions.class_start_time, sessions.room_id, ce.duration)); } } } sortSessionsByProtor(); if (RANDOM_ORDER) { // shuffle all exam couse to make a diversity exam table allExamCourse.Shuffle(); } else { // sort by session count of courses, descending (course with more sessions in first) allExamCourse.Sort( delegate(CourseEntity c1, CourseEntity c2) { int i = c2.sessionIds.Count - c1.sessionIds.Count; if (i == 0) { return(c1.courseId - c2.courseId); } return(i); }); } }
public ExamTables arrangeExam() { ExamTables ret = new ExamTables(); maxLevel = -1; sortExamCourse(); getProtorRoomAndSpecial(); allLevelTimeLine = new List <TimeValueInterval> [maxLevel + 1]; for (int i = 0; i < maxLevel; ++i) { allLevelTimeLine[i] = new List <TimeValueInterval>(); } while (allSpecial.Count > 0) { int courseId = allSpecial[0].courseId; List <SpecialEntity> s = checkInSpecial(courseId); CourseEntity ce = null; foreach (CourseEntity c in allExamCourse) { if (c.courseId == courseId) { ce = c; break; } } if (ce == null) { foreach (SpecialEntity se in s) { allSpecial.Remove(se); } continue; } List <SessionEntity> remainSessions = new List <SessionEntity>(ce.sessionIds); TimeValueInterval timeData = allSpecial[0].timeData; if (s.Count > 0) // special arrangement(course with a specified room an start time) { foreach (SpecialEntity se in s) { ExamEntity e = specialArrange(ce, se, timeData, remainSessions, s); ret.addExam(e); } } if (remainSessions.Count > 0) { List <ExamEntity> el = normalArrange(ce, remainSessions, timeData); foreach (ExamEntity exam in el) { ret.addExam(exam); } } foreach (SpecialEntity se in s) { allSpecial.Remove(se); } allExamCourse.Remove(ce); } while (allExamCourse.Count > 0) { CourseEntity ce = allExamCourse[0]; List <SessionEntity> remainSessions = new List <SessionEntity>(ce.sessionIds); TimeValueInterval timeData = getEarlistTimeData(ce); if (timeData == null) { allExamCourse.Remove(ce); Console.WriteLine("Course " + ce.courseId + " required impoosible resourses"); continue; } if (remainSessions.Count > 0) { List <ExamEntity> el = normalArrange(ce, remainSessions, timeData); foreach (ExamEntity exam in el) { ret.addExam(exam); } } allExamCourse.Remove(ce); } foreach (CourseEntity ce in nonExamCourse) { ExamEntity ex = new ExamEntity(); ex.courseId = ce.courseId; ex.protorId = -1; ex.sessionIds = ce.sessionIds; ex.roomType = ce.requiredRoomType; ret.addExam(ex); } return(ret); }