Повреждение очков Optaplanner и правило, основанное на времени

Я столкнулся с проблемой искажения очков в моем решении. Это случается, когда я подсчитываю мягкую оценку своих сущностей в режиме FULL_ASSERT. В режиме ПРОИЗВОДСТВО искажения счета не происходит.

Я попытался рассчитать коэффициент, учитывающий текущую дату. В основном что-то вроде (сейчас - start_date_of_my_entity) * priority_of_my_entity. Результатом этого является оценка объекта.

Я попытался кое-что исправить: в файле drools у меня есть глобальная переменная с именем «now», которая инициализируется правилом с именем «init». Это правило имеет значение 1000, чтобы быть уверенным, что это правило выполняется первым. Но это тоже не работает. Когда я запускаю свое решение, все работает нормально, пока переменная «сейчас» не достигнет значения XX: YY: ZZ + 1. На этот раз появляется искажение счета.

Вот трассировка стека:

10:19:00,007  INFO XXXXXXXXXXXXXXXXXX:153 - Score corruption: the workingScore (0hard/0medium/-188soft) is not the uncorruptedScore (0hard/0medium/-198soft) after completedAction (Entity(Customer1-19531312-50min)-Agent(19463312-TEST) => Agent(19463312-TEST)):
  The corrupted scoreDirector has 3 ConstraintMatch(s) which are in excess (and should not be there):
    com.package.solver/agentRatio/level2/[[Ljava.lang.Object;@105d99aa, Agent(19463312-TEST)]=-63
    com.package.solver/decalageEtPriorite/level2/[Entity(Customer2-19531332-23min)-Agent(19463312-TEST)]=-50
    com.package.solver/decalageEtPriorite/level2/[Entity(Customer1-19531312-50min)-Agent(19463312-TEST)]=-75
  The corrupted scoreDirector has 3 ConstraintMatch(s) which are missing:
    com.package.solver/agentRatio/level2/[[Ljava.lang.Object;@23739ca6, Agent(19463312-TEST)]=-63
    com.package.solver/decalageEtPriorite/level2/[Entity(Customer2-19531332-23min)-Agent(19463312-TEST)]=-55
    com.package.solver/decalageEtPriorite/level2/[Entity(Customer1-19531312-50min)-Agent(19463312-TEST)]=-80
  Check your score constraints.
10:19:00,007  INFO BasicPlumbingTermination:59 - Terminating solver early.
java.lang.IllegalStateException: Score corruption: the workingScore (0hard/0medium/-188soft) is not the uncorruptedScore (0hard/0medium/-198soft) after completedAction (Entity(Customer1-19531312-50min)-Agent(19463312-TEST) => Agent(19463312-TEST)):
  The corrupted scoreDirector has 3 ConstraintMatch(s) which are in excess (and should not be there):
    com.package.solver/agentRatio/level2/[[Ljava.lang.Object;@105d99aa, Agent(19463312-TEST)]=-63
    com.package.solver/decalageEtPriorite/level2/[Entity(Customer2-19531332-23min)-Agent(19463312-TEST)]=-50
    com.package.solver/decalageEtPriorite/level2/[Entity(Customer1-19531312-50min)-Agent(19463312-TEST)]=-75
  The corrupted scoreDirector has 3 ConstraintMatch(s) which are missing:
    com.package.solver/agentRatio/level2/[[Ljava.lang.Object;@23739ca6, Agent(19463312-TEST)]=-63
    com.package.solver/decalageEtPriorite/level2/[Entity(Customer2-19531332-23min)-Agent(19463312-TEST)]=-55
    com.package.solver/decalageEtPriorite/level2/[Entity(Customer1-19531312-50min)-Agent(19463312-TEST)]=-80
  Check your score constraints.
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.assertWorkingScoreFromScratch(AbstractScoreDirector.java:308)
    at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.assertWorkingScoreFromScratch(DefaultSolverScope.java:118)
    at org.optaplanner.core.impl.phase.scope.AbstractPhaseScope.assertWorkingScoreFromScratch(AbstractPhaseScope.java:131)
    at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.processMove(LocalSearchDecider.java:164)
    at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.doMove(LocalSearchDecider.java:149)
    at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.decideNextStep(LocalSearchDecider.java:121)
    at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:66)
    at org.optaplanner.core.impl.solver.DefaultSolver.runPhases(DefaultSolver.java:193)
    at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:157)

Думаю, проблема в том, что когда я перескакиваю с одной минуты на другую, счет не тот. Например, для объекта, начиная с 08:10:00 и с приоритетом 5:

  • В 08:00:59 счет 10 * 5 => 50.
  • В 08:01:00 счет 9 * 5 => 45

Кажется, что счет рассчитывается в 08:00:59, а в 08h01: 00 проводится проверка счета.

Вдобавок я вижу, что происходит переход от текущего агента к текущему агенту. Это нормально ?

Кроме того, трассировка стека включает еще одно правило agentRatio. Я думаю, это потому, что это правило основано на текущем времени для подсчета очков. Такая же проблема для этого правила.

Не могли бы вы помочь мне решить эту проблему?

РЕДАКТИРОВАТЬ: попробовав пару потенциальных решений, я все еще застрял с этой проблемой. Я мог бы попробовать добавить проблемный факт, который будет представлять время, и вместо этого выполнять расчет на основе времени. Но меня это решение не радует.


person Bibou3618    schedule 17.03.2015    source источник
comment
Вы нашли какое-либо решение этой проблемы с искажением очков?   -  person Клаус Шварц    schedule 24.09.2018


Ответы (1)


Я столкнулся с той же проблемой, в моем случае это начинается, когда я перемещаю логику подсчета очков из файла Drools в свой Java-код, например:

scoreHolder.addSoftConstraintMatch(kcontext,<complex expression>);

to

scoreHolder.addSoftConstraintMatch(kcontext,$myVariable.calculate());

Согласно этой ссылке, я не смог этого сделать.

person Edu Costa    schedule 23.03.2015