@Override public int compare(Room o1, Room o2) { Integer roomScore1 = 0; Integer roomScore2 = 0; try { List<Feature> featureList1 = o1.objectsOfRoomProvidesFeature(); List<Feature> featureList2 = o2.objectsOfRoomProvidesFeature(); Collections.sort(featureList1); Collections.sort(featureList2); Map<Feature, Integer> featureToQuantityRoom1 = new TreeMap<Feature, Integer>(); Map<Feature, Integer> featureToQuantityRoom2 = new TreeMap<Feature, Integer>(); for (RoomProvidesFeature roomProvidesFeature : o1.whereSubjectOfRoomProvidesFeature()) { featureToQuantityRoom1.put( roomProvidesFeature.getFeature(), roomProvidesFeature.getQuantity()); } for (RoomProvidesFeature roomProvidesFeature : o2.whereSubjectOfRoomProvidesFeature()) { featureToQuantityRoom2.put( roomProvidesFeature.getFeature(), roomProvidesFeature.getQuantity()); } for (int i = 0; i < featureList1.size(); ++i) { int r1 = featureToQuantityRoom1.get(featureList1.get(i)); int r2 = featureToQuantityRoom2.get(featureList2.get(i)); if (r1 > r2) { ++roomScore1; } else if (r1 < r2) { ++roomScore2; } } } catch (DatabaseException e) { e.printStackTrace(); } if (roomScore1 == roomScore2) { if (random.nextBoolean()) { return -1; } else { return 1; } // return new Integer(o1.getId()).compareTo(new // Integer(o2.getId())); } return roomScore1.compareTo(roomScore2); }
/** * Calculates the hard fitness for a given schedule. * * <p>Hard fitness is the fitness that considers constraints which have to be fulfilled. If they * are not fulfilled the courses cannot take place. * * <p>Rules of assignment: * * <p>(1) Each course has a scheduled score and a maximum score where the maximum score for each * course consists of at least these 2 points: No overlapping in room allocation and no * overlapping in lecturer allocation. The maximum score is increased by 1 for each constraint. * * <p>(2) If there is not more than 1 course in the same room at the same time: score + 1 * * <p>(3) If the course lecturer has no other course at the same time: score + 1 * * <p>(4) If any other constraint of a course is fulfilled: score + 1 * * <p>(5) The total score is the sum of all course scores * * <p>(6) Hard fitness = scheduled scores / maximum scores * * <p>As the fitness value is defined by the position of the course it is calculated by iterating * over the course entries of the <code>Schedule</code> map. * * <p>First rule (2) and (3) will be tested. Second the constraints of a course will be checked * one after another. In each iteration step the maximum score and the schedule score will be * saved and added to the final fitness at the end of an iteration step. * * @throws DatabaseException * @see * de.fu.scetris.scheduler.model.strategy.interfaces.CalculateHardFitness#calculateHardFitness(de.fu.scetris.scheduler.model.strategy.interfaces.Schedule) */ @Override public double calculateHardFitness(final Schedule schedule, Configuration config) throws DatabaseException { int scheduledScore = 0; int maximumScore = 0; for (Entry<CourseElementInstance, RoomTimeIndex> entry : ((ScheduleImpl) schedule).getCourseToSlot().entrySet()) { maximumScore += 2; CourseElementInstance course = entry.getKey(); int roomIndex = entry.getValue().getRoomIndex(); int timeSlotIndex = entry.getValue().getTimeSlotIndex(); // Check rule (2) boolean roomOverlap = false; for (int i = 0; i < course.getDuration(); ++i) { if (((ScheduleImpl) schedule).getCourseListAt(roomIndex, timeSlotIndex).size() > 1) { roomOverlap = true; break; } } if (!roomOverlap) { scheduledScore += 1; } // Check rule (3) boolean lecturerOverlap = false; for (int i = 0; i < config.numberOfRooms; ++i) { for (int j = 0; j < course.getDuration(); ++j) { List<CourseElementInstance> courseList = ((ScheduleImpl) schedule).getCourseListAt(i, timeSlotIndex + j); for (CourseElementInstance checkedCourse : courseList) { if (!checkedCourse.equals(course) && checkedCourse .getCourseInstance() .getMainLecturer() .equals(course.getCourseInstance().getMainLecturer())) { lecturerOverlap = true; break; } } } } if (!lecturerOverlap) { scheduledScore += 1; } // Check rule (4) for (ElementInstancePrefersRoom coursePrefersRoom : course.whereSubjectOfElementInstancePrefersRoom()) { if (coursePrefersRoom.getPriority() == 100) { maximumScore += 1; Room preferredRoom = coursePrefersRoom.getRoom(); Room actualRoom = ((ScheduleImpl) schedule).getRoomTimeCourseSlotList().get(roomIndex).getRoom(); if (preferredRoom.equals(actualRoom)) { scheduledScore += 1; } } } for (ElementInstancePrefersTimeslot coursePrefersTimeSlot : course.whereSubjectOfElementInstancePrefersTimeslot()) { if (coursePrefersTimeSlot.getPriority() == 100) { maximumScore += 1; int preferredTimeSlotIndex = config.timeSlotList.indexOf(coursePrefersTimeSlot.getTimeslot()); if (preferredTimeSlotIndex >= timeSlotIndex && preferredTimeSlotIndex <= timeSlotIndex + course.getDuration()) { scheduledScore += 1; } } } for (ElementInstanceRequiresFeature courseRequiredFeature : course.whereSubjectOfElementInstanceRequiresFeature()) { maximumScore += 1; Room room = ((ScheduleImpl) schedule).getRoomTimeCourseSlotList().get(roomIndex).getRoom(); for (RoomProvidesFeature providedFeature : room.whereSubjectOfRoomProvidesFeature()) { int neededQuanity; if (courseRequiredFeature.getPriority() == 100) { neededQuanity = courseRequiredFeature.getQuantityMin(); } else { neededQuanity = courseRequiredFeature.getQuantityBetter(); } if (providedFeature.getFeature().equals(courseRequiredFeature.getFeature()) && providedFeature.getQuantity() >= neededQuanity) { scheduledScore += 1; break; } } } } for (Person lecturer : config.lecturerList) { for (PersonPrefersTimeslot prefersTimeSlot : lecturer.whereSubjectOfPersonPrefersTimeslot()) { if (prefersTimeSlot.getPriority() == 100) { maximumScore += 1; int preferredTimeSlotIndex = prefersTimeSlot.getTimeslot().getId(); for (CourseElementInstance course : lecturer.objectsOfPersonTakesPartInElementInstance()) { int timeSlotIndex = ((ScheduleImpl) schedule).getCourseToSlot().get(course).getTimeSlotIndex(); if (timeSlotIndex == preferredTimeSlotIndex) { scheduledScore += 1; break; } } } } } for (Room room : config.roomList) { for (RoomPrefersTimeslot prefersTimeSlot : room.whereSubjectOfRoomPrefersTimeslot()) { if (prefersTimeSlot.getPriority() == 100) { int preferredTimeSlot = prefersTimeSlot.getTimeslot().getId(); for (RoomTimeCourseSlot roomTimeCourseSlot : ((ScheduleImpl) schedule).getRoomTimeCourseSlotList()) { if (roomTimeCourseSlot.getRoom().equals(room)) { if (roomTimeCourseSlot .getTimeCourseSlots() .get(preferredTimeSlot) .getCourseList() .size() > 0) { scheduledScore += 1; break; } } } } } } return ((double) scheduledScore / (double) maximumScore); }