private void initializeExamList( LocalSearchSolverScope localSearchSolverScope, Examination examination) { List<Period> periodList = examination.getPeriodList(); List<Room> roomList = examination.getRoomList(); List<Exam> examList = new ArrayList<Exam>( examination .getTopicList() .size()); // TODO this can be returned from createExamAssigningScoreList WorkingMemory workingMemory = localSearchSolverScope.getWorkingMemory(); List<ExamInitializationWeight> examInitialWeightList = createExamAssigningScoreList(examination); for (ExamInitializationWeight examInitialWeight : examInitialWeightList) { Score unscheduledScore = localSearchSolverScope.calculateScoreFromWorkingMemory(); Exam leader = examInitialWeight.getExam(); FactHandle leaderHandle = null; List<ExamToHandle> examToHandleList = new ArrayList<ExamToHandle>(5); if (leader.getExamCoincidence() == null) { examToHandleList.add(new ExamToHandle(leader)); } else { for (Exam coincidenceExam : leader.getExamCoincidence().getCoincidenceExamSet()) { examToHandleList.add(new ExamToHandle(coincidenceExam)); } } List<PeriodScoring> periodScoringList = new ArrayList<PeriodScoring>(periodList.size()); for (Period period : periodList) { for (ExamToHandle examToHandle : examToHandleList) { if (examToHandle.getExamHandle() == null) { examToHandle.getExam().setPeriod(period); examToHandle.setExamHandle(workingMemory.insert(examToHandle.getExam())); if (examToHandle.getExam().isCoincidenceLeader()) { leaderHandle = examToHandle.getExamHandle(); } } else { examToHandle.getExam().setPeriod(period); workingMemory.update(examToHandle.getExamHandle(), examToHandle.getExam()); } } Score score = localSearchSolverScope.calculateScoreFromWorkingMemory(); periodScoringList.add(new PeriodScoring(period, score)); } Collections.sort(periodScoringList); scheduleLeader( periodScoringList, roomList, localSearchSolverScope, workingMemory, unscheduledScore, examToHandleList, leader, leaderHandle); examList.add(leader); // Schedule the non leaders for (ExamToHandle examToHandle : examToHandleList) { Exam exam = examToHandle.getExam(); // Leader already has a room if (!exam.isCoincidenceLeader()) { scheduleNonLeader( roomList, localSearchSolverScope, workingMemory, exam, examToHandle.getExamHandle()); examList.add(exam); } } } Collections.sort(examList, new PersistableIdComparator()); examination.setExamList(examList); }
private void scheduleLeader( List<PeriodScoring> periodScoringList, List<Room> roomList, LocalSearchSolverScope localSearchSolverScope, WorkingMemory workingMemory, Score unscheduledScore, List<ExamToHandle> examToHandleList, Exam leader, FactHandle leaderHandle) { boolean perfectMatch = false; Score bestScore = DefaultHardAndSoftScore.valueOf(Integer.MIN_VALUE, Integer.MIN_VALUE); Period bestPeriod = null; Room bestRoom = null; for (PeriodScoring periodScoring : periodScoringList) { if (bestScore.compareTo(periodScoring.getScore()) >= 0) { // No need to check the rest break; } for (ExamToHandle examToHandle : examToHandleList) { examToHandle.getExam().setPeriod(periodScoring.getPeriod()); workingMemory.update(examToHandle.getExamHandle(), examToHandle.getExam()); } for (Room room : roomList) { leader.setRoom(room); workingMemory.update(leaderHandle, leader); Score score = localSearchSolverScope.calculateScoreFromWorkingMemory(); if (score.compareTo(unscheduledScore) < 0) { if (score.compareTo(bestScore) > 0) { bestScore = score; bestPeriod = periodScoring.getPeriod(); bestRoom = room; } } else if (score.equals(unscheduledScore)) { perfectMatch = true; break; } else { throw new IllegalStateException( "The score (" + score + ") cannot be higher than unscheduledScore (" + unscheduledScore + ")."); } } if (perfectMatch) { break; } } if (!perfectMatch) { if (bestPeriod == null || bestRoom == null) { throw new IllegalStateException( "The bestPeriod (" + bestPeriod + ") or the bestRoom (" + bestRoom + ") cannot be null."); } leader.setRoom(bestRoom); workingMemory.update(leaderHandle, leader); for (ExamToHandle examToHandle : examToHandleList) { examToHandle.getExam().setPeriod(bestPeriod); workingMemory.update(examToHandle.getExamHandle(), examToHandle.getExam()); } } logger.debug(" Exam ({}) initialized for starting solution.", leader); }