Presentation instructions

  • Press right arrow key to go to the first real slide
  • Press escape key for an overview of all slides

Tips:

OptaPlanner

Do more business
with less resources

by Geoffrey De Smet

What is business resource optimization?

demo

Traveling Salesman Problem (TSP)

TSP
is an academic problem

What is realistic
business resource optimization?

VRP demo

What is a planning problem?

  • Complete goals
  • With limited resources
  • Under constraints

Planning problem use cases

  • Agenda scheduling: doctor appointments, court hearings,
    maintenance jobs, TV advertisements, ...
  • Educational timetabling: lectures, exams, conference presentations, ...
  • Task assignment: affinity/skill matchmaking for tax audits, wage calc, ...
  • Employee shift rostering: nurses, repairmen, help desk, firemen, ...
  • Vehicle routing: route trucks, buses, trains, boats, airplanes, VIP escorts, ...
  • Bin packing: fill containers, trucks, ships, storage warehouses,
    cloud computers nodes, prisons, hospitals, ...
  • Job shop scheduling: assembly lines for cars, furniture, books, ...
  • Cutting stock: minimize waste while cutting paper, steel, carpet, ...
  • Sport scheduling: football/baseball league, tennis court utilization, ...
  • Financial optimization: investment portfolio balance, risk spreading, ...

Are planning problems
difficult to solve?

What is business resource optimization?

Cloud Balancing demo

Find optimal solution and scale out
for an NP-complete problem?

⇔ Is P = NP?

  • Unresolved since 1971
  • 1 000 000 $ reward since 2000
  • Most believe P ≠ NP
    • Impossible to find optimal solution and scale out
  • 3000+ known NP-complete problems (wikipedia)

Planning problems are
difficult to solve!

And human aren't good at it

But they don't realize it
(nor does their manager)

Reuse optimization algorithms

Find better solutions in time and scale out

  • Open source
    Apache License
  • Regular releases
    Download the zip or from Maven Central
  • Documented
    Reference manual, examples, ...
  • Quality coverage
    Unit, integration and stress tests

Cloud Balancing example

Domain model

Computer

public class Computer {

  private int cpuPower;
  private int memory;
  private int networkBandwidth;

  private int cost;

  // getters
}

Process is a planning entity

@PlanningEntity
public class Process {

  private int requiredCpuPower;
  private int requiredMemory;
  private int requiredNetworkBandwidth;

  // getters

  ...
}

Process has a planning variable

@PlanningEntity
public class Process {
  ...

  private Computer computer;

  @PlanningVariable(valueRangeProviderRefs = {"computerRange"})
  public Computer getComputer() {
    return computer;
  }
  public void setComputer(Computer computer) {
    this.computer = computer;
  }

}

Solution CloudBalance

public class CloudBalance implements Solution<HardSoftScore> {

  private List<Computer> computerList;
  private List<Process> processList;

  @ValueRangeProvider(id = "computerRange")
  public List<Computer> getComputerList() {
    return computerList;
  }

  @PlanningEntityCollectionProperty
  public List<Process> getProcessList() {
    return processList;
  }

  ...
}

Solution CloudBalance: score

public class CloudBalance implements Solution<HardSoftScore> {
  ...

  private HardSoftScore score;

  public HardSoftScore getScore() {
    return score;
  }
  public void setScore(HardSoftScore score) {
    this.score = score;
  }

}

Cloud Balancing example

Score constraints

Given 2 solutions
which one is better?

Score calculation

  • Easy Java
  • Incremental Java
  • Drools

Easy Java score calculation

  • Easy to implement
  • Bridge an existing system
  • Slow
public class CloudBalancingEasyScoreCalculator
    implements EasyScoreCalculator<CloudBalance> {

  public Score calculateScore(CloudBalance cb) {
    ...
    return HardSoftScore.valueOf(hardScore, softScore);
  }

}

Incremental Java score calculation

  • Fast
    • Solution changes ⇒ recalculate score delta only
  • Hard to implement
    • Much boilerplate code

Drools score calculation

  • Incremental
    • No boilerplate code
  • Constraints in Drools Rule Language (DRL)
    • Declarative (like SQL, regular expression)
  • Integration opportunities
    • Drools Workbench
    • Decision tables

Solution CloudBalance: getProblemFacts()

public class CloudBalance implements Solution<HardSoftScore> {

  private List<Computer> computerList;
  private List<Process> processList;
  ...

  // Used in Drools score rules (DRL)
  public Collection<Object> getProblemFacts() {
    List<Object> facts = new ArrayList<Object>();
    facts.addAll(computerList);
    return facts;
  }

  ...
}

DRL soft constraint: computer cost

rule "computerCost"
  when
    // there is a computer
    $s : Computer($c : cost)
    // there is a processes on that computer
    exists Process(computer == $s)
  then
    // lower soft score by the maintenance cost
    scoreHolder.addSoftConstraintMatch(kcontext, - $c);
end

DRL hard constraint: CPU power

rule "requiredCpuPowerTotal"
  when
    // there is a computer
    $s : Computer($cpu : cpuPower)
    // with too little cpu for its processes
    $total : Number(intValue > $cpu) from accumulate(
      Process(computer == $s, $requiredCpu : requiredCpuPower),
      sum($requiredCpu)
    )
  then
    // lower hard score by the excessive CPU usage
    scoreHolder.addHardConstraintMatch(kcontext,
        $cpu - $total.intValue());
end

Score calculation must be flexible

  • Optimal solution for almost your business problem is useless
  • Model supports:
    • Reusing existing classes
    • Rich, OO class hierarchies (including polymorphism)
  • Constraints supports:
    • Any constraint (no linear or quadratic restrictions!)
    • Reusing existing code
  • Scoring supports:
    • Positive/negative mix
    • Score weights
    • Unlimited score levels

Cloud Balancing example

Solving it

Solver configuration by XML

<solver>
  <solutionClass>...CloudBalance</solutionClass>
  <entityClass>...Process</entityClass>

  <scoreDirectorFactory>
    <scoreDefinitionType>HARD_AND_SOFT</scoreDefinitionType>
    <scoreDrl>...ScoreRules.drl</scoreDrl>
  </scoreDirectorFactory>

  <!-- optimization algorithms -->
</solver>

Solving

SolverFactory factory = SolverFactory.createFromXmlResource(
    "...SolverConfig.xml");
Solver solver = factory.buildSolver();

solver.solve(cloudBalance);
cloudBalance = (CloudBalance) solver.getBestSolution();

Cloud Balancing example

Optimization algorithms

Brute force config

<solver>
  ...

  <exhaustiveSearch>
    <exhaustiveSearchType>BRUTE_FORCE</exhaustiveSearchType>
  </exhaustiveSearch>
</solver>

Brute force scalability

Plan 1200 processes with brute force?


First Fit config

<solver>
  ...

  <constructionHeuristic>
    <constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
  </constructionHeuristic>
</solver>

First Fit scalability

First Fit results

All hard constraints satisfied: maintenance cost shown

First Fit Decreasing config

<solver>
  ...

  <constructionHeuristic>
    <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
  </constructionHeuristic>
</solver>

DifficultyComparator

public class ProcessDifficultyComparator
    implements Comparator<Process> {
  public int compare(Process a, Process b) {
    // Compare on requiredCpuPower * requiredMemory
    //     * requiredNetworkBandwidth
  }
}

@PlanningEntity(difficultyComparatorClass
    = ProcessDifficultyComparator.class)
public class Process  {
  ...
}

First Fit Decreasing scalability

First Fit Decreasing results

Construction Heuristics + Local Search

<solver>
  ...

  <constructionHeuristic>
    <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
  </constructionHeuristic>
  <localSearch>
    ...
  <localSearch>
</solver>

Hill Climbing config

<localSearch>
  <forager>
    <!-- Untweaked standard value -->
    <acceptedCountLimit>1000</acceptedCountLimit>
  </forager>
</localSearch>

Tabu Search config

<localSearch>
  <acceptor>
    <!-- Typical standard value -->
    <entityTabuSize>7</entityTabuSize>
  </acceptor>
  <forager>
    <!-- Typical value -->
    <acceptedCountLimit>1000</acceptedCountLimit>
  </forager>
</localSearch>

Simulated Annealing config

<localSearch>
  <acceptor>
    <!-- Tweaked value -->
    <simulatedAnnealingStartingTemperature>
        0hard/400soft
    </simulatedAnnealingStartingTemperature>
  </acceptor>
  <forager>
    <!-- Typical value -->
    <acceptedCountLimit>4</acceptedCountLimit>
  </forager>
</localSearch>

Late Acceptance config

<localSearch>
  <acceptor>
    <!-- Typical standard value -->
    <lateAcceptanceSize>400</lateAcceptanceSize>
  </acceptor>
  <forager>
    <!-- Typical value -->
    <acceptedCountLimit>4</acceptedCountLimit>
  </forager>
</localSearch>

Local Search results

Cost ($) reduction

Optimization algorithms

  • Exhaustive Search
    • Brute Force
    • Branch And Bound
  • Construction Heuristics
    • First Fit (Decreasing)
    • Weakest/Strongest Fit (Decreasing)
    • Cheapest Insertion
  • Local Search
    • Hill Climbing
    • Tabu Search
    • Strategic Oscillation Tabu Search
    • Simulated Annealing
    • Late Acceptance
    • Step Counting Hill Climbing

Benchmark results

Demo

Repeated planning:
continuous/real-time

Continuous planning demo

Nurse rostering demo

Summary

  • OptaPlanner solves planning and scheduling problems
  • Adding constraints: easy and scalable
  • Switching/combining optimization algorithms: easy

Build from source

$ git clone git@github.com:droolsjbpm/optaplanner.git
...
$ cd optaplanner
$ mvn clean install -DskipTests
...
$ cd optaplanner-examples
$ mvn exec:exec
...

Q & A


Introduction to
heuristics and metaheuristics
for
business resource optimization

by Geoffrey De Smet

N Queens demo

demo

Simplified problem

N Queens

  • Place n queens on a n sizes chessboard
  • No 2 queens can attach each other

Bad

Good

  • Imperfect example
    • Not NP-complete (shortcuts exist)
    • Score function is too simple (too black and white)

What solution is better?

  • Need for objective scoring
  • Better score ⇔ better solution
  • Highest score ⇔ optimal solution

N Queens

  • Hard constraints:
    • -1 for every pair of conflicting queens
  • Soft constraints:
    • None

Score = -2

Conflicts: A-B, B-D

Score = 0

No conflicts

How do we find the best solution?

  • Need for optimization algorithms
  • Best solution in available time

Brute Force scalability

8 queens = 15.7 seconds
9 queens = 2.5 minutes (times 10)
10 queens = 0.83 hours (times 20)

How many combinations for 100 queens?

  • 1 queen per column
  • 100 queens ⇒ 100 variables
  • 100 rows ⇒ 100 values per variable

Source: NASA (wikipedia)

> humans?
7 000 000 000

How many combinations for 100 queens?

  • 1 queen per column
  • 100 queens ⇒ 100 variables
  • 100 rows ⇒ 100 values per variable

Source: NASA and ESA (wikipedia)

> minimum atoms
in the observable universe?
1080

How many combinations for 100 queens?

  • 1 queen per column
  • 100 queens ⇒ 100 variables
  • 100 rows ⇒ 100 values per variable

100100 = 10200

1 0000000000 0000000000 0000000000 0000000000 0000000000
  0000000000 0000000000 0000000000 0000000000 0000000000
  0000000000 0000000000 0000000000 0000000000 0000000000
  0000000000 0000000000 0000000000 0000000000 0000000000

How many combinations for n queens?

  • 1 queen per column
  • n queens ⇒ n variables
  • n rows ⇒ n values per variable

nn

|valueSet||variableSet|

How long?

Presume 109 scores/ms ⇒ 1020 scores/year

Queens Combinations Calculation time
100 100100 = 10200 10180 years
1000 10001000 = 103000 102980 years
10000 1000010000 = 1040000 1039980 years

Moore's law == a drop in the ocean

Exhaustive Search doesn't scale

  • Branches explode exponentially
  • Not enough CPU
  • Not enough memory

Move types

  • Change move
  • Swap move
  • ...

All change moves

n # moves # solutions
4 16 256
8 64 16777216
64 4096 10116
n n2 nn

Multiple moves

Multiple moves can reach any solution

Performance tricks

Reuse existing business code

public class Nurse {

  private Country country;

  public boolean isHoliday(Date date) {
    if (country == Country.BE) {
      // true if date is 1-JAN, easter monday, 21-JUL, ...
    } else if (country == Country.FR) {
      // true if date is 1-JAN, easter monday, 14-JUL, ...
    } else if (...) {
      ...
    }
    ...
  }

}

Q & A