Optaplanner: попытка понять правило нежелательного шаблона на примере списка медсестер

Я новичок в слюни и java, и я пытаюсь понять, как работает это правило из примера составления списка медсестер, особенно в первой части о шаблоне $.

rule "unwantedPatternShiftType3DaysPattern"
    when
        $pattern : ShiftType3DaysPattern(
            $dayIndex0ShiftType : dayIndex0ShiftType,
            $dayIndex1ShiftType : dayIndex1ShiftType,
            $dayIndex2ShiftType : dayIndex2ShiftType
        )
        PatternContractLine(
            pattern == $pattern, $contract : contract
        )

        ShiftAssignment(
            shiftType == $dayIndex0ShiftType,
            contract == $contract,
            $employee : employee, $firstDayIndex : shiftDateDayIndex
        )
        ShiftAssignment(
            shiftType == $dayIndex1ShiftType,
            employee == $employee,
            shiftDateDayIndex == ($firstDayIndex + 1)
        )
        ShiftAssignment(
            shiftType == $dayIndex2ShiftType,
            employee == $employee,
            shiftDateDayIndex == ($firstDayIndex + 2)
        )
    then
        scoreHolder.addSoftConstraintMatch(kcontext, - $pattern.getWeight());
end

В частности, как слюнки узнают, какое значение находится в: dayIndex0ShiftType, dayIndex1ShiftType, dayIndex2ShiftType? Он вызывает класс ShiftType3DaysPattern с этими значениями, но как эти значения определяются?

Кроме того, когда он делает этот вызов:

ShiftType3DaysPattern (dayIndex0ShiftType, dayIndex1ShiftType, dayIndex2ShiftType)

который относится к следующему:

@XStreamAlias("ShiftType3DaysPattern")
public class ShiftType3DaysPattern extends Pattern {

    private ShiftType dayIndex0ShiftType;
    private ShiftType dayIndex1ShiftType;
    private ShiftType dayIndex2ShiftType;

    public ShiftType getDayIndex0ShiftType() {
        return dayIndex0ShiftType;
    }

    public void setDayIndex0ShiftType(ShiftType dayIndex0ShiftType) {
        this.dayIndex0ShiftType = dayIndex0ShiftType;
    }

    public ShiftType getDayIndex1ShiftType() {
        return dayIndex1ShiftType;
    }

    public void setDayIndex1ShiftType(ShiftType dayIndex1ShiftType) {
        this.dayIndex1ShiftType = dayIndex1ShiftType;
    }

    public ShiftType getDayIndex2ShiftType() {
        return dayIndex2ShiftType;
    }

    public void setDayIndex2ShiftType(ShiftType dayIndex2ShiftType) {
        this.dayIndex2ShiftType = dayIndex2ShiftType;
    }

    @Override
    public String toString() {
        return "Work pattern: " + dayIndex0ShiftType + ", " + dayIndex1ShiftType + ", " + dayIndex2ShiftType;
    }

}

Это сокращение для ShiftType3DaysPattern.getDayIndex0ShiftType, ShiftType3DaysPattern.getDayIndex1ShiftType и ShiftType3DaysPattern.getDayIndex2ShiftType?

И если это так, как ShiftType3DaysPattern знает, какой шаблон вернуть, если в исходных файлах xml имеется более одного «трехдневного шаблона»? Что мне не хватает?

Более того, если существует более одного «трехдневного паттерна», то как слюни автоматически применяют это правило ко всем этим «трехдневным паттернам»?


person Jeff    schedule 26.09.2018    source источник


Ответы (1)


В частности, как слюнки узнают, какое значение находится в: dayIndex0ShiftType, dayIndex1ShiftType, dayIndex2ShiftType? Он вызывает класс ShiftType3DaysPattern с этими значениями, но как эти значения определяются?

Каждый ShiftType3DaysPattern в вашей коллекции фактов о проблемах будет оцениваться по этому правилу в сочетании с другими условиями в предложении when. Таким образом, каждая комбинация ShiftType3DaysPattern, PatternContractLine и трех ShiftAssignment, доступная как факт проблемы в сеансе Kie, будет оцениваться. Если все условия совпадают (то есть PatternContractLine соответствует ShiftType3DayPattern и все три типа ShiftAssignment назначаются в порядке нежелательного ShiftType3DayPattern, правило будет активировано, и оценка будет иметь отрицательное влияние. Таким образом, значение dayIndex0ShiftType, dayIndex1ShiftTy будет быть тем, что задано в ShiftType3DaysPattern в коллекции фактов о проблеме.

Это сокращение для ShiftType3DaysPattern.getDayIndex0ShiftType, ShiftType3DaysPattern.getDayIndex1ShiftType и ShiftType3DaysPattern.getDayIndex2ShiftType?

Я не уверен, что именно вы имеете в виду, но если вы имеете в виду это:

$pattern : ShiftType3DaysPattern(
    $dayIndex0ShiftType : dayIndex0ShiftType,
    $dayIndex1ShiftType : dayIndex1ShiftType,
    $dayIndex2ShiftType : dayIndex2ShiftType
)

Это просто синтаксис для присвоения dayIndex0ShiftType переменной $dayIndex0ShiftType, чтобы на нее можно было ссылаться в правиле позже. Сам паттерн также присваивается переменной $pattern. Сам по себе знак доллара - это просто условность.

И если это так, как ShiftType3DaysPattern знает, какой шаблон возвращать, если в исходных файлах xml имеется более одного трехдневного шаблона? Что мне не хватает?

Более того, если существует более одного трехдневного паттерна, как слюни автоматически применяют это правило ко всем этим трехдневным паттернам?

Как я сказал ранее, правило будет оцениваться для каждой доступной комбинации фактов проблемы, поэтому каждый ShiftType3DaysPattern будет оцениваться по сравнению с другими фактами, указанными в пункте when правила.

Я рекомендую вам прочитать документацию по Drools, она поможет вам улучшить ваше базовое понимание Drools. Это долгое чтение, но оно того стоит. По крайней мере, прочтите Руководство пользователя.

person n1ck    schedule 27.09.2018
comment
Я очень ценю ваш ответ - я полагаю, я действительно не понимаю, как создается Факт шаблона ShiftType3day - это где-то в файле .drl? Чтобы создать факт, разве вам не нужно правило в файле .drl, которое вставляет факт, но я не вижу этого в файле .drl .... Кроме того, я не совсем понимаю, что делает PatternContractLine? Какова его цель? Спасибо!!!! - person Jeff; 28.09.2018
comment
@Jeff Решение, которое необходимо решить, читается из XML в приложении примеров. Взгляните на NurseRosteringImporter.java, здесь все факты, включая шаблон ShiftType3Day, вставлены в решение (NurseRoster.java). Optaplanner вставляет факты за вас под капот с помощью аннотаций ProblemFactCollectionProperty и PlanningEntityCollectionProperty в классе решения (см. Документацию по этим аннотациям). Что касается вашего второго вопроса, вы можете изучить документацию для этого примера: docs.optaplanner.org/7.11.0.Final/optaplanner-docs/html_single/ - person n1ck; 28.09.2018