Правило DRL Ошибка в Optaplanner при срабатывании логического значения - PullRequest
1 голос
/ 18 июня 2019

Я пытаюсь написать правило для балансировки нагрузки, в первую очередь, отдельный контракт.В конечном итоге я хочу быть в состоянии сбалансировать неравные контракты, такие как неполный рабочий день (PT) и полный рабочий день (FT).

Кто-нибудь сделал это и может поделиться своим правилом DRL?Я обнаружил, что вам нужно использовать PT x инверсию FT перед подачей формулы.

Я много раз читал пример тенниса в документации Optaplanner.Я могу получить единичный контракт, чтобы хорошо сбалансировать его, но хочу, чтобы он работал с логическим значением IS_LOADBALANCED, которое я сделал в булевом классе.Я получаю ошибку, которую не понимаю.Первый элемент кода работает, но я хочу, чтобы второй работал на основе логического значения, поскольку я хотел бы сохранить правило * «Минимальное и максимальное количество назначений», которое входит в комплект поставки NurseRoster.

rule "fairAssignmentCountPerEmployee"
    when
        accumulate(
        $e : Employee()
        and accumulate(
         ShiftAssignment(employee == $e);
         $assignment : count()
         );
         $result : loadBalance($assignment)
         )
     then
        scoreHolder.addSoftConstraintMatch(kcontext, -(int)$result.getMeanDeviationSquaredSumRootMillis());

        end

rule "fairAssignmentCountPerEmployee"
salience 1
    when
    $contractLine : BooleanContractLine(contractLineType == ContractLineType. IS_LOADBALANCED, enabled == true, $contract : contract)

            accumulate(
        $e : Employee(contract == $contract)
        and accumulate(
         ShiftAssignment(employee == $e);
         $assignment : count()
         );
         $result : loadBalance($assignment)
         )
     then
//Just to see the contract type
     System.out.println($contract);
        scoreHolder.addSoftConstraintMatch(kcontext, -(int)$result.getMeanDeviationSquaredSumRootMillis());

        end
Caused by: java.lang.NullPointerException
    at org.drools.core.reteoo.FromNodeLeftTuple.getAccumulatedObjects(FromNodeLeftTuple.java:111)
    at org.drools.core.common.AgendaItem.getObjectsDeep(AgendaItem.java:79)
    at org.drools.core.reteoo.RuleTerminalNodeLeftTuple.getObjectsDeep(RuleTerminalNodeLeftTuple.java:359)
    at org.optaplanner.core.api.score.holder.AbstractScoreHolder.extractJustificationList(AbstractScoreHolder.java:133)
    at org.optaplanner.core.api.score.holder.AbstractScoreHolder.registerConstraintMatch(AbstractScoreHolder.java:104)
    at org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder.addSoftConstraintMatch(HardSoftScoreHolder.java:177)
    at org.optaplanner.examples.nurserostering.solver.Rule_fairAssignmentCountPerEmployee343111290.defaultConsequence(Rule_fairAssignmentCountPerEmployee343111290.java:21)
    at org.optaplanner.examples.nurserostering.solver.Rule_fairAssignmentCountPerEmployee343111290DefaultConsequenceInvokerGenerated.evaluate(Unknown Source)
    at org.optaplanner.examples.nurserostering.solver.Rule_fairAssignmentCountPerEmployee343111290DefaultConsequenceInvoker.evaluate(Unknown Source)
    at org.drools.core.phreak.RuleExecutor.innerFireActivation(RuleExecutor.java:432)

Тем временем я работал над этим, используя нижеприведенное.Я, однако, все еще ищу помощь, чтобы уравновесить неравные контракты.Кто-нибудь ??

 rule "Minimum and maximum number of assignments"


           salience 1 // Do these rules first (optional, for performance)
        when
            $contractLine : MinMaxContractLine(contractLineType == ContractLineType.TOTAL_ASSIGNMENTS, enabled == true,  $contract : contract
              ) && BooleanContractLine(contractLineType == ContractLineType. IS_LOADBALANCED, enabled == false, contract == $contract)

            $employee : Employee(contract == $contract)

            accumulate(
                $assignment : ShiftAssignment(employee == $employee);
                $total : count($assignment)
     )
        then
           int totalInt = $total.intValue();
            if ($contractLine.isMinimumEnabled() && totalInt < $contractLine.getMinimumValue()) {
                scoreHolder.addSoftConstraintMatch(kcontext,
                       (totalInt - $contractLine.getMinimumValue()) * $contractLine.getMinimumWeight());
            } else if ($contractLine.isMaximumEnabled() && totalInt > $contractLine.getMaximumValue()) {
               scoreHolder.addSoftConstraintMatch(kcontext,
                        ($contractLine.getMaximumValue() - totalInt) * $contractLine.getMaximumWeight());
            } else {
               // Workaround for https://issues.jboss.org/browse/PLANNER-761
             scoreHolder.addSoftConstraintMatch(kcontext, 0);
            }
    end 



    rule "fairAssignmentCountPerTeam"

        when $contractLine : BooleanContractLine(contractLineType == ContractLineType. IS_LOADBALANCED, enabled == true, $contract : contract) 

            accumulate(
                ShiftAssignment(employee != null, $e : employee, contract == $contract, $shift:shift);
                $total : loadBalanceByCount($e)
            )
        then

            scoreHolder.addHardConstraintMatch(kcontext, - (int) $total.getZeroDeviationSquaredSumRootMillis());
    end
...