Runnable examples

One complete script per supported problem class — LP, QP, MILP, MINLP, QUBO, PUBO, NLP — plus a realistic facility-location MILP and a look at how infeasibility comes back. Each script is self-contained:

pip install "quicopt[mathopt]"

The NLP, MINLP, and PUBO examples model in Pyomo — for those, install quicopt[pyomo].

LP — a linear program

Continuous variables, a linear objective, linear constraints. LPs are solved to proven optimality — status: optimal, feasible: true:

lp.py
from ortools.math_opt.python import mathopt
from quicopt import Client

# A linear program: continuous variables, a linear objective, linear constraints.
model = mathopt.Model(name="lp")
x = model.add_variable(lb=0.0, name="x")
y = model.add_variable(lb=0.0, ub=6.0, name="y")
model.add_linear_constraint(x + 2 * y <= 14)
model.add_linear_constraint(3 * x - y >= 0)
model.maximize(3 * x + 4 * y)

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(model)
print(result.display)
$ python lp.py
├── status:     optimal
├── feasible:   true
├── objective:  42.0
├── x:          x=14, y=0  (2 variables)
└── solve_time: 0.0031 s

QP — a quadratic program

A convex quadratic objective under a linear constraint. Unconstrained the optimum would sit at (1, 2); the budget x + y <= 2 pushes it to (0.5, 1.5):

qp.py
from ortools.math_opt.python import mathopt
from quicopt import Client

# A QP: continuous variables, a convex quadratic objective, a linear constraint.
# Unconstrained the optimum would be (1, 2); the constraint x + y <= 2 pushes
# it to (0.5, 1.5) with objective 0.5.
model = mathopt.Model(name="qp")
x = model.add_variable(lb=0.0, name="x")
y = model.add_variable(lb=0.0, name="y")
model.add_linear_constraint(x + y <= 2)
model.minimize((x - 1) * (x - 1) + (y - 2) * (y - 2))

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(model)
print(result.display)
$ python qp.py
├── status:     optimal
├── feasible:   true
├── objective:  0.4999999825141841
├── x:          x=0.5, y=1.5  (2 variables)
└── solve_time: 0.3984 s

MILP — a small mixed-integer program

One continuous and one integer variable under two linear constraints. The LP relaxation would take y = 3.5; integrality bites and the true optimum is x=14, y=0:

milp.py
from ortools.math_opt.python import mathopt
from quicopt import Client

# A tiny mixed-integer model: one continuous and one integer variable.
model = mathopt.Model(name="milp")
x = model.add_variable(lb=0.0, name="x")
y = model.add_integer_variable(lb=0.0, ub=10.0, name="y")
model.add_linear_constraint(x + 2 * y <= 14)
model.add_linear_constraint(3 * x - y >= 0)
model.maximize(3 * x + 4 * y)

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(model)
print(result.display)
$ python milp.py
├── status:     optimal
├── feasible:   true
├── objective:  42.0
├── x:          x=14, y=0  (2 variables)
└── solve_time: 0.0041 s

MILP at a realistic shape — facility location

4 candidate facilities serving 8 customers — 4 binary open/close decisions plus 32 continuous shipping quantities, 36 variables in total. The interesting part is the coupling: a facility may only ship if it is opened, expressed through its capacity constraint sum(ship) <= capacity * open:

facility.py
"""Capacitated facility location as a MILP.

Decisions:
  - y[f] (binary):      is facility f opened?
  - x[f][c] (continuous): quantity shipped from facility f to customer c

Objective: minimize fixed costs of opened facilities + transport costs.
Constraints:
  - every customer's demand must be met exactly
  - a facility may not ship more than its capacity
  - only opened facilities may ship (coupled through the capacity constraint)
"""
from ortools.math_opt.python import mathopt
from quicopt import Client

# --- Deterministic problem instance ---------------------------------------
F = 4   # facilities
C = 8   # customers          ->  F + F*C = 4 + 32 = 36 variables

fixed_cost = [100.0, 120.0, 90.0, 150.0]        # opening cost per facility
capacity   = [60.0, 80.0, 50.0, 100.0]          # capacity per facility
demand     = [10.0, 15.0, 8.0, 12.0, 20.0, 9.0, 14.0, 11.0]   # demand per customer

# Transport cost facility->customer, generated deterministically
trans = [[4.0 + ((f * 7 + c * 3) % 11) for c in range(C)] for f in range(F)]

assert sum(capacity) >= sum(demand), "total capacity does not cover demand"

# --- Model -----------------------------------------------------------------
model = mathopt.Model(name="facility_location")

y = [model.add_binary_variable(name=f"open_{f}") for f in range(F)]
x = [[model.add_variable(lb=0.0, name=f"ship_{f}_{c}") for c in range(C)] for f in range(F)]

# Every customer is served exactly
for c in range(C):
    model.add_linear_constraint(sum(x[f][c] for f in range(F)) == demand[c])

# Capacity + coupling: only opened facilities ship
for f in range(F):
    model.add_linear_constraint(sum(x[f][c] for c in range(C)) <= capacity[f] * y[f])

# Objective: fixed costs + transport costs
model.minimize(
    sum(fixed_cost[f] * y[f] for f in range(F))
    + sum(trans[f][c] * x[f][c] for f in range(F) for c in range(C))
)

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(model)
print(result.display)
$ python facility.py
├── status:     optimal
├── feasible:   true
├── objective:  863.0
├── x:          open_0=1, open_1=1, open_2=1, open_3=0, ship_0_0=10, ship_0_1=15, …  (36 variables)
└── solve_time: 0.0762 s

QUBO — quadratic binary optimization

Binary variables, a quadratic objective, no constraints. QUBOs are solved heuristically over several shots — the status comes back heuristic and feasible is n/a (there are no constraints to satisfy):

qubo.py
from ortools.math_opt.python import mathopt
from quicopt import Client

# A QUBO: 4 binary variables, a quadratic objective, no constraints.
model = mathopt.Model(name="qubo")
x = [model.add_binary_variable(name=f"x{i}") for i in range(4)]

# Reward each variable; penalise adjacent pairs on the 4-cycle 0-1-2-3-0.
# Distinct linear weights break the symmetry, so the optimum is unique.
model.minimize(
    -(1.0 * x[0] + 0.7 * x[1] + 1.3 * x[2] + 0.5 * x[3])
    + 2.0 * (x[0] * x[1] + x[1] * x[2] + x[2] * x[3] + x[0] * x[3])
)

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(model)
print(result.display)
$ python qubo.py
├── shots
│   ├── 1 · Heuristic 1   -2.3   0.0s  ◀ best
│   ├── 2 · Heuristic 2   -2.3   0.0s
│   └── 3 · Heuristic 2   -2.3   0.0s
├── status:     heuristic
├── feasible:   n/a
├── objective:  -2.3
├── x:          x0=1, x1=0, x2=1, x3=0  (4 variables)
└── solve_time: 0.0017 s

PUBO — a higher-order binary polynomial

Binary optimization of degree ≥ 3 — solved as-is, with no reduction to quadratic and no auxiliary variables. This is the LABS problem (low-autocorrelation binary sequences) for N = 7: spins s = 1 - 2x turn the binaries into ±1, and the energy is a degree-four polynomial — the same objective as the LABS benchmark. Modeled in Pyomo (pip install "quicopt[pyomo]"); the returned energy 3 is the proven optimum for N = 7:

pubo.py
import pyomo.environ as pyo
from quicopt import Client

# A PUBO: the LABS problem (low-autocorrelation binary sequences) for N=7.
# Spins s_i = 1 - 2 x_i turn the binary x into +/-1; the energy
# sum_k C_k^2 with C_k = sum_i s_i s_{i+k} is a degree-4 polynomial.
N = 7
m = pyo.ConcreteModel()
m.x = pyo.Var(range(N), domain=pyo.Binary)
s = [1 - 2 * m.x[i] for i in range(N)]
m.obj = pyo.Objective(
    expr=sum(sum(s[i] * s[i + k] for i in range(N - k)) ** 2
             for k in range(1, N)),
    sense=pyo.minimize)

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(m)
print(result.display)
$ python pubo.py
├── status:     heuristic
├── feasible:   true
├── objective:  3.0
├── x:          x1=0, x2=0, x3=0, x4=1, x5=1, x6=0, …  (7 variables)
└── solve_time: 3.5084 s

NLP — a non-linear program

A smooth non-linear objective (exp, log) under a linear constraint, modeled in Pyomo (pip install "quicopt[pyomo]"). The optimum takes y to its lower bound and balances exp(-x) against :

nlp.py
import pyomo.environ as pyo
from quicopt import Client

# An NLP: a smooth non-linear objective (exp, log) under a linear constraint.
m = pyo.ConcreteModel()
m.x = pyo.Var(bounds=(0.1, 10))
m.y = pyo.Var(bounds=(0.1, 10))
m.budget = pyo.Constraint(expr=m.x + m.y <= 8)
m.obj = pyo.Objective(expr=pyo.exp(-m.x) + pyo.log(m.y) + m.x**2, sense=pyo.minimize)

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(m)
print(result.display)
$ python nlp.py
├── status:     optimal
├── feasible:   true
├── objective:  -1.4754011643639007
├── x:          x1=0.3517, x2=0.1  (2 variables)
└── solve_time: 0.0258 s

MINLP — mixed-integer non-linear

Binary on/off decisions mixed with continuous variables under a non-linear (exp) cost curve — a miniature unit-commitment model: switch generating units on or off and set each unit's output to meet demand at minimum cost. Modeled in Pyomo. The best plan switches only the larger unit on. (On the free tier, integer variables beyond binary aren't accepted in non-linear models yet.)

minlp.py
import pyomo.environ as pyo
from quicopt import Client

# An MINLP: switch generating units on or off (binary) and set each unit's
# continuous output, under a non-linear (exp) fuel-cost curve. An off unit
# produces nothing and costs nothing.
caps, fixed, fuel = [4.0, 6.0], [2.0, 3.5], [1.0, 0.8]
demand = 5.0

m = pyo.ConcreteModel()
m.on = pyo.Var(range(2), domain=pyo.Binary)
m.p = pyo.Var(range(2), bounds=(0, None))
m.cap = pyo.Constraint(range(2), rule=lambda m, i: m.p[i] <= caps[i] * m.on[i])
m.demand = pyo.Constraint(expr=m.p[0] + m.p[1] >= demand)
m.obj = pyo.Objective(
    expr=sum(fixed[i] * m.on[i] + fuel[i] * (pyo.exp(m.p[i] / caps[i]) - 1)
             for i in range(2)),
    sense=pyo.minimize)

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(m)
print(result.display)
$ python minlp.py
├── status:     heuristic
├── feasible:   true
├── objective:  4.5407807127338655
├── x:          x1=0, x2=1, x3=0, x4=5.0  (4 variables)
└── solve_time: 2.6109 s

Handling an infeasible model

Infeasibility is a regular result, not an errorsolve() returns normally and you check result.status. This model forces it with two contradictory constraints (sum(x) >= 7 and sum(x) <= 3); objective comes back None and solution is empty:

infeasible.py
"""A linear model that has no feasible solution.

Linear objective over binary variables plus two contradictory constraints
that exclude each other:

    sum(x) >= 7   AND   sum(x) <= 3

No assignment satisfies both -> the model is infeasible.
"""
from ortools.math_opt.python import mathopt
from quicopt import Client

N = 10
model = mathopt.Model(name="infeasible")
x = [model.add_binary_variable(name=f"x{i}") for i in range(N)]

# Linear objective
model.minimize(sum((i + 1) * x[i] for i in range(N)))

# Contradictory constraints -> no feasible solution
model.add_linear_constraint(sum(x[i] for i in range(N)) >= 7)
model.add_linear_constraint(sum(x[i] for i in range(N)) <= 3)

client = Client("https://try.quicoptapi.pgi.fz-juelich.de")
result = client.solve(model)
print(result.display)

if result.status == "infeasible":
    print("No feasible solution — relax a constraint and try again.")
$ python infeasible.py
├── status:     infeasible
├── feasible:   false
├── objective:  —
├── x:          —  (10 variables)
└── solve_time: 0.0054 s

Coming soon

Black-box objectives are on the way. A model outside today's classes is declined with a readable message — never a wrong or half-solved result. If that class is the one that matters to you — or anything else is unclear — talk to us:

Questions? Talk to us.

Tell us what you're optimizing — we'll keep you posted on your problem class.

Talk to us →