Mixed Integer Programming

A tool to consider.

 

By Marco Neumann.

Why

An practical example.

K8s Pod Placement

Cluster

Node

Node

Pod

Pod

Pod

Solver

Find a solution.

SAT Solver

Variables

  • boolean (true/false; 1/0)
  • what we want

 

Constraints

  • depending on solver:
    • boolean
    • linear integers (= pseudo-boolean)
    • ...
  • what we know

Knapsack

Node 1 Node 2
Pod A ∑=0 = 1
Pod B ∑=0 = 1
Pod C ∑=0 = 1
∑=0 ≤ 5 ∑=0 ≤ 5

Cluster

Node

Node

Knapsack

Node 1 Node 2
Pod A ∑=1 = 1
Pod B ∑=0 = 1
Pod C ∑=0 = 1
∑=1 ≤ 5 ∑=0 ≤ 5

Cluster

Node

Node

Pod A

Knapsack

Node 1 Node 2
Pod A ∑=2 = 1
Pod B ∑=0 = 1
Pod C ∑=0 = 1
∑=1 ≤ 5 ∑=0 ≤ 5

Cluster

Node

Node

Pod A

Pod A

Knapsack

Node 1 Node 2
Pod A ∑=0 = 1
Pod B ∑=0 = 1
Pod C ∑=0 = 1
∑=6 ≤ 5 ∑=0 ≤ 5

Cluster

Node

Node

Pod B

Pod C

Pod A

Knapsack

Node 1 Node 2
Pod A ∑=1 = 1
Pod B ∑=1 = 1
Pod C ∑=1 = 1
∑=4 ≤ 5 ∑=2 ≤ 5

Cluster

Node

Node

Pod B

Pod C

Pod A

NP-Completeness

Roughly: The problem is so hard that you have to enumerate all solutions.

 

Math: Exponential complexity.

😱

Knapsack is NP-complete.

Most real instances are NOT.

Solvers are VERY fast.

😅

Over-Constrained

Optimizer

Find best solution.

Inputs

Constraints

  • equation ≤ constant
  • linear
  • quadratic
  • ... depending on optimizer

 

Target Function

min/max equation:

  • linear
  • quadratic
  • ... depending on optimizer

Most solvers are numeric!

Multiple Target Functions

Weight-based

Unit-based

 

e.g. express cost in €

100 \cdot c_\textrm{nodes} + 25 \cdot c_\textrm{movement}
c_\textrm{nodes}

Cost of running nodes

c_\textrm{movement}

Discruption by moving existing pods

Tricks

c_n = \begin{cases} a &\textrm{ if } |\textrm{pods on node}| > 0 \\ 0 &\textrm{ if } |\textrm{pods on node}| = 0 \end{cases}
c_n = ay_n \\ y_n \textrm{ binary} \\ |\textrm{pods on node}| \leq y_n \left( |\textrm{pods}| + 1 \right)

Implementation

Actually implementing it.

Code

YAML

serde

Rust struct

good_lp

problem gen

SCIP

interprete

YAML

serde

Rust struct

⚠️ prototype code ⚠️

Input

nodes:
  n1:
    cpu: 2.0
    memory: 16.0
    cost: 50.0
  n2:
    cpu: 1.0
    memory: 32.0
    cost: 200.0
  n3:
    cpu: 1.0
    memory: 32.0
    cost: 100.0
pods:
  p1:
    cpu: 0.5
    memory: 10.0
    movement_cost: 200.0
    current_node: n2
  p2:
    cpu: 1.0
    memory: 8.0
  p3:
    cpu: 1.0
    memory: 8.0
  p4:
    cpu: 0.5
    memory: 2.0

Demo

Summary

Wrap-up & alternatives.

Approaches

Manual

 

  • low barrier
  • potentially better if sufficiently tuned
  • most people will end up with semi-optimal heuristics
  • harder to maintain & extend

Existing Optimizer

 

  • provides structured approach
  • easy to extend
  • extensive set of optimizer passes
  • requires modelling knowledge

Choose The Right Solver

Open Source

Proprietary

Choose The Right Tool

Use the "tightest" fitting tool!

 

Alternatives

  • Cannot describe solution space
    ⇒ Genetic Programming, Metaheuristic
     
  • Solver only, but more complex data types
    ⇒ SMT (Satisfiability Modulo Theories) Solver

???

Mixed Integer Programming

By Marco Neumann

Mixed Integer Programming

  • 39