8.7. 运行 7000 timetable 应用程序
创建 IANA 时间范围项目后,在开发模式下运行它。在开发模式中,您可以在应用程序运行时更新应用程序源和配置。您的更改将显示在正在运行的应用程序中。
先决条件
- 您已创建了 phone timetable 项目。
流程
要将应用程序以开发模式编译,请从项目目录中输入以下命令:
./mvnw compile quarkus:dev
./mvnw compile quarkus:dev
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 测试 REST 服务。您可以使用任何 REST 客户端。以下示例使用 Linux 命令
curl
发送 POST 请求:curl -i -X POST http://localhost:8080/timeTable/solve -H "Content-Type:application/json" -d '{"timeslotList":[{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"}],"roomList":[{"name":"Room A"},{"name":"Room B"}],"lessonList":[{"id":1,"subject":"Math","teacher":"A. Turing","studentGroup":"9th grade"},{"id":2,"subject":"Chemistry","teacher":"M. Curie","studentGroup":"9th grade"},{"id":3,"subject":"French","teacher":"M. Curie","studentGroup":"10th grade"},{"id":4,"subject":"History","teacher":"I. Jones","studentGroup":"10th grade"}]}'
$ curl -i -X POST http://localhost:8080/timeTable/solve -H "Content-Type:application/json" -d '{"timeslotList":[{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"}],"roomList":[{"name":"Room A"},{"name":"Room B"}],"lessonList":[{"id":1,"subject":"Math","teacher":"A. Turing","studentGroup":"9th grade"},{"id":2,"subject":"Chemistry","teacher":"M. Curie","studentGroup":"9th grade"},{"id":3,"subject":"French","teacher":"M. Curie","studentGroup":"10th grade"},{"id":4,"subject":"History","teacher":"I. Jones","studentGroup":"10th grade"}]}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
终止中指定的时间用
application.properties
文件中定义的时间后,服务会返回类似以下示例的输出:HTTP/1.1 200 Content-Type: application/json ... {"timeslotList":...,"roomList":...,"lessonList":[{"id":1,"subject":"Math","teacher":"A. Turing","studentGroup":"9th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},"room":{"name":"Room A"}},{"id":2,"subject":"Chemistry","teacher":"M. Curie","studentGroup":"9th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"},"room":{"name":"Room A"}},{"id":3,"subject":"French","teacher":"M. Curie","studentGroup":"10th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},"room":{"name":"Room B"}},{"id":4,"subject":"History","teacher":"I. Jones","studentGroup":"10th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"},"room":{"name":"Room B"}}],"score":"0hard/0soft"}
HTTP/1.1 200 Content-Type: application/json ... {"timeslotList":...,"roomList":...,"lessonList":[{"id":1,"subject":"Math","teacher":"A. Turing","studentGroup":"9th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},"room":{"name":"Room A"}},{"id":2,"subject":"Chemistry","teacher":"M. Curie","studentGroup":"9th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"},"room":{"name":"Room A"}},{"id":3,"subject":"French","teacher":"M. Curie","studentGroup":"10th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},"room":{"name":"Room B"}},{"id":4,"subject":"History","teacher":"I. Jones","studentGroup":"10th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"},"room":{"name":"Room B"}}],"score":"0hard/0soft"}
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,您的应用程序为两个时间插槽和两个空间之一分配了四个小活动。另请注意,它符合所有硬限制。例如,M. Curie 的两个定义位于不同的时间段内。
要查看在过期期间 OptaPlanner 执行的操作,请查看服务器端的信息日志。以下是 info 日志输出示例:
... Solving started: time spent (33), best score (-8init/0hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0). ... Construction Heuristic phase (0) ended: time spent (73), best score (0hard/0soft), score calculation speed (459/sec), step total (4). ... Local Search phase (1) ended: time spent (5000), best score (0hard/0soft), score calculation speed (28949/sec), step total (28398). ... Solving ended: time spent (5000), best score (0hard/0soft), score calculation speed (28524/sec), phase total (2), environment mode (REPRODUCIBLE).
... Solving started: time spent (33), best score (-8init/0hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0). ... Construction Heuristic phase (0) ended: time spent (73), best score (0hard/0soft), score calculation speed (459/sec), step total (4). ... Local Search phase (1) ended: time spent (5000), best score (0hard/0soft), score calculation speed (28949/sec), step total (28398). ... Solving ended: time spent (5000), best score (0hard/0soft), score calculation speed (28524/sec), phase total (2), environment mode (REPRODUCIBLE).
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.7.1. 构建应用程序 复制链接链接已复制到粘贴板!
良好的应用程序包括测试覆盖。这个示例在 Red Hat build of Quarkus 上测试红帽构建的 OptaPlanner Demo timetable 项目。它使用 JUnit 测试来生成测试数据集,并将其发送到 TimeTableController
来解决。
流程
使用以下内容创建
src/test/java/com/example/rest/TimeTableResourceTest.java
类:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 此测试会验证之后,所有较少记录都会被分配给一个时间插槽和房间。它还会验证它发现了一个可行的解决方案(没有硬约束中断)。
在
src/main/resources/application.properties
文件中添加 test 属性:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
通常,解析器会在 200 毫秒内找到可行的解决方案。请注意,application.properties
文件在测试期间如何覆盖 solver 终止,以便在找到可行的解决方案 (0hard thesoft)
时立即终止。这可避免硬编码一个固定时间,因为单元测试可能会在任意硬件上运行。这种方法可确保测试运行足够长,以找到可行的解决方案,即使在较慢的系统上也是如此。但是,即使在快速的系统上,它不会运行毫秒的时间超过其严格要求。
8.7.2. 日志记录 复制链接链接已复制到粘贴板!
完成 Red Hat build of OptaPlanner 旧时间后,您可以使用日志信息来帮助微调 ConstraintProvider
中的限制。查看 info
日志文件中的分数计算速度,以评估对您的限制的影响。以调试模式运行应用程序,以显示应用程序采取的每个步骤,或使用 trace 日志记录来记录每个步骤和每次移动。
流程
- 在固定时间内运行 7000 timetable 应用程序,例如五分钟。
查看日志文件中的分数计算速度,如下例所示:
... Solving ended: ..., score calculation speed (29455/sec), ...
... Solving ended: ..., score calculation speed (29455/sec), ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
更改约束,在相同时间内再次运行 planning 应用程序,并查看日志文件中记录的分数计算速度。
以 debug 模式运行应用程序,以记录应用程序所做的每个步骤:
-
要从命令行运行调试模式,请使用
-D
系统属性。 要永久启用调试模式,请在
application.properties
文件中添加以下行:quarkus.log.category."org.optaplanner".level=debug
quarkus.log.category."org.optaplanner".level=debug
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 以下示例以 debug 模式显示
日志文件中
的输出:... Solving started: time spent (67), best score (-20init/0hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0). ... CH step (0), time spent (128), score (-18init/0hard/0soft), selected move count (15), picked move ([Math(101) {null -> Room A}, Math(101) {null -> MONDAY 08:30}]). ... CH step (1), time spent (145), score (-16init/0hard/0soft), selected move count (15), picked move ([Physics(102) {null -> Room A}, Physics(102) {null -> MONDAY 09:30}]). ...
... Solving started: time spent (67), best score (-20init/0hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0). ... CH step (0), time spent (128), score (-18init/0hard/0soft), selected move count (15), picked move ([Math(101) {null -> Room A}, Math(101) {null -> MONDAY 08:30}]). ... CH step (1), time spent (145), score (-16init/0hard/0soft), selected move count (15), picked move ([Physics(102) {null -> Room A}, Physics(102) {null -> MONDAY 09:30}]). ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
-
要从命令行运行调试模式,请使用
-
使用
trace
日志记录来显示每个步骤,以及每个步骤的每次移动。