java - 在 Optaplanner 中建模 Activity 调度

标签 java optimization optaplanner

我正在尝试解决 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/

相关文章:

java - 二叉树 : method remove subtree

java - 解析 Android Volley JSONArray 响应

java - 比较字符串(文字和数字)的最快方法

java - IncrementalScore 在 Optaplanner 中产生不可行的解决方案

algorithm - 使用 OptaPlanner 对具有 z 分组约束的未定义数量的组中的 x 实体进行分组

java - 循环执行3次

php - 每秒 Apache 请求数

c - 在程序没有错误之前,我们是否应该禁用编译器优化?

drools - Optaplanner 7.13.0 无法从 jar 文件执行

java - 从 Java/Android url 获取参数名称集合