Search code examples
drools-planner

getting list of broken constraints for final best solution in drools-planner


I'm using drools-planner-5.4.0.CR1 and I wanna get list of broken constraints for final best solution

and also looked of examples of 5.4.0.CR1

I've implemented like in example but it returns empty list, in other words getScoreDetailList().size() is equal to 0, but solution.getScore() is equal to -54.

is there any suggestions?

public class SomeClass {
...
private volatile Solver solver;
private ScoreDirector scoreDirector;
...
public void someMethod() {
    SolverFactory solverFactory = new XmlSolverFactory(SOLVER_CONFIG);
    solver = solverFactory.buildSolver();
    scoreDirector = solver.getScoreDirectorFactory().buildScoreDirector();
    ...
    this.scoreDirector.setWorkingSolution(solution);
    this.solver.setPlanningProblem(this.scoreDirector.getWorkingSolution());
    this.solver.solve();

    SomeSolution solution = (SomeSolution) solver.getBestSolution();
    this.scoreDirector.setWorkingSolution(solution);
    System.out.println( "Score: " + solution.getScore());
    System.out.println( "getScoreDetailList size:" + getScoreDetailList().size());
}

public List<ScoreDetail> getScoreDetailList() {
    if (!(scoreDirector instanceof DroolsScoreDirector)) {
        return null;
    }
    Map<String, ScoreDetail> scoreDetailMap = new HashMap<String, ScoreDetail>();
    WorkingMemory workingMemory = ((DroolsScoreDirector) scoreDirector).getWorkingMemory();
    if (workingMemory == null) {
        return Collections.emptyList();
    }
    Iterator<ConstraintOccurrence> it = (Iterator<ConstraintOccurrence>) workingMemory.iterateObjects(
            new ClassObjectFilter(ConstraintOccurrence.class));
    while (it.hasNext()) {
        ConstraintOccurrence constraintOccurrence = it.next();
        ScoreDetail scoreDetail = scoreDetailMap.get(constraintOccurrence.getRuleId());
        if (scoreDetail == null) {
            scoreDetail = new ScoreDetail(constraintOccurrence.getRuleId(), constraintOccurrence.getConstraintType());
            scoreDetailMap.put(constraintOccurrence.getRuleId(), scoreDetail);
        }
        scoreDetail.addConstraintOccurrence(constraintOccurrence);
    }
    List<ScoreDetail> scoreDetailList = new ArrayList<ScoreDetail>(scoreDetailMap.values());
    Collections.sort(scoreDetailList);
    return scoreDetailList;
}
}

Solution

  • After

    this.scoreDirector.setWorkingSolution(solution);
    

    you forgot to call

    this.scoreDirector.calculateScore();
    

    I 'll docs about using Solver.getScoreDirectorFactory() in 5.4.0.Final.