optaplanners toList ConstraintCollector 有错误吗?

Has optaplanners toList ConstraintCollector a bug?

在 optaplanner 8.1 中使用 toList() ConstraintCollector 时,例如:

factory.from(Lesson.class)
          .groupBy(Lesson::getCourse, ConstraintCollectors.toList()).penalize(...);

我运行进入:

Exception executing consequence for rule "foo" in model: java.lang.ClassCastException: class model.Lesson cannot be cast to class java.util.List (model.Lesson is in unnamed module of loader 'app'; java.util.List is in module java.base of loader 'bootstrap')
    at org.drools.core.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39)

问题:这是 optaplanner 的错误,还是我的代码有误?


我找到的最简单的完整复制器是:

@PlanningSolution
public class OptaplannerIssue2 implements ConstraintProvider {

  @Override
  public Constraint[] defineConstraints(ConstraintFactory factory) {
    return new Constraint[] {factory.from(IssueEntity.class)
        .groupBy(IssueEntity::getValue, ConstraintCollectors.toList())
        .penalize("x", HardSoftScore.ofHard(1), (entity, enityList) -> 2)};
  }

  @PlanningScore
  private HardSoftScore score = HardSoftScore.ZERO;

  @PlanningEntityCollectionProperty
  private final List<IssueEntity> entities = new ArrayList<IssueEntity>();

  public List<IssueEntity> getEntities() {
    return entities;
  }

  @ValueRangeProvider(id = "valueRange")
  public CountableValueRange<Integer> getValueRange() {
    return ValueRangeFactory.createIntValueRange(0, 4);
  }

  public static void main() {
    // create Entity
    OptaplannerIssue2 issue = new OptaplannerIssue2();
    IssueEntity e1 = new IssueEntity();
    issue.entities.add(e1);

    // solve
    SolverFactory<OptaplannerIssue2> solverFactory = SolverFactory.create(new SolverConfig()
        .withEnvironmentMode(EnvironmentMode.FULL_ASSERT).withSolutionClass(OptaplannerIssue2.class)
        .withEntityClasses(IssueEntity.class)
        .withScoreDirectorFactory(
            new ScoreDirectorFactoryConfig().withConstraintProviderClass(OptaplannerIssue2.class))
        .withTerminationConfig(new TerminationConfig().withSecondsSpentLimit(5L)).withPhases(
            new ConstructionHeuristicPhaseConfig()
                .withConstructionHeuristicType(ConstructionHeuristicType.FIRST_FIT),
            new LocalSearchPhaseConfig().withLocalSearchType(LocalSearchType.LATE_ACCEPTANCE)));
    Solver<OptaplannerIssue2> solver = solverFactory.buildSolver();
    solver.solve(issue);
  }
}

具有以下实体-class:

@PlanningEntity
public class IssueEntity {

  @PlanningVariable(valueRangeProviderRefs = {"valueRange"})
  Integer value;

  public Integer getValue() {
    return value;
  }
}

在相关主题中:Optaplanner GroupBy with toList not working as expected提问者没有向试图提供帮助的评论员提供所有信息,当我在那里提供复制者时我被删除了,所以我不得不问新问题。

您描述的行为是 OptaPlanner 中的一个错误,我们现已修复。请升级到 OptaPlanner 的下一版本,在撰写此答案时将为 OptaPlanner 8.2.0。

详情见PLANNER-2305