我正在尝试解决 Optaplanner 中的特定问题,但无法弄清楚如何最好地将其融入域模型。
我的问题涉及许多“组”实体,每个实体每天有 3 个时段,可以在其中进行多项 Activity 中的任意一项。此外,每个小组对于在两周的计划中可以进行的每项 Activity 的具体数量都有独特的要求。 对于这个问题,我考虑有四个主要对象:组、 Activity 、日和期间。在这种情况下,我应该使用什么作为我的 PlanningEntity 和 PlanningVariable?
最佳答案
看起来您需要一个额外的类来充当您的 PlanningEntity,这将是一个多对多的“加入”类。像 ActivityAssignment 这样的东西,它将具有 Group、Period 和 Activity PlanningVariable 字段。
Activity 实例仅代表可能 Activity 的列表。 ActivityAssignment 是将 Activity 与组和时间(或时间段)相关联的地方。
Day 和Period 类也稍微复杂一些。您需要为时间表中的每一天提供一个 Day 实例。如果这是一个重复的时间表,那么“日”在概念上可能代表“第一周”的“星期一”;第一周,星期二; ...;到第 2 周星期五。如果不是重复计划,则每个 Day 实例将代表一个日历日期。无论如何,Day 类可以有三个Period 成员:Period1、Period2 和Period3(或者您可以使用Period 集合,如果它将来会增长的话)。根据规则逻辑,实现规则取决于您是否使用集合还是三个离散的周期字段)。
期间与日期有双向关系。 Day 将具有 getPeriod1()、getPeriod2()、getPeriod3() 等方法。 period 有一个方法 getDay()。这是您确定特定 ActivityAssignment 属于哪个时间段和日期的方法,例如 ActivityAssignment.getPeriod().getDay()。
要计算某个组的 Activity 数量,您可以实现 drools 规则或查询来选择所有 ActivityAssignments ($aa),其中 $aa.group.id == "this_group",且 $aa.activity.id = =“那个 Activity ”。如果该数字大于该组允许的最大值(可能类似于 group.getMaxActivityCount("that_activity")),则向 ScoreHolder 添加适当的惩罚。
编辑: 为了完整起见,您将拥有一个带 @PlanningSolution 注释的解决方案类,其中包含组、 Activity 和时段的问题事实集合。您可以在循环中使用 3 个 period 实例初始化所有 Day 实例,但您还可以将每个 period 实例添加到单独的列表中,然后在 PlanningSolution 类上设置该列表。
您将拥有一个类似如下的规划解决方案类:
@PlanningSolution
public class ActivitySchedule {
@ValueRangeProvider(id = "groupRange")
private List<Group> groups;
@ValueRangeProvider(id = "periodRange")
private List<Period> periods;
@ValueRangeProvider(id = "activityRange")
private List<Activity> activities;
private HardSoftScore score;
//...
}
初始化解决方案时,请执行以下操作:
// Coded for clarity, not for efficiency ;)
for(int dayCount = 0; dayCount < 10; dayCount++){
Day day = new Day();
day.setIndex(dayCount);
//...
Period period1 = new Period(day);
day.setPeriod1(period1);
Period period2 = new Period(day);
day.setPeriod2(period1);
Period period3 = new Period(day);
day.setPeriod3(period3);
dayList.add(day);
periodList.add(period1);
periodList.add(period2);
periodList.add(period3);
}
activitySolution.setDays(dayList);
activitySolution.setPeriods(periodList);
activitySolution.setActivities(activityList);
//...
关于java - 在 Optaplanner 中建模 Activity 调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50397049/