OptaPlanner - 实体从未添加到此 ScoreDirector 错误中

2024-03-26

我正在 OptaPlanner 中实现一种类似于 NurseRoster 的算法。我需要在 drools 中实施一条规则来检查是否Employee工作天数不能超过他的工作天数contract。由于我不知道如何在 drools 中实现这一点,所以我决定将其编写为类中的方法,然后在 drools 中使用它来检查约束是否已被打破。因为我需要一个List of ShiftAssignments in the Employee类,我需要使用@InverseRelationShadowVariable自动更新该列表Employee被分配到一个Shift。自从我的Employee现在必须是PlanningEntity, 错误The entity was never added to this ScoreDirector出现了。我相信该错误是由我造成的ShiftAssignment实体,它有一个@ValueRangeProvider of employees可以在那方面发挥作用Shift。我认为这是因为ScoreDirector.beforeEntityAdded and ScoreDirector.afterEntityAdded从未被调用,因此出现错误。由于某种原因,当我从中删除该范围提供者时ShiftAssignment并穿上它NurseRoster哪一个是@PlanningSolution, 有效。

这是代码:

员工:

@InverseRelationShadowVariable(sourceVariableName = "employee")
public List<ShiftAssignment> getEmployeeAssignedToShiftAssignments() {
    return employeeAssignedToShiftAssignments;
}

班次分配:

@PlanningVariable(valueRangeProviderRefs = {
    "employeeRange" }, strengthComparatorClass =    EmployeeStrengthComparator.class,nullable = true)
public Employee getEmployee() {
    return employee;
}

// the value range for this planning entity
@ValueRangeProvider(id = "employeeRange")
public List<Employee> getPossibleEmployees() {
    return getShift().getEmployeesThatCanWorkThisShift();
}

护士名册:

@ValueRangeProvider(id = "employeeRange")
@PlanningEntityCollectionProperty
public List<Employee> getEmployeeList() {
    return employeeList;
}

这就是我用来更新的方法listOfEmployeesThatCanWorkThisShift:

public static void checkIfAnEmployeeCanBelongInGivenShiftAssignmentValueRange(NurseRoster nurseRoster) {
    List<Shift> shiftList = nurseRoster.getShiftList();
    List<Employee> employeeList = nurseRoster.getEmployeeList();
    for (Shift shift : shiftList) {
        List<Employee> employeesThatCanWorkThisShift = new ArrayList<>();
        String shiftDate = shift.getShiftDate().getDateString();
        ShiftTypeDefinition shiftTypeDefinitionForShift = shift.getShiftType().getShiftTypeDefinition();
        for (Employee employee : employeeList) {
            AgentDailySettings agentDailySetting = SearchThroughSolution.findAgentDailySetting(employee, shiftDate);
            List<ShiftTypeDefinition> shiftTypeDefinitions = agentDailySetting.getShiftTypeDefinitions();
            if (shiftTypeDefinitions.contains(shiftTypeDefinitionForShift)) {
                employeesThatCanWorkThisShift.add(employee);

            }
        }
        shift.setEmployeesThatCanWorkThisShift(employeesThatCanWorkThisShift);
    }
}

我使用的规则:

rule "maxDaysInPeriod"
when
$shiftAssignment : ShiftAssignment(employee != null)
then
int differentDaysInPeriod = MethodsUsedInScoreCalculation.employeeMaxDaysPerPeriod($shiftAssignment.getEmployee());
int maxDaysInPeriod = $shiftAssignment.getEmployee().getAgentPeriodSettings().getMaxDaysInPeriod();
if(differentDaysInPeriod > maxDaysInPeriod)
{
scoreHolder.addHardConstraintMatch(kcontext, differentDaysInPeriod - maxDaysInPeriod);
}
end

我该如何修复这个错误?


这肯定与创建“新的最佳解决方案”时发生的解决方案克隆有关。

当我实现自定义解决方案克隆时,我遇到了同样的错误。在我的项目中,我有多个规划实体类,并且所有这些实体类都相互引用(单个值或列表)。因此,当发生解决方案克隆时,需要更新引用,以便它们可以指向克隆的值。默认克隆过程执行此操作不会出现任何问题,从而使解决方案保持一致状态。它甚至可以正确更新父计划实体中的计划实体实例列表(由 OptaPlanner 核心的“FieldAccessingSolutionCloner”类中的方法“cloneCollectionsElementIfNeeded”覆盖)。

只是一个演示我在规划实体类方面所拥有的内容:

@PlanningEntity
public class ParentPlanningEntityClass{
    List<ChildPlanningEntityClass> childPlanningEntityClassList;
}

@PlanningEntity
public class ChildPlanningEntityClass{
    ParentPlanningEntityClass parentPlanningEntityClass;
}

起初,我没有更新任何引用,甚至对于“ChildPlanningEntityClass”也出现错误。然后我编写了更新引用的代码。当涉及来自“ChildPlanningEntityClass”类的规划实体实例时,此时一切都很好,因为它们指向克隆的对象。我在“ParentPlanningEntityClass”案例中做错的是,我没有使用“new ArrayList();”从头开始创建“childPlanningEntityClassList”列表,而是只是更新了列表的元素(使用“set”方法)指向“ChildPlanningEntityClass”类的克隆实例。创建“new ArrayList();”时,填充元素以指向克隆对象并设置“childPlanningEntityClassList”列表,一切都是一致的(使用 FULL_ASSERT 进行测试)。

因此,只需将其连接到我的问题,列表“employeeAssignedToShiftAssignments”可能不是使用“new ArrayList();”从头开始创建的。而元素只是从列表中添加或删除。因此,可能发生的情况(如果列表不是从头开始创建的)是,工作解决方案和新的最佳解决方案(克隆)都将指向同一个列表,并且当工作解决方案继续更改此列表时,它会损坏最佳解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OptaPlanner - 实体从未添加到此 ScoreDirector 错误中 的相关文章

随机推荐