nbaztec
nbaztec

Reputation: 402

Explain all moves in Optaplanner

I'm currently using ObservabilityPhaseListener to hook into the optimization runs. A specific use-case is to debug why a certain combination/move lead to a lower score (and so did not get selected).

Currently, stepEnded is the lowest I can go, but it's already too late since a "bad" move will not be selected and as such never explained.

I've also been using a hack, to perform a move in stepEnded and explaining it, but it's sometimes not feasible or simply too much effort.

Does anyone have an idea on how to accomplish explaining all moves (and their poor scores) as an optimization proceeds?

Thanks.

-- edit: I've managed to implement a custom ScoreDirectoryFactory but having problems plugging it in the config:

class MyScoreDirectorFactory<Solution_>(solutionDescriptor: SolutionDescriptor<Solution_>?, kieContainer: KieContainer?, ksessionName: String?) : DroolsScoreDirectorFactory<Solution_>(solutionDescriptor, kieContainer, ksessionName) {
    @Override
    override fun buildScoreDirector(lookUpEnabled: Boolean, constraintMatchEnabledPreference: Boolean): DroolsScoreDirector<Solution_> {
        return super.buildScoreDirector(lookUpEnabled, true)
    }
}

val config = SolverConfig().apply {
        environmentMode = REPRODUCIBLE
        solutionClass = XYZ::class.java
        entityClassList = listOf(...)

        scoreDirectorFactoryConfig = ScoreDirectorFactoryConfig().apply {
             ... // ?
        }
}

Upvotes: 1

Views: 307

Answers (2)

Geoffrey De Smet
Geoffrey De Smet

Reputation: 27312

humans would often ask why a certain combination was rejected and that's where the broken constraints can come in handy

Let the users make changes in the UI and run the result through ScoreManager.explain(Solution) to display the Score and a heat map of the Indictments.

Upvotes: 2

Geoffrey De Smet
Geoffrey De Smet

Reputation: 27312

For what's it worth (here be dragons!):

Turn on TRACE logging to identify which step index and which move index in that step don't behave like you expect. Put a conditional breakpoint in the LocalSearchDecider with the condition that the step index and move index match (to skip the thousands of move evaluations before you hit that break point). In there, run a code fragment using ScoreManager.explainScore() before and after the move is done (before it is undone).

Upvotes: 1

Related Questions