Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OptaPlanner';腐败的神话分数_Java_Optimization_Optaplanner - Fatal编程技术网

Java OptaPlanner';腐败的神话分数

Java OptaPlanner';腐败的神话分数,java,optimization,optaplanner,Java,Optimization,Optaplanner,我对我的模型使用增量分数计算器。在“完全断言”模式下进行数小时/数天的优化后,将抛出分数损坏异常: java.lang.IllegalStateException: Score corruption: the workingScore (-86591/-2765/-422/-591) is not the uncorruptedScore (-86591/-2873/-422/-591) after completedAction [...]: Uncorrupted: Score calcul

我对我的模型使用增量分数计算器。在“完全断言”模式下进行数小时/数天的优化后,将抛出分数损坏异常:

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]
这就是参数
TimeLineGapScore
中的分数不同。分数实例是从分数计算器对象字段
prioritizesscore
timelinegapscore
requirementgapscore
timelineversionscore
创建的。根据日志,这两个分数的实例在这些字段中是相等的,但optaplanner引擎发现了差异(-86591/-2765/-422/-591)与(-86591/-2873/-422/-591)。这怎么可能

我怀疑在解决方案克隆(它的具体实现和深度复制)上存在引用泄漏,但仔细的代码检查并没有显示此类错误

UPD:我忘了提到:optaplanner在守护程序模式下运行,模型能够实时更改事实。所以我怀疑模型中的种族条件。但我不知道在optaplanner的保护下如何实现变化(信息不够)。

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

例如,如果一个皇后a从第1行移动到第2行,它就不需要检查皇后B和皇后C是否可以互相攻击,因为它们都没有改变。”

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

可能有几个原因。如果您使用Drools分数计算,它甚至可能是Drools中的一个bug。如果你能把它分离出来,用复制机归档一份jira,那么我们通常会很快给你看

隔离意味着(按此顺序!):

  • 删除所有不需要复制的分数规则
  • 删除所有不需要复制的规划实体
  • 删除复制它不需要的所有步骤。请参阅Termination.stepCountLimit以在解决方案出错之前保存该解决方案,然后从该解决方案开始求解
  • (可选)删除不需要复制的所有移动。打开跟踪日志。这是很难做到的没有黑客optaplanner,所以我们通常做这一步

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

    我使用普通Java分数计算器而不是Drools,不幸的是,这段代码是高度耦合的。根据日志,optaplanner将原始解决方案S0克隆到S1,然后在S0上执行几个步骤,这些步骤从逻辑上导致初始解决方案(例如,交换移动AB、BA、AC、CA),然后检查分数等价性分数(S0)=分数(S1)。当然,在我的例子中,这样的等式是成立的,但是分数实例是不同的,尽管我使用简单的代码创建分数:
    return BendableScore.valueOf(new int[]{requirementgapscore,timelinegapscore},new int[]{priorityesscore,timelineversionscore})
    使用
    EasyJavaScoreCalculator
    ,分数损坏是不可能的。我猜您正在使用
    增量JavaScoreCalculator
    ?很高兴听到Drools中没有bug:)在NQueens示例实现中,在sandwished的情况下,B和C被认为是相互攻击的。但即使sandswish并没有攻击要求,您也可以通过跟踪sandswish状态来进行增量计算以更好地扩展。@GeoffreyDeSmet我为问题添加了细节。顺便说一句,关于文档:误导:calculateScore()调用不是在每次交换移动之后。在实时模型更改的描述中可能存在类似的错误:)OptaPlanner可以跳过
    calculateScore()
    ,如果它不需要它(或者它可以预测它),以提高性能,因此我可以在调用
    calculateScore()
    之前先做几步。如果使用CompositeMove(例如,如果您的实体上有2个变量),则这一点更为重要。只要您正确使用
    addProblemFactChange()
    修改解算器中的模型(因为该回调在解算器线程内执行),就不可能出现争用条件。请注意
    addProblemFactChange()
    确实可能很棘手。它通常需要进行更深入的克隆,而不仅仅是计划中的克隆。例如,要在CB示例中添加新计算机,需要克隆computerList(这在计划克隆中不会发生)。