在 OptaPlanner 中生成基准报告期间出现 ArrayIndexOutOfBoundsException
ArrayIndexOutOfBoundsException during generating benchmarking report in OptaPlanner
所以我想运行 OptaPlanner 的基准测试,我已经能够针对各种问题(tsp、vrp)成功地实现它。
现在我正在 运行 将其用于更复杂的 vrp,但在生成基准报告期间我遇到了 ArrayIndexOutOfBoundsException
。
// start benchmark
PlannerBenchmarkFactory plannerBenchmarkFactory = PlannerBenchmarkFactory.createFromXmlFile(
new File("src/main/resources/vehiclerouting/benchmark/vrpBenchmarkConfig.xml"));
PlannerBenchmark plannerBenchmark = plannerBenchmarkFactory.buildPlannerBenchmark();
plannerBenchmark.benchmark(); //exception is thrown here.
向下钻取我发现它发生在 writeBestScoreSummaryChart()
中 BenchMarkReport
。
private void writeBestScoreSummaryChart() {
// Each scoreLevel has it's own dataset and chartFile
List<DefaultCategoryDataset> datasetList = new ArrayList<>(CHARTED_SCORE_LEVEL_SIZE);
for (SolverBenchmarkResult solverBenchmarkResult : plannerBenchmarkResult.getSolverBenchmarkResultList()) {
String solverLabel = solverBenchmarkResult.getNameWithFavoriteSuffix();
for (SingleBenchmarkResult singleBenchmarkResult : solverBenchmarkResult.getSingleBenchmarkResultList()) {
String planningProblemLabel = singleBenchmarkResult.getProblemBenchmarkResult().getName();
if (singleBenchmarkResult.hasAllSuccess()) {
double[] levelValues = ScoreUtils.extractLevelDoubles(singleBenchmarkResult.getAverageScore());
for (int i = 0; i < levelValues.length && i < CHARTED_SCORE_LEVEL_SIZE; i++) {
if (i >= datasetList.size()) {
datasetList.add(new DefaultCategoryDataset());
}
datasetList.get(i).addValue(levelValues[i], solverLabel, planningProblemLabel);
}
}
}
}
bestScoreSummaryChartFileList = new ArrayList<>(datasetList.size());
int scoreLevelIndex = 0;
for (DefaultCategoryDataset dataset : datasetList) {
String scoreLevelLabel = plannerBenchmarkResult.findScoreLevelLabel(scoreLevelIndex);
CategoryPlot plot = createBarChartPlot(dataset,
"Best " + scoreLevelLabel, NumberFormat.getInstance(locale));
JFreeChart chart = new JFreeChart("Best " + scoreLevelLabel + " summary (higher is better)",
JFreeChart.DEFAULT_TITLE_FONT, plot, true);
bestScoreSummaryChartFileList.add(writeChartToImageFile(chart, "bestScoreSummaryLevel" + scoreLevelIndex));
scoreLevelIndex++;
}
}
在上面的方法中 datasetList
达到了 7 的大小。(我们有 7 个分数级别 -> 6 个硬,1 个软)。
当在第二个循环中调用 plannerBenchmarkResult.findScoreLevelLabel(scoreLevelIndex);
时 findScoreLevelLabel()
只有 returns 5 个分数级别。即:hard 0 score
、hard 1 score
、hard 2 score
、hard 3 score
和soft 0 score
。
所以一旦 scoreLevelLabel
有一个值 >4
一个 ArrayIndexOutOfBoundsException
被抛出。关于为什么 Optaplanner 注册 5 个分数级别的任何想法/提示,而应该有 7 个。
编辑
堆栈跟踪:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at org.optaplanner.benchmark.impl.result.PlannerBenchmarkResult.findScoreLevelLabel(PlannerBenchmarkResult.java:242)
at org.optaplanner.benchmark.impl.report.BenchmarkReport.writeBestScoreSummaryChart(BenchmarkReport.java:365)
at org.optaplanner.benchmark.impl.report.BenchmarkReport.writeReport(BenchmarkReport.java:241)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmarkingEnded(DefaultPlannerBenchmark.java:306)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmark(DefaultPlannerBenchmark.java:104)
at benchmark.BenchMarker.main(BenchMarker.java:57)
我找到问题了。
@PlanningScore(bendableHardLevelsSize = 4, bendableSoftLevelsSize = 1)
public BendableLongScore getScore() {
return score;
}
添加更多级别后,相应的分数级别未更新。
我不知道错误的声明如何影响 Optaplanner。这些级别是否用于(反)序列化以外的其他用途?
所以我想运行 OptaPlanner 的基准测试,我已经能够针对各种问题(tsp、vrp)成功地实现它。
现在我正在 运行 将其用于更复杂的 vrp,但在生成基准报告期间我遇到了 ArrayIndexOutOfBoundsException
。
// start benchmark
PlannerBenchmarkFactory plannerBenchmarkFactory = PlannerBenchmarkFactory.createFromXmlFile(
new File("src/main/resources/vehiclerouting/benchmark/vrpBenchmarkConfig.xml"));
PlannerBenchmark plannerBenchmark = plannerBenchmarkFactory.buildPlannerBenchmark();
plannerBenchmark.benchmark(); //exception is thrown here.
向下钻取我发现它发生在 writeBestScoreSummaryChart()
中 BenchMarkReport
。
private void writeBestScoreSummaryChart() {
// Each scoreLevel has it's own dataset and chartFile
List<DefaultCategoryDataset> datasetList = new ArrayList<>(CHARTED_SCORE_LEVEL_SIZE);
for (SolverBenchmarkResult solverBenchmarkResult : plannerBenchmarkResult.getSolverBenchmarkResultList()) {
String solverLabel = solverBenchmarkResult.getNameWithFavoriteSuffix();
for (SingleBenchmarkResult singleBenchmarkResult : solverBenchmarkResult.getSingleBenchmarkResultList()) {
String planningProblemLabel = singleBenchmarkResult.getProblemBenchmarkResult().getName();
if (singleBenchmarkResult.hasAllSuccess()) {
double[] levelValues = ScoreUtils.extractLevelDoubles(singleBenchmarkResult.getAverageScore());
for (int i = 0; i < levelValues.length && i < CHARTED_SCORE_LEVEL_SIZE; i++) {
if (i >= datasetList.size()) {
datasetList.add(new DefaultCategoryDataset());
}
datasetList.get(i).addValue(levelValues[i], solverLabel, planningProblemLabel);
}
}
}
}
bestScoreSummaryChartFileList = new ArrayList<>(datasetList.size());
int scoreLevelIndex = 0;
for (DefaultCategoryDataset dataset : datasetList) {
String scoreLevelLabel = plannerBenchmarkResult.findScoreLevelLabel(scoreLevelIndex);
CategoryPlot plot = createBarChartPlot(dataset,
"Best " + scoreLevelLabel, NumberFormat.getInstance(locale));
JFreeChart chart = new JFreeChart("Best " + scoreLevelLabel + " summary (higher is better)",
JFreeChart.DEFAULT_TITLE_FONT, plot, true);
bestScoreSummaryChartFileList.add(writeChartToImageFile(chart, "bestScoreSummaryLevel" + scoreLevelIndex));
scoreLevelIndex++;
}
}
在上面的方法中 datasetList
达到了 7 的大小。(我们有 7 个分数级别 -> 6 个硬,1 个软)。
当在第二个循环中调用 plannerBenchmarkResult.findScoreLevelLabel(scoreLevelIndex);
时 findScoreLevelLabel()
只有 returns 5 个分数级别。即:hard 0 score
、hard 1 score
、hard 2 score
、hard 3 score
和soft 0 score
。
所以一旦 scoreLevelLabel
有一个值 >4
一个 ArrayIndexOutOfBoundsException
被抛出。关于为什么 Optaplanner 注册 5 个分数级别的任何想法/提示,而应该有 7 个。
编辑 堆栈跟踪:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at org.optaplanner.benchmark.impl.result.PlannerBenchmarkResult.findScoreLevelLabel(PlannerBenchmarkResult.java:242)
at org.optaplanner.benchmark.impl.report.BenchmarkReport.writeBestScoreSummaryChart(BenchmarkReport.java:365)
at org.optaplanner.benchmark.impl.report.BenchmarkReport.writeReport(BenchmarkReport.java:241)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmarkingEnded(DefaultPlannerBenchmark.java:306)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmark(DefaultPlannerBenchmark.java:104)
at benchmark.BenchMarker.main(BenchMarker.java:57)
我找到问题了。
@PlanningScore(bendableHardLevelsSize = 4, bendableSoftLevelsSize = 1)
public BendableLongScore getScore() {
return score;
}
添加更多级别后,相应的分数级别未更新。 我不知道错误的声明如何影响 Optaplanner。这些级别是否用于(反)序列化以外的其他用途?