Toggle navigation OptaPlanner logo
  • Home
  • Download
  • Learn
    • Documentation
    • Videos
    • Slides
    • Training
    • Use cases
    • Compatibility
    • Testimonials and case studies
  • Get help
  • Source
  • Team
  • Services
  • Star
  • @OptaPlanner
  • Fb
Fork me on GitHub
  • Is the search space of an optimization problem ...
  • Cheating on the N Queens benchmark

Put the user in control of the score constraints

Thu 17 April 2014

Avatar Geoffrey De Smet

Geoffrey De Smet


Twitter LinkedIn GitHub

OptaPlanner lead

OptaPlanner optimizes towards the plan with the best score. But who defines the score function? Normally the developers do, based on the specs of the users. Can we empower users to define the score function themselves? Let’s take a look how.

If we’re using the Drools rule engine for the score calculation in OptaPlanner, then we can use any of the supported features in the Drools ecosystem to manipulate those score rules. That includes Decision Tables, Scorecards and the Drools Workbench web application.

I’ll empower the users on the Cloud Balancing example, for which we need to assign processes to computers, without going above the capacity of any computer. For more information about this example, see this video.

Static DRL rules

As a developer, we can write the score rules statically in the DRL file:

rule "Risk for out of memory"
    when
        CloudComputerUsage(freeMemory < 2)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, -100);
end
rule "Unused memory but no CPU"
    when
        CloudComputerUsage(freeMemory >= 8, freeCpuPower < 4)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, -10);
end

However, DRL files are too difficult for a user to edit directly.

Data driven DRL rules

One way to empower the user, is to create a data object for him/her to fill in:

public class FreePenalty {

    private int minFreeMemory; // Defaults to 0
    private int maxFreeMemory; // Defaults to Integer.MAX_VALUE
    private int minFreeCpuPower; // Defaults to 0
    private int maxFreeCpuPower; // Defaults to Integer.MAX_VALUE
    private int minFreeNetworkBandwidth; // Defaults to 0
    private int maxFreeNetworkBandwidth; // Defaults to Integer.MAX_VALUE

    private int softScoreImpact;

    ...
}

We write 1 rule to apply those FreePenalty instances as score constraints:

rule "requiredCpuPowerTotal"
    when
        // Defined by the user
        FreePenalty(
                $minFreeMemory : minFreeMemory, $maxFreeMemory : maxFreeMemory,
                $minFreeCpuPower : minFreeCpuPower, $maxFreeCpuPower : maxFreeCpuPower,
                $minFreeNetworkBandwidth : minFreeNetworkBandwidth, $maxFreeNetworkBandwidth : maxFreeNetworkBandwidth)
        // Calculated insertlogical from the process assignments
        CloudComputerUsage(
                freeMemory >= $minFreeMemory, freeMemory < $maxFreeMemory,
                freeCpuPower >= $minFreeCpuPower, freeCpuPower < $maxFreeCpuPower,
                freeMemory >= $minFreeNetworkBandwidth, freeMemory < $maxFreeNetworkBandwidth,
                $softScoreImpact : softScoreImpact)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, $softScoreImpact);
end

And of course, we build a web interface so the user can create/update/delete FreePenalty records. So the user can use that UI to create these records:

User creates new FreePenalty(maxFreeMemory = 2, softScoreImpact = -100)
User creates new FreePenalty(minFreeMemory = 8, maxFreeCpuPower = 4, softScoreImpact = -10)

These 2 records result in the same score function as the statically defines score function which we saw earlier, but now the user can change them.

An added advantage of this approach is that the user’s changes are part of the dataset. Multiple datasets, for the exact same Solver configuration, use separate FreePenalty instances. This is especially useful in a multi-tenancy application.

Decision tables

Another way to expose the constraints to the user, is through a Drools decision table. The user edits an xls file with Excel or LibreOffice to change the score function:

decisionTable

Before sending this file to the users, we hide row 2 to 11, so the user isn’t exposed to the technical details.

See this video for a detailed demonstration:

Note that a decision table is more powerful then a data driven DRL rule: the user decides which conditions to apply. The other conditions are not even included (which is faster than checking them against default values).

Rule templates

If data driven DRL rules aren’t powerful enough for you, but a decision table's xls file sticks out like sore thumb in your UI, use Drools rule templates with a custom UI.

Drools Workbench

Workbench (formerly known as Guvnor) is a full blown web application to manage rules and workflows. Using a web interface, business users can create and edit rules, including the score rules used by OptaPlanner.

This is a very interesting setup, which I 'll demonstrate in a future blog post. Meanwhile, for more information, see the Drools documentation.

Conclusion

In OptaPlanner, there are several ways to enable your users to define the score function of their planning problem themselves.

This means that your users can fine tune the score function at runtime, by looking at the result of the Solver, changing the score function and solving it again. Those faster iterations, enables them to evolve the business planning quicker.


Comments Permalink
 tagged as howto feature

Comments

Visit our forum to comment
  • Is the search space of an optimization problem ...
  • Cheating on the N Queens benchmark
Atom News feed
Don't want to miss a single blog post?
Follow us on
  • T
  • Fb
Blog archive
Latest release
  • 8.1.0.Final released
    Fri 15 January 2021
Upcoming events
  • KIE Live
    Worldwide - Tue 19 January 2021
    • OptaPlanner Shadow Variables for the Vehicle Routing Problem and Task Assignment by Geoffrey De Smet, Karina Varela, Alex Porcelli
  • Javaland
    Worldwide - Tue 16 March 2021
    • AI on Quarkus: I love it when an OptaPlan comes together by Geoffrey De Smet
Add event / Archive
Latest blog posts
  • Solve the facility location problem
    Fri 9 October 2020
     Jiří Locker
  • OptaPlanner Week 2020 recordings
    Mon 7 September 2020
     Geoffrey De Smet
  • Let’s OptaPlan your jBPM tasks (part 1) - Integrating the two worlds
    Fri 3 July 2020
     Walter Medvedeo
  • AI versus Covid-19: How Java helps nurses and doctors in this fight
    Fri 8 May 2020
     Christopher Chianelli
  • Workflow processes with AI scheduling
    Tue 5 May 2020
     Christopher Chianelli
  • Constraint Streams - Modern Java constraints without the Drools Rule Language
    Tue 7 April 2020
     Geoffrey De Smet
  • How to plan (and optimize) a Secret Santa
    Wed 18 December 2019
     Christopher Chianelli
Blog archive
Latest videos
  • YT Shadow variables
    Tue 19 January 2021
     Geoffrey De Smet
  • YT Domain modeling and design patterns
    Tue 17 November 2020
     Geoffrey De Smet
  • YT Quarkus insights: AI constraint solving
    Tue 20 October 2020
     Geoffrey De Smet
  • YT AI in kotlin
    Wed 23 September 2020
     Geoffrey De Smet
  • YT Planning agility: continuous planning, real-time planning and more
    Thu 3 September 2020
     Geoffrey De Smet
  • YT Quarkus and OptaPlanner: create a school timetable application
    Thu 3 September 2020
     Radovan Synek
  • YT Business use cases and the impact of OptaPlanner
    Thu 3 September 2020
     Satish Kale
Video archive

KIE projects

  • Drools rule engine
  • OptaPlanner constraint solver
  • jBPM workflow engine

Community

  • Blog
  • Get Help
  • Team
  • Governance
  • Academic research

Code

  • Build from source
  • Submit a bug
  • License (Apache-2.0)
  • Release notes
  • Upgrade recipes
Sponsored by
Red Hat
More coder content at
Red Hat Developers
© Copyright 2006-2021, Red Hat, Inc. or third-party contributors - Privacy statement - Terms of use - Website info