所以我想运行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()
仅返回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)
答案 0 :(得分:1)
我发现了问题。
@PlanningScore(bendableHardLevelsSize = 4, bendableSoftLevelsSize = 1)
public BendableLongScore getScore() {
return score;
}
添加更多级别时,不会更新适当的分数级别。 我不知道错误的声明如何影响Optaplanner。除了(反序列化)之外,这些级别是否还用于其他用途?