ScoreAttained条件抛出算术异常 - OptaPlanner

时间:2014-02-25 23:17:34

标签: exception math optaplanner

使用HARDSOFTBIGDECIMAL得分。

在配置文件中,我将scoreAttained设置为0hard / 0soft。

我收到此错误:

Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(Unknown Source)
at org.optaplanner.core.impl.score.buildin.hardsoftbigdecimal.HardSoftBigDecimalScoreDefinition.calculateTimeGradient(HardSoftBigDecimalScoreDefinition.java:96)
at org.optaplanner.core.impl.score.buildin.hardsoftbigdecimal.HardSoftBigDecimalScoreDefinition.calculateTimeGradient(HardSoftBigDecimalScoreDefinition.java:27)
at org.optaplanner.core.impl.termination.ScoreAttainedTermination.calculateSolverTimeGradient(ScoreAttainedTermination.java:50)
at org.optaplanner.core.impl.termination.OrCompositeTermination.calculateSolverTimeGradient(OrCompositeTermination.java:69)
at org.optaplanner.core.impl.termination.OrCompositeTermination.calculateSolverTimeGradient(OrCompositeTermination.java:69)
at org.optaplanner.core.impl.termination.PhaseToSolverTerminationBridge.calculatePhaseTimeGradient(PhaseToSolverTerminationBridge.java:80)
at org.optaplanner.core.impl.localsearch.DefaultLocalSearchSolverPhase.solve(DefaultLocalSearchSolverPhase.java:60)
at org.optaplanner.core.impl.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:190)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:155)

编辑:

通过扩展HARDSOFTBIGDECIMALSCOREDEFINITION并覆盖calculateTimeGradient(..)方法解决了这个问题。在BigDecimal上调用divide方法时,我向上舍入。

1 个答案:

答案 0 :(得分:1)

你很可能将两个具有无限精确商数的数字分开。

例如:1/3 = 0.33333...

来自docs

  

提供MathContext对象时,精度设置为0   (例如,MathContext.UNLIMITED),算术运算是精确的,   不带MathContext对象的算术方法也是如此。 (这个   是5之前版本中唯一支持的行为。)

     

作为计算确切结果的推论,舍入模式   设置精度设置为0的MathContext对象不是   使用,因而无关紧要。在除法的情况下,确切的商   可以有一个无限长的十进制扩展;例如,1   除以3。

     

如果商具有非终止的十进制扩展和   指定操作以返回精确结果,a   抛出ArithmeticException。否则,确切的结果   如同其他操作一样,返回除法。

所以要解决这个问题,你需要为BigDecimal提供一个精度等级,如下所示:

x.divide(y, 2, RoundingMode.HALF_UP)

其中2是精度,RoundingMode.HALF_UP是舍入模式。

您可以阅读有关舍入here的更多信息。