OptaPlanner 神话般的分数腐败

OptaPlanner's mythical score corruption

我为我的模型使用增量分数计算器。 经过hours/days优化"full assert"模式分数损坏异常抛出:

java.lang.IllegalStateException: Score corruption: the workingScore (-86591/-2765/-422/-591) is not the uncorruptedScore (-86591/-2873/-422/-591) after completedAction [...]:
Uncorrupted: Score calculator 3718238 [schedule=Schedule6422-2015-04-16T09:47:36.932[-86591/-2873/-422/-591], prioritiesScore=-422, timelineGapsScore=-2873, requirementGapsScore=-86591, timelineVersionsScore=-591]
Corrupted: Score calculator 3717237 [schedule=Schedule6422-2015-04-16T09:47:36.932[-86591/-2873/-422/-591], prioritiesScore=-422, timelineGapsScore=-2873, requirementGapsScore=-86591, timelineVersionsScore=-591]

分数在参数 timelineGapsScore 上有所不同。分数实例是从分数计算器对象字段 prioritiesScoretimelineGapsScorerequirementGapsScoretimelineVersionsScore 创建的。通过日志,两个分数的实例在这些字段中是等效的,但 optaplanner 引擎发现差异 (-86591/-2765/-422/-591) vs (-86591/-2873/-422/-591)。怎么可能?

我怀疑解决方案克隆的引用泄漏(它是特定的实现并进行深度复制),但仔细的代码检查没有显示此类错误。

UPD: 我忘了说:optaplanner 以守护进程模式运行,模型能够实时更改事实。所以我怀疑模型中的竞争条件。但是我不知道在 optaplanner 的引擎盖下如何实现更改注入(信息不够in docs)。

“当解决方案发生变化时,增量分数计算(也称为基于增量的分数计算)将计算与先前状态的增量以找到新的分数,而不是在每次解决方案评估时重新计算整个分数。

例如,如果单个女王 A 从第 1 行移动到第 2 行,则不会费心检查女王 B 和 C 是否可以互相攻击,因为他们都没有改变。"

当增量分数和真实分数(=未损坏的分数)不同步时,就会发生分数损坏。

可能有多种原因。如果您使用 Drools 分数计算,它甚至可能是 Drools 中的错误。如果您可以隔离它并使用复制器归档一个 jira,那么我们通常会快速查看它。

隔离方式(按此顺序!):

  1. 删除所有不需要重现它的评分规则
  2. 删除所有不需要重现它的计划实体
  3. 删除重现它不需要的所有步骤。请参阅 Termination.stepCountLimit 以在出错之前保存解决方案,然后从该解决方案开始解决
  4. (可选)删除所有不需要重现它的动作。打开跟踪日志。如果不破解 optaplanner 很难做到这一点,所以我们通常会做这一步。

这是我的实现错误。在增量分数计算器实施方面要准确(或尝试使用 Drools)。