Skip to content

Commit

Permalink
CurriculumCourseGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
ge0ffrey committed Mar 19, 2017
1 parent 84dbe48 commit 42f5960
Show file tree
Hide file tree
Showing 2 changed files with 281 additions and 1 deletion.
Expand Up @@ -106,7 +106,7 @@ public static StringDataGenerator buildCompanyNames() {
"ES"); "ES");
} }


public static StringDataGenerator build10kLocationNames() { public static StringDataGenerator buildLocationNames() {
return new StringDataGenerator() return new StringDataGenerator()
.addPart(true, 0, .addPart(true, 0,
"Los", "Los",
Expand Down
@@ -0,0 +1,280 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* 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.optaplanner.examples.curriculumcourse.persistence;

import java.io.File;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

import org.optaplanner.examples.common.app.LoggingMain;
import org.optaplanner.examples.common.persistence.AbstractSolutionImporter;
import org.optaplanner.examples.common.persistence.SolutionDao;
import org.optaplanner.examples.common.persistence.StringDataGenerator;
import org.optaplanner.examples.curriculumcourse.domain.Course;
import org.optaplanner.examples.curriculumcourse.domain.CourseSchedule;
import org.optaplanner.examples.curriculumcourse.domain.Curriculum;
import org.optaplanner.examples.curriculumcourse.domain.Day;
import org.optaplanner.examples.curriculumcourse.domain.Lecture;
import org.optaplanner.examples.curriculumcourse.domain.Period;
import org.optaplanner.examples.curriculumcourse.domain.Room;
import org.optaplanner.examples.curriculumcourse.domain.Teacher;
import org.optaplanner.examples.curriculumcourse.domain.Timeslot;

import static org.optaplanner.examples.common.persistence.AbstractSolutionImporter.getFlooredPossibleSolutionSize;

public class CurriculumCourseGenerator extends LoggingMain {

public static final int DAY_LIST_SIZE = 5;
public static final int TIMESLOT_LIST_SIZE = 7;

public static void main(String[] args) {
CurriculumCourseGenerator generator = new CurriculumCourseGenerator();
generator.writeCourseSchedule(100, 4);
generator.writeCourseSchedule(160, 5);
}

private final int[] roomCapacityOptions = {
20,
25,
30,
40,
50
};

private final String[] courseCodes = new String[]{
"Math",
"Chemistry",
"Physics",
"Geography",
"Biology",
"History",
"English",
"Spanish",
"French",
"German",
"ICT",
"Economics",
"Psychology",
"Art",
"Music"};

private final StringDataGenerator teacherNameGenerator = StringDataGenerator.buildFullNames();

protected final SolutionDao solutionDao;
protected final File outputDir;
protected Random random;

public CurriculumCourseGenerator() {
solutionDao = new CurriculumCourseDao();
outputDir = new File(solutionDao.getDataDir(), "unsolved");
}

private void writeCourseSchedule(int lectureListSize, int curriculumListSize) {
int courseListSize = lectureListSize * 2 / 9 + 1;
int teacherListSize = courseListSize / 3 + 1;
int periodListSize = DAY_LIST_SIZE * TIMESLOT_LIST_SIZE - TIMESLOT_LIST_SIZE + 4;
int roomListSize = curriculumListSize * 2 / 5 + 1;
String fileName = determineFileName(lectureListSize, periodListSize, roomListSize);
File outputFile = new File(outputDir, fileName + ".xml");
CourseSchedule schedule = createCourseSchedule(fileName, teacherListSize, curriculumListSize, courseListSize, lectureListSize, roomListSize);
solutionDao.writeSolution(schedule, outputFile);
}

private String determineFileName(int lectureListSize, int periodListSize, int roomListSize) {
return lectureListSize + "lectures-" + periodListSize + "periods" + roomListSize + "rooms";
}

public CourseSchedule createCourseSchedule(String fileName, int teacherListSize, int curriculumListSize, int courseListSize, int lectureListSize, int roomListSize) {
random = new Random(37);
CourseSchedule schedule = new CourseSchedule();
schedule.setId(0L);

createDayList(schedule);
createTimeslotList(schedule);
createPeriodList(schedule);
createTeacherList(schedule, teacherListSize);
createCourseList(schedule, courseListSize);
createLectureList(schedule, lectureListSize);
createRoomList(schedule, roomListSize);
createCurriculumList(schedule, curriculumListSize);

int possibleForOneLectureSize = schedule.getPeriodList().size() * schedule.getRoomList().size();
BigInteger possibleSolutionSize = BigInteger.valueOf(possibleForOneLectureSize).pow(
schedule.getLectureList().size());
logger.info("CourseSchedule {} has {} teachers, {} curricula, {} courses, {} lectures," +
" {} periods, {} rooms and {} unavailable period constraints with a search space of {}.",
fileName,
schedule.getTeacherList().size(),
schedule.getCurriculumList().size(),
schedule.getCourseList().size(),
schedule.getLectureList().size(),
schedule.getPeriodList().size(),
schedule.getRoomList().size(),
schedule.getUnavailablePeriodPenaltyList().size(),
getFlooredPossibleSolutionSize(possibleSolutionSize));
return schedule;
}

private void createDayList(CourseSchedule schedule) {
List<Day> dayList = new ArrayList<>(DAY_LIST_SIZE);
for (int i = 0; i < DAY_LIST_SIZE; i++) {
Day day = new Day();
day.setId((long) i);
day.setDayIndex(i);
day.setPeriodList(new ArrayList<>(TIMESLOT_LIST_SIZE));
dayList.add(day);
}
schedule.setDayList(dayList);
}

private void createTimeslotList(CourseSchedule schedule) {
List<Timeslot> timeslotList = new ArrayList<>(TIMESLOT_LIST_SIZE);
for (int i = 0; i < TIMESLOT_LIST_SIZE; i++) {
Timeslot timeslot = new Timeslot();
timeslot.setId((long) i);
timeslot.setTimeslotIndex(i);
timeslotList.add(timeslot);
}
schedule.setTimeslotList(timeslotList);
}

private void createPeriodList(CourseSchedule schedule) {
List<Period> periodList = new ArrayList<>(schedule.getDayList().size() * schedule.getTimeslotList().size());
long periodId = 0L;
for (Day day : schedule.getDayList()) {
for (Timeslot timeslot : schedule.getTimeslotList()) {
if (day.getDayIndex() == 2 && timeslot.getTimeslotIndex() >= 4) {
// No lectures Wednesday afternoon
continue;
}
Period period = new Period();
period.setId(periodId);
periodId++;
period.setDay(day);
day.getPeriodList().add(period);
period.setTimeslot(timeslot);
periodList.add(period);
}
}
schedule.setPeriodList(periodList);
}

private void createTeacherList(CourseSchedule schedule, int teacherListSize) {
List<Teacher> teacherList = new ArrayList<>(teacherListSize);
teacherNameGenerator.predictMaximumSizeAndReset(teacherListSize);
for (int i = 0; i < teacherListSize; i++) {
Teacher teacher = new Teacher();
teacher.setId((long) i);
teacher.setCode(teacherNameGenerator.generateNextValue());
teacherList.add(teacher);
}
schedule.setTeacherList(teacherList);
}

private void createCourseList(CourseSchedule schedule, int courseListSize) {
List<Teacher> teacherList = schedule.getTeacherList();
List<Course> courseList = new ArrayList<>(courseListSize);
Set<String> codeSet = new HashSet<>();
for (int i = 0; i < courseListSize; i++) {
Course course = new Course();
course.setId((long) i);
if (i < courseCodes.length * 2) {

}
String code = (i < courseCodes.length * 2)
? courseCodes[i % courseCodes.length]
: courseCodes[random.nextInt(courseCodes.length)];
if (courseListSize >= courseCodes.length) {
int codeSuffixNumber = 1;
while (codeSet.contains(code + codeSuffixNumber)) {
codeSuffixNumber++;
}
code = code + codeSuffixNumber;
codeSet.add(code);
}
course.setCode(code);
Teacher teacher = (i < teacherList.size() * 2)
? teacherList.get(i % teacherList.size())
: teacherList.get(random.nextInt(teacherList.size()));
course.setTeacher(teacher);
course.setLectureSize(0);
course.setMinWorkingDaySize(1);
course.setCurriculumList(new ArrayList<>());
course.setStudentSize(0);
courseList.add(course);
}
schedule.setCourseList(courseList);
}

private void createLectureList(CourseSchedule schedule, int lectureListSize) {
List<Course> courseList = schedule.getCourseList();
List<Lecture> lectureList = new ArrayList<>(lectureListSize);
for (int i = 0; i < lectureListSize; i++) {
Lecture lecture = new Lecture();
lecture.setId((long) i);
Course course = (i < courseList.size() * 2)
? courseList.get(i % courseList.size())
: courseList.get(random.nextInt(courseList.size()));
lecture.setCourse(course);
lecture.setLectureIndexInCourse(course.getLectureSize());
course.setLectureSize(course.getLectureSize() + 1);
lecture.setLocked(false);
lectureList.add(lecture);
}
schedule.setLectureList(lectureList);

}

private void createRoomList(CourseSchedule schedule, int roomListSize) {
List<Room> roomList = new ArrayList<>(roomListSize);
for (int i = 0; i < roomListSize; i++) {
Room room = new Room();
room.setId((long) i);
room.setCode("R" + ((i / 50 * 100) + 1 + i));
room.setCapacity(roomCapacityOptions[random.nextInt(roomCapacityOptions.length)]);
roomList.add(room);
}
schedule.setRoomList(roomList);
}

private void createCurriculumList(CourseSchedule schedule, int curriculumListSize) {
int maximumCapacity = schedule.getRoomList().stream().mapToInt(Room::getCapacity).max().getAsInt();
List<Course> courseList = schedule.getCourseList();
List<Curriculum> curriculumList = new ArrayList<>(curriculumListSize);
for (int i = 0; i < curriculumListSize; i++) {
Curriculum curriculum = new Curriculum();
curriculum.setId((long) i);
int studentSize = 5 + random.nextInt(20);

// List<Course> courseSubList = courseList.stream()
// .filter(course -> course.getStudentSize() + studentSize < maximumCapacity)
// .collect(Collectors.toList());
// Collections.shuffle(courseSubList);
// courseSubList.stream().limit(ggg);

curriculumList.add(curriculum);
}
schedule.setCurriculumList(curriculumList);
}

}

0 comments on commit 42f5960

Please sign in to comment.