Hacker News new | ask | show | jobs
by nanope 1523 days ago
I’m curious to know how your experience with Optaplanner has been. As I understand you model your problems quite differently and it is more of a search for a good enough solution using metaheuristics?
1 comments

I think Optaplanner has its own DSL, but we use the Java/JVM API: a 'solution' is just a normal JVM object, which references other objects in the usual way. Certain fields are annotated, which tells Optaplanner that it can mutate/alter them.

Implementing the domain objects is pretty natural. The only part that feels weird is that solving is completely based around mutation; whilst that's pretty idiomatic for Java, it feels a bit alien in Scala (I previously worked mostly in Haskell, and haven't written Java in over a decade).

There's a bunch of configuration boilerplate; including the following, which is the only Java code in the whole project (and almost looks like a parody of "Enterprise Java"!):

    class Config {
        public static ScoreDirectorFactoryConfig config =
            (new ScoreDirectorFactoryConfig())
            .withEasyScoreCalculatorClass(ScoreCalculator.class);
    }
IIRC, this had to be Java due to some weird self-referential interface that makes Scala's type-checker explode.

We can give each solution both a "hard" score and a "soft" score, where the soft score will be sacrificed if it improves the hard score. We use the hard score to count errors which make a solution invalid (e.g. trying to assign two people to the same seat); and the soft score as a weighted sum of mismatched seat attributes (e.g. it would be nice to stay facing the same direction; but not crucial).

Once the problem has been defined, it can be sent to a bunch of solvers; we use simulated annealing with a timeout. Since it's an anytime-algorithm, we can adjust the timeout to however long we're prepared to wait.

To avoid "obvious" problems in Optaplanner's results, we send them through a simple hill-climbing loop to ensure we're at a local maximum.