use of org.acme.schooltimetabling.domain.TimeTable in project optaplanner-quickstarts by kiegroup.
the class TimeTableResourceTest method solveAndRetrieve.
@Test
@Timeout(60L)
void solveAndRetrieve() throws JsonProcessingException {
timeTableResource.solve();
await().timeout(AWAIT_TIMEOUT).until(solverRequestSink::received, messages -> messages.size() == 1);
Message<String> solverRequestMessage = solverRequestSink.received().get(0);
SolverRequest solverRequest = objectMapper.readValue(solverRequestMessage.getPayload(), SolverRequest.class);
// Assign one lesson to simulate solving.
TimeTable requestTimeTable = solverRequest.getTimeTable();
Lesson firstLesson = requestTimeTable.getLessonList().get(0);
firstLesson.setRoom(requestTimeTable.getRoomList().get(0));
firstLesson.setTimeslot(requestTimeTable.getTimeslotList().get(0));
SolverResponse solverResponse = new SolverResponse(solverRequest.getProblemId(), requestTimeTable);
solverResponseSource.send(objectMapper.writeValueAsString(solverResponse));
// Wait until the client receives the message and saves the new timetable to a database.
await().timeout(AWAIT_TIMEOUT).until(timeTableResource::getTimeTable, timeTable -> timeTable.getLessonList().get(0).getRoom() != null);
Lesson solvedFirstLesson = timeTableResource.getTimeTable().getLessonList().get(0);
assertThat(solvedFirstLesson.getRoom()).isNotNull();
assertThat(solvedFirstLesson.getTimeslot()).isNotNull();
}
use of org.acme.schooltimetabling.domain.TimeTable in project optaplanner-quickstarts by kiegroup.
the class TimeTableMessagingHandler method solve.
@Incoming(SOLVER_REQUEST_CHANNEL)
public CompletionStage<Void> solve(Message<String> solverRequestMessage) {
return CompletableFuture.runAsync(() -> {
SolverRequest solverRequest;
try {
solverRequest = objectMapper.readValue(solverRequestMessage.getPayload(), SolverRequest.class);
} catch (Throwable throwable) {
LOGGER.warn("Unable to deserialize solver request from JSON.", throwable);
/* Usually a bad request, which should be immediately rejected. No error response can be sent back
as the problemId is unknown. Such a NACKed message is redirected to the DLQ (Dead letter queue).
Catching the Throwable to make sure no unchecked exceptions are missed. */
solverRequestMessage.nack(throwable);
return;
}
TimeTable solution;
try {
solution = solver.solve(solverRequest.getTimeTable());
replySuccess(solverRequestMessage, solverRequest.getProblemId(), solution);
} catch (Throwable throwable) {
LOGGER.warn("Error during processing a solver request ({}).", solverRequest.getProblemId(), throwable);
replyFailure(solverRequestMessage, solverRequest.getProblemId(), throwable);
}
});
}
use of org.acme.schooltimetabling.domain.TimeTable in project optaplanner-quickstarts by kiegroup.
the class TimeTableApp method printTimetable.
private static void printTimetable(TimeTable timeTable) {
LOGGER.info("");
List<Room> roomList = timeTable.getRoomList();
List<Lesson> lessonList = timeTable.getLessonList();
Map<Timeslot, Map<Room, List<Lesson>>> lessonMap = lessonList.stream().filter(lesson -> lesson.getTimeslot() != null && lesson.getRoom() != null).collect(Collectors.groupingBy(Lesson::getTimeslot, Collectors.groupingBy(Lesson::getRoom)));
LOGGER.info("| | " + roomList.stream().map(room -> String.format("%-10s", room.getName())).collect(Collectors.joining(" | ")) + " |");
LOGGER.info("|" + "------------|".repeat(roomList.size() + 1));
for (Timeslot timeslot : timeTable.getTimeslotList()) {
List<List<Lesson>> cellList = roomList.stream().map(room -> {
Map<Room, List<Lesson>> byRoomMap = lessonMap.get(timeslot);
if (byRoomMap == null) {
return Collections.<Lesson>emptyList();
}
List<Lesson> cellLessonList = byRoomMap.get(room);
if (cellLessonList == null) {
return Collections.<Lesson>emptyList();
}
return cellLessonList;
}).collect(Collectors.toList());
LOGGER.info("| " + String.format("%-10s", timeslot.getDayOfWeek().toString().substring(0, 3) + " " + timeslot.getStartTime()) + " | " + cellList.stream().map(cellLessonList -> String.format("%-10s", cellLessonList.stream().map(Lesson::getSubject).collect(Collectors.joining(", ")))).collect(Collectors.joining(" | ")) + " |");
LOGGER.info("| | " + cellList.stream().map(cellLessonList -> String.format("%-10s", cellLessonList.stream().map(Lesson::getTeacher).collect(Collectors.joining(", ")))).collect(Collectors.joining(" | ")) + " |");
LOGGER.info("| | " + cellList.stream().map(cellLessonList -> String.format("%-10s", cellLessonList.stream().map(Lesson::getStudentGroup).collect(Collectors.joining(", ")))).collect(Collectors.joining(" | ")) + " |");
LOGGER.info("|" + "------------|".repeat(roomList.size() + 1));
}
List<Lesson> unassignedLessons = lessonList.stream().filter(lesson -> lesson.getTimeslot() == null || lesson.getRoom() == null).collect(Collectors.toList());
if (!unassignedLessons.isEmpty()) {
LOGGER.info("");
LOGGER.info("Unassigned lessons");
for (Lesson lesson : unassignedLessons) {
LOGGER.info(" " + lesson.getSubject() + " - " + lesson.getTeacher() + " - " + lesson.getStudentGroup());
}
}
}
use of org.acme.schooltimetabling.domain.TimeTable in project optaplanner-quickstarts by kiegroup.
the class TimeTableApp method main.
public static void main(String[] args) {
SolverFactory<TimeTable> solverFactory = SolverFactory.create(new SolverConfig().withSolutionClass(TimeTable.class).withEntityClasses(Lesson.class).withConstraintProviderClass(TimeTableConstraintProvider.class).withTerminationSpentLimit(Duration.ofSeconds(5)));
// Load the problem
TimeTable problem = generateDemoData();
// Solve the problem
Solver<TimeTable> solver = solverFactory.buildSolver();
TimeTable solution = solver.solve(problem);
// Visualize the solution
printTimetable(solution);
}
use of org.acme.schooltimetabling.domain.TimeTable in project optaplanner-quickstarts by kiegroup.
the class TimeTableController method getTimeTable.
// To try, GET http://localhost:8080/timeTable
@GetMapping()
public TimeTable getTimeTable() {
// Get the solver status before loading the solution
// to avoid the race condition that the solver terminates between them
SolverStatus solverStatus = getSolverStatus();
TimeTable solution = timeTableRepository.findById(TimeTableRepository.SINGLETON_TIME_TABLE_ID);
// Sets the score
scoreManager.updateScore(solution);
solution.setSolverStatus(solverStatus);
return solution;
}
Aggregations