构造启发式中的自定义移动

Custom Move in construction heuristic

有没有办法在构造启发式中放置自定义移动? 我正在从事一个与 optaplanner 中的护士排班问题接近的项目,但除了将员工安排到轮班任务之外,我还需要将员工安排到班次内所需的小任务中。 因此,当我让员工轮班时,我需要让员工完成他可以完成的所有小任务(具有适合他们的技能)。我不希望它成为第二个计划实体,而员工是计划变量,我只希望当我将员工分配到一个班次时,然后循环遍历该班次内的所有小任务(在开始和结束之间轮班的次数),要么分配他,要么不分配他,所以如果他有技能,就必须分配他,否则不分配。 我无法将此自定义移动放入构造启发式中。有办法吗?

编辑: 在每个班次上放置一个 "price tag" 会不会很好,我的意思是 运行 通过预 optaplanner 启发式(在求解开始之前)计算每个 [=18= 中小任务的出现次数] 稍后使用此信息来决定员工是否适合该班次,假设如果他有能力满足至少 70% 的小 assignments.For 示例,他可以被分配到给定的班次在轮班时间内发生下一个小任务(SA):SA1 4 次,SA2 4 次,SA3 2 次,我们有员工 1 有 SA1 和 SA2 的技能,员工 2 只有 SA1 的技能,那么 employee1 可以被分配到班次,因为他满足了 70% 以上的小任务,但是 employee2 不能,因为他只满足了 40%。然后在员工得到 "in" 之后,轮班就把他分配到他可以工作的所有任务(如果他有小任务的技能,他就会去做,除了员工具备所需的技能)。不会决定将哪个员工分配给一个小任务,每个员工都是一样的,如果他被分配到轮班并且有技能。 这是个好主意吗?

而且可以将多个计划值分配给计划实体的单个实例吗?在这种情况下是否可以将多个员工分配给一个班次分配实例(我只是以它为例,我不打算那样做)?

查看文档中Construction Heuristics的高级配置。 构造启发式仅适用于 ChangeMove 及其组合(笛卡尔、并集、序列)。 例如,如果您有 2 个实体 A 和 B(每个都有 1 个变量),其中 10 个 A 实例和 7 B 实例,有可能:

  • 要有 2 个 CH:第一个 CH 分配所有 A,然后第二个分配所有 B。因此它按此顺序分配:A1、A2、A3、...、A10、B1、B2、...、B7(并尝试每个计划值)。
  • 要有 1 个分配 A 和 B 混合的 CH。所以它以混合顺序分配(由实体排序器定义):A1、B1、B2、A2、B4、A3、...、B7 , A10.
  • (如果只有 1 个实体 class 但有 2 个变量,则可以进行笛卡尔积或顺序分配。)

无论如何,如果这还不行,实现一个 CustomPhaseCommand 以获得完全的自由(请参阅具有 ...Initializer class 的文档和示例) .

besides just putting the employee to a shift assignment i also need to put the employee to small assignments that are required within a shift

听起来你的模型可能效率低下。考虑只有 1 个规划变量的替代模型:

class Employee {}
class Shift {}
@PlanningEntity class SmallAssignment {
    Shift shift;
    @PlanningVariable Employee employee;
}

或者更好地定义什么是 "shift":如果 2 个人同时工作,他们是否使用相同的轮班实例?由于您的业务复杂性可能需要此模型:

class Employee {}
class ShiftWithDateTime {}
@PlanningEntity lass ShiftWithDateTimeAndEmployee {
    ShiftWithDateTime shiftWithDateTime;
    @PlanningVariable Employee employee;
}
@PlanningEntity class SmallAssignment {
    ShiftWithDateTime shiftWithDateTime;
    @PlanningVariable Employee employee;
}

但在那种情况下,我可能会检查它是否像这样可重构(这只有在小任务可以贪婪地完美分配时才有可能,所以它们的约束不是 NP-hard):

class Employee {}
@PlanningEntity class ShiftWithDateTime { // shadow entity
    @InverseRelationShadow List<ShiftWithDateTimeAndEmployee> assignments;
    boolean hasEnoughEmployeesToFulfillAllSmallAssignments() { ... }
}
@PlanningEntity lass ShiftWithDateTimeAndEmployee {
    ShiftWithDateTime shiftWithDateTime;
    @PlanningVariable Employee employee;
}