
本文详解如何突破标准车辆路径问题(vrp)限制,在 optaplanner 中构建适配医院担架员调度的定制化优化模型,支持多人员协同任务、纯时间窗约束及无地理坐标的场景建模。
本文详解如何突破标准车辆路径问题(vrp)限制,在 optaplanner 中构建适配医院担架员调度的定制化优化模型,支持多人员协同任务、纯时间窗约束及无地理坐标的场景建模。
OptaPlanner 本身并非仅限于经典 VRP 示例(如 vehiclerouting 官方案例)所呈现的“单车—单客户—欧氏距离”范式。它是一个通用约束求解框架,核心能力在于建模业务逻辑与硬/软约束,而非强制依赖地理坐标或一对一任务分配。因此,将担架员轮班调度建模为优化问题,关键在于重构问题本质:这本质上是带资源约束与时间窗的多技能任务分配问题(Multi-Skill Task Assignment with Time Windows),而非传统意义上的路径规划。
✅ 正确建模思路
-
实体抽象替代“车辆-客户”映射
- StretcherBearer(担架员)作为 @PlanningEntity,代表可调度资源;
- Mission(任务)作为 @PlanningEntity 或 @ProblemFact,含属性:requiredBearers: int(需2人/1人)、earliestStart: LocalDateTime、latestEnd: LocalDateTime、duration: Duration;
- 移除 Location 类与坐标字段——无需 x/y,也无需距离矩阵。
-
用约束替代“路径计算”
由于无空间坐标,无法定义行驶时间,但可基于任务时间窗与担架员可用性建模时序约束:// 硬约束:任务必须被足额分配且不超时 Constraint missionFullyAssigned(ConstraintFactory factory) { return factory.forEach(Mission.class) .filter(mission -> mission.getAssignedBearers().size() < mission.getRequiredBearers()) .penalize(HardSoftScore.ONE_HARD) .asConstraint("Mission fully assigned"); } // 软约束:最小化担架员总工作时长(替代“总路程”目标) Constraint minimizeTotalWorkingTime(ConstraintFactory factory) { return factory.forEach(StretcherBearer.class) .join(Mission.class, equal(StretcherBearer::getId, Mission::getAssigneeId)) .groupBy((bearer, mission) -> bearer, sumDuration((bearer, mission) -> mission.getDuration())) .reward(SoftScore.ONE_SOFT) .asConstraint("Minimize total working time"); } -
数据输入格式灵活适配
不必强转为 .vrptw 或依赖坐标 JSON。推荐使用轻量级 JSON Schema:{ "bearers": [ {"id": 1, "name": "Bear1", "availableFrom": "08:00", "availableUntil": "17:00"}, {"id": 2, "name": "Bear2", "availableFrom": "09:00", "availableUntil": "18:00"} ], "missions": [ { "id": 101, "requiredBearers": 2, "earliestStart": "08:30", "latestEnd": "09:15", "duration": "20m" } ] }通过 Jackson 反序列化为 Java 对象后直接注入 SolverManager,无需中间格式转换。
⚠️ 注意事项与最佳实践
- 避免误用 VRP 示例结构:不要继承 VehicleRoutingSolution 或复用 DistanceMatrix 相关代码——它们与您的问题域不匹配;
- 时间精度统一:所有时间使用 LocalDateTime + Duration,禁用 java.util.Date;建议以分钟为单位归一化时间窗偏移;
- 多资源协同建模:若任务需“特定组合”(如1名资深+1名实习),可扩展 Mission 的 requiredSkills: Set<String>,并添加技能匹配约束;
- 性能提示:启用 @PlanningPin 标记已锁定的紧急任务;对高优先级任务设置 @PlanningVariable(graphType = PlanningVariableGraphType.CHAIN) 实现链式排程。
综上,OptaPlanner 完全胜任担架员调度建模——只需跳出“VRP 必须有坐标”的思维定式,回归约束求解本质:明确谁(资源)、做什么(任务)、何时做(时间窗)、满足什么条件(约束)。真正的优化价值,源于对医疗调度业务规则的精准编码,而非对地理路径的拟合。

















