org.drools.planner.examples.curriculumcourse.persistence.CurriculumCourseSolutionImporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of drools-planner-examples Show documentation
Show all versions of drools-planner-examples Show documentation
Drools Planner optimizes automated planning by combining metaheuristic search algorithms with rule
engine powered score calculation. This is the drools-planner-examples module which contains examples on how to use
Drools Planner.
/*
* Copyright 2010 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.planner.examples.curriculumcourse.persistence;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.drools.planner.examples.common.persistence.AbstractTxtSolutionImporter;
import org.drools.planner.examples.curriculumcourse.domain.Course;
import org.drools.planner.examples.curriculumcourse.domain.Curriculum;
import org.drools.planner.examples.curriculumcourse.domain.CurriculumCourseSchedule;
import org.drools.planner.examples.curriculumcourse.domain.Day;
import org.drools.planner.examples.curriculumcourse.domain.Lecture;
import org.drools.planner.examples.curriculumcourse.domain.Period;
import org.drools.planner.examples.curriculumcourse.domain.Room;
import org.drools.planner.examples.curriculumcourse.domain.Teacher;
import org.drools.planner.examples.curriculumcourse.domain.Timeslot;
import org.drools.planner.examples.curriculumcourse.domain.UnavailablePeriodPenalty;
import org.drools.planner.core.solution.Solution;
public class CurriculumCourseSolutionImporter extends AbstractTxtSolutionImporter {
private static final String INPUT_FILE_SUFFIX = ".ctt";
private static final String SPLIT_REGEX = "[\\ \\t]+";
public static void main(String[] args) {
new CurriculumCourseSolutionImporter().convertAll();
}
public CurriculumCourseSolutionImporter() {
super(new CurriculumCourseDaoImpl());
}
@Override
protected String getInputFileSuffix() {
return INPUT_FILE_SUFFIX;
}
public TxtInputBuilder createTxtInputBuilder() {
return new CurriculumCourseInputBuilder();
}
public class CurriculumCourseInputBuilder extends TxtInputBuilder {
public Solution readSolution() throws IOException {
CurriculumCourseSchedule schedule = new CurriculumCourseSchedule();
schedule.setId(0L);
// Name: ToyExample
schedule.setName(readStringValue("Name:"));
// Courses: 4
int courseListSize = readIntegerValue("Courses:");
// Rooms: 2
int roomListSize = readIntegerValue("Rooms:");
// Days: 5
int dayListSize = readIntegerValue("Days:");
// Periods_per_day: 4
int timeslotListSize = readIntegerValue("Periods_per_day:");
// Curricula: 2
int curriculumListSize = readIntegerValue("Curricula:");
// Constraints: 8
int unavailablePeriodPenaltyListSize = readIntegerValue("Constraints:");
Map courseMap = readCourseListAndTeacherList(
schedule, courseListSize);
readRoomList(
schedule, roomListSize);
Map, Period> periodMap = createPeriodListAndDayListAndTimeslotList(
schedule, dayListSize, timeslotListSize);
readCurriculumList(
schedule, courseMap, curriculumListSize);
readUnavailablePeriodPenaltyList(
schedule, courseMap, periodMap, unavailablePeriodPenaltyListSize);
readEmptyLine();
readConstantLine("END.");
createLectureList(schedule);
logger.info("CurriculumCourseSchedule with {} teachers, {} curricula, {} courses, {} periods, {} rooms" +
" and {} unavailable period constraints.",
new Object[]{schedule.getTeacherList().size(),
schedule.getCurriculumList().size(),
schedule.getCourseList().size(),
schedule.getPeriodList().size(),
schedule.getRoomList().size(),
schedule.getUnavailablePeriodPenaltyList().size()});
int possibleForOneLectureSize = schedule.getPeriodList().size() * schedule.getRoomList().size();
BigInteger possibleSolutionSize = BigInteger.valueOf(possibleForOneLectureSize).pow(
schedule.getLectureList().size());
String flooredPossibleSolutionSize = "10^" + (possibleSolutionSize.toString().length() - 1);
logger.info("CurriculumCourseSchedule with flooredPossibleSolutionSize ({}) and possibleSolutionSize ({}).",
flooredPossibleSolutionSize, possibleSolutionSize);
return schedule;
}
private Map readCourseListAndTeacherList(
CurriculumCourseSchedule schedule, int courseListSize) throws IOException {
Map courseMap = new HashMap(courseListSize);
Map teacherMap = new HashMap();
List courseList = new ArrayList(courseListSize);
readEmptyLine();
readConstantLine("COURSES:");
for (int i = 0; i < courseListSize; i++) {
Course course = new Course();
course.setId((long) i);
// Courses: <# Lectures> <# Students>
String line = bufferedReader.readLine();
String[] lineTokens = splitBySpacesOrTabs(line, 5);
course.setCode(lineTokens[0]);
course.setTeacher(findOrCreateTeacher(teacherMap, lineTokens[1]));
course.setLectureSize(Integer.parseInt(lineTokens[2]));
course.setMinWorkingDaySize(Integer.parseInt(lineTokens[3]));
course.setCurriculumList(new ArrayList());
course.setStudentSize(Integer.parseInt(lineTokens[4]));
courseList.add(course);
courseMap.put(course.getCode(), course);
}
schedule.setCourseList(courseList);
List teacherList = new ArrayList(teacherMap.values());
schedule.setTeacherList(teacherList);
return courseMap;
}
private Teacher findOrCreateTeacher(Map teacherMap, String code) {
Teacher teacher = teacherMap.get(code);
if (teacher == null) {
teacher = new Teacher();
int id = teacherMap.size();
teacher.setId((long) id);
teacher.setCode(code);
teacherMap.put(code, teacher);
}
return teacher;
}
private void readRoomList(CurriculumCourseSchedule schedule, int roomListSize)
throws IOException {
readEmptyLine();
readConstantLine("ROOMS:");
List roomList = new ArrayList(roomListSize);
for (int i = 0; i < roomListSize; i++) {
Room room = new Room();
room.setId((long) i);
// Rooms:
String line = bufferedReader.readLine();
String[] lineTokens = splitBySpacesOrTabs(line, 2);
room.setCode(lineTokens[0]);
room.setCapacity(Integer.parseInt(lineTokens[1]));
roomList.add(room);
}
schedule.setRoomList(roomList);
}
private Map, Period> createPeriodListAndDayListAndTimeslotList(
CurriculumCourseSchedule schedule, int dayListSize, int timeslotListSize) throws IOException {
int periodListSize = dayListSize * timeslotListSize;
Map, Period> periodMap = new HashMap, Period>(periodListSize);
List dayList = new ArrayList(dayListSize);
for (int i = 0; i < dayListSize; i++) {
Day day = new Day();
day.setId((long) i);
day.setDayIndex(i);
dayList.add(day);
}
schedule.setDayList(dayList);
List timeslotList = new ArrayList(timeslotListSize);
for (int i = 0; i < timeslotListSize; i++) {
Timeslot timeslot = new Timeslot();
timeslot.setId((long) i);
timeslot.setTimeslotIndex(i);
timeslotList.add(timeslot);
}
schedule.setTimeslotList(timeslotList);
List periodList = new ArrayList(periodListSize);
for (int i = 0; i < dayListSize; i++) {
for (int j = 0; j < timeslotListSize; j++) {
Period period = new Period();
period.setId((long) (i * timeslotListSize + j));
period.setDay(dayList.get(i));
period.setTimeslot(timeslotList.get(j));
periodList.add(period);
periodMap.put(Arrays.asList(i, j), period);
}
}
schedule.setPeriodList(periodList);
return periodMap;
}
private void readCurriculumList(CurriculumCourseSchedule schedule,
Map courseMap, int curriculumListSize) throws IOException {
readEmptyLine();
readConstantLine("CURRICULA:");
List curriculumList = new ArrayList(curriculumListSize);
for (int i = 0; i < curriculumListSize; i++) {
Curriculum curriculum = new Curriculum();
curriculum.setId((long) i);
// Curricula: <# Courses> ...
String line = bufferedReader.readLine();
String[] lineTokens = splitBySpacesOrTabs(line);
if (lineTokens.length < 2) {
throw new IllegalArgumentException("Read line (" + line
+ ") is expected to contain at least 2 tokens.");
}
curriculum.setCode(lineTokens[0]);
int coursesInCurriculum = Integer.parseInt(lineTokens[1]);
if (lineTokens.length != (coursesInCurriculum + 2)) {
throw new IllegalArgumentException("Read line (" + line + ") is expected to contain "
+ (coursesInCurriculum + 2) + " tokens.");
}
for (int j = 2; j < lineTokens.length; j++) {
Course course = courseMap.get(lineTokens[j]);
if (course == null) {
throw new IllegalArgumentException("Read line (" + line + ") uses an unexisting course("
+ lineTokens[j] + ").");
}
course.getCurriculumList().add(curriculum);
}
curriculumList.add(curriculum);
}
schedule.setCurriculumList(curriculumList);
}
private void readUnavailablePeriodPenaltyList(CurriculumCourseSchedule schedule, Map courseMap,
Map, Period> periodMap, int unavailablePeriodPenaltyListSize)
throws IOException {
readEmptyLine();
readConstantLine("UNAVAILABILITY_CONSTRAINTS:");
List penaltyList = new ArrayList(
unavailablePeriodPenaltyListSize);
for (int i = 0; i < unavailablePeriodPenaltyListSize; i++) {
UnavailablePeriodPenalty penalty = new UnavailablePeriodPenalty();
penalty.setId((long) i);
// Unavailability_Constraints:
String line = bufferedReader.readLine();
String[] lineTokens = splitBySpacesOrTabs(line, 3);
penalty.setCourse(courseMap.get(lineTokens[0]));
int dayIndex = Integer.parseInt(lineTokens[1]);
int timeslotIndex = Integer.parseInt(lineTokens[2]);
Period period = periodMap.get(Arrays.asList(dayIndex, timeslotIndex));
if (period == null) {
throw new IllegalArgumentException("Read line (" + line + ") uses an unexisting period("
+ dayIndex + " " + timeslotIndex + ").");
}
penalty.setPeriod(period);
penaltyList.add(penalty);
}
schedule.setUnavailablePeriodPenaltyList(penaltyList);
}
private void createLectureList(CurriculumCourseSchedule schedule) {
List courseList = schedule.getCourseList();
List lectureList = new ArrayList(courseList.size());
long id = 0L;
for (Course course : courseList) {
for (int i = 0; i < course.getLectureSize(); i++) {
Lecture lecture = new Lecture();
lecture.setId((long) id);
id++;
lecture.setCourse(course);
lecture.setLectureIndexInCourse(i);
// Notice that we leave the PlanningVariable properties on null
lectureList.add(lecture);
}
}
schedule.setLectureList(lectureList);
}
}
}