Model

PyEPO supports end-to-end predict-then-optimize with linear objective functions and unknown cost coefficients. At its core is the differentiable optimization solver, which computes gradients of the cost coefficients with respect to the optimal solution.

optModel is the base abstraction in PyEPO. It wraps an optimization solver or algorithm as a container, providing a unified interface for training and evaluation. PyEPO provides several pre-defined models using GurobiPy, Pyomo, COPT, OR-Tools, and MPAX:

  • Shortest path (GurobiPy, Pyomo, COPT, OR-Tools & MPAX)

  • Knapsack (GurobiPy, Pyomo, COPT, OR-Tools & MPAX)

  • Traveling salesman (GurobiPy, Pyomo & COPT)

  • Portfolio optimization (GurobiPy, Pyomo & COPT)

When building models with PyEPO, users do not need to specify the cost coefficients, since they are unknown and will be predicted from data.

For more details, see the 01 Optimization Model notebook.

User-defined Models

Users can define custom optimization problems with linear objective functions. PyEPO provides several ways to do this:

  1. GurobiPy-based: Inherit from optGrbModel and implement _getModel.

  2. Pyomo-based: Inherit from optOmoModel and implement _getModel.

  3. COPT-based: Inherit from optCoptModel and implement _getModel.

  4. OR-Tools-based: Inherit from optOrtModel (pywraplp) or optOrtCpModel (CP-SAT) and implement _getModel.

  5. MPAX-based: Inherit from optMpaxModel and provide constraint matrices A, b, G, h.

  6. From scratch: Inherit from optModel and implement _getModel, setObj, solve, and num_cost.

The optModel interface consists of:

  • _getModel: Build and return the optimization model and decision variables.

  • setObj: Set the objective function with a given cost vector.

  • solve: Solve the problem and return the optimal solution and objective value.

User-defined GurobiPy Models

To define a GurobiPy model, inherit from pyepo.model.grb.optGrbModel and implement the _getModel method. The model sense (minimize/maximize) is automatically detected from the GurobiPy model.

class pyepo.model.grb.optGrbModel

This is an abstract class for a Gurobi-based optimization model

_model

Gurobi model

Type:

GurobiPy model

__init__()
abstract _getModel()

An abstract method to build a model from an optimization solver

Returns:

optimization model and variables

Return type:

tuple

property num_cost

number of costs to be predicted

relax()

An unimplemented method to relax the MIP model

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

For example, consider the following binary optimization problem:

\[\begin{split}\begin{aligned} \max_{x} & \sum_{i=0}^4 c_i x_i \\ s.t. \quad & 3 x_0 + 4 x_1 + 3 x_2 + 6 x_3 + 4 x_4 \leq 12 \\ & 4 x_0 + 5 x_1 + 2 x_2 + 3 x_3 + 5 x_4 \leq 10 \\ & 5 x_0 + 4 x_1 + 6 x_2 + 2 x_3 + 3 x_4 \leq 15 \\ & \forall x_i \in \{0, 1\} \end{aligned}\end{split}\]

Users only need to implement the _getModel method:

import random

import gurobipy as gp
from gurobipy import GRB

from pyepo.model.grb import optGrbModel

class myModel(optGrbModel):

    def _getModel(self):
        # create a model
        m = gp.Model()
        # variables
        x = m.addVars(5, name="x", vtype=GRB.BINARY)
        # model sense
        m.modelSense = GRB.MAXIMIZE
        # constraints
        m.addConstr(3 * x[0] + 4 * x[1] + 3 * x[2] + 6 * x[3] + 4 * x[4] <= 12)
        m.addConstr(4 * x[0] + 5 * x[1] + 2 * x[2] + 3 * x[3] + 5 * x[4] <= 10)
        m.addConstr(5 * x[0] + 4 * x[1] + 6 * x[2] + 2 * x[3] + 3 * x[4] <= 15)
        return m, x

myoptmodel = myModel()
cost = [random.random() for _ in range(myoptmodel.num_cost)] # random cost vector
myoptmodel.setObj(cost) # set objective function
myoptmodel.solve() # solve

User-defined Pyomo Models

To define a Pyomo model, inherit from pyepo.model.omo.optOmoModel and implement the _getModel method.

class pyepo.model.omo.optOmoModel(solver='glpk')

This is an abstract class for a Pyomo-based optimization model

_model

Pyomo model

Type:

Pyomo model

solver

optimization solver in the background

Type:

str

__init__(solver='glpk')
Parameters:

solver (str) – optimization solver in the background

abstract _getModel()

An abstract method to build a model from an optimization solver

Returns:

optimization model and variables

Return type:

tuple

property num_cost

number of costs to be predicted

relax()

An unimplemented method to relax the MIP model

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

Warning

Unlike optGrbModel, optOmoModel requires explicitly setting modelSense in _getModel.

Here is the same problem implemented with Pyomo:

import random

from pyomo import environ as pe

from pyepo.model.omo import optOmoModel
from pyepo import EPO

class myModel(optOmoModel):

    def _getModel(self):
        # sense
        self.modelSense = EPO.MAXIMIZE
        # create a model
        m = pe.ConcreteModel()
        # variables
        x = pe.Var([0,1,2,3,4], domain=pe.Binary)
        m.x = x
        # constraints
        m.cons = pe.ConstraintList()
        m.cons.add(3 * x[0] + 4 * x[1] + 3 * x[2] + 6 * x[3] + 4 * x[4] <= 12)
        m.cons.add(4 * x[0] + 5 * x[1] + 2 * x[2] + 3 * x[3] + 5 * x[4] <= 10)
        m.cons.add(5 * x[0] + 4 * x[1] + 6 * x[2] + 2 * x[3] + 3 * x[4] <= 15)
        return m, x

myoptmodel = myModel(solver="gurobi")
cost = [random.random() for _ in range(myoptmodel.num_cost)] # random cost vector
myoptmodel.setObj(cost) # set objective function
myoptmodel.solve() # solve

User-defined COPT Models

To define a COPT model, inherit from pyepo.model.copt.optCoptModel and implement the _getModel method. The model sense (minimize/maximize) is automatically detected from the COPT model.

class pyepo.model.copt.optCoptModel

This is an abstract class for a Cardinal Optimizer optimization model

_model

COPT model

Type:

COPT model

__init__()
abstract _getModel()

An abstract method to build a model from an optimization solver

Returns:

optimization model and variables

Return type:

tuple

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

Here is the same problem implemented with COPT:

import random

from coptpy import Envr, COPT

from pyepo.model.copt import optCoptModel

class myModel(optCoptModel):

    def _getModel(self):
        # create a model
        m = Envr().createModel()
        # variables
        x = m.addVars(range(5), vtype=COPT.BINARY)
        # model sense
        m.setObjSense(COPT.MAXIMIZE)
        # constraints
        m.addConstr(3 * x[0] + 4 * x[1] + 3 * x[2] + 6 * x[3] + 4 * x[4] <= 12)
        m.addConstr(4 * x[0] + 5 * x[1] + 2 * x[2] + 3 * x[3] + 5 * x[4] <= 10)
        m.addConstr(5 * x[0] + 4 * x[1] + 6 * x[2] + 2 * x[3] + 3 * x[4] <= 15)
        return m, x

myoptmodel = myModel()
cost = [random.random() for _ in range(myoptmodel.num_cost)] # random cost vector
myoptmodel.setObj(cost) # set objective function
myoptmodel.solve() # solve

User-defined OR-Tools Models

OR-Tools provides two solving paradigms: pywraplp (LP/MIP solvers) and CP-SAT (constraint programming). PyEPO provides base classes for both.

pywraplp — Inherit from pyepo.model.ort.optOrtModel and implement _getModel. The solver parameter selects the backend (e.g., "scip", "glop", "cbc").

class pyepo.model.ort.optOrtModel(solver='scip')

This is an abstract class for an OR-Tools pywraplp optimization model

_model

OR-Tools linear solver

Type:

pywraplp.Solver

solver

solver backend (e.g. “scip”, “glop”, “cbc”)

Type:

str

__init__(solver='scip')
Parameters:

solver (str) – solver backend for pywraplp

abstract _getModel()

An abstract method to build a model from an optimization solver

Returns:

optimization model and variables

Return type:

tuple

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

Warning

Unlike optGrbModel, optOrtModel requires explicitly setting modelSense in _getModel.

import random

from ortools.linear_solver import pywraplp

from pyepo.model.ort import optOrtModel
from pyepo import EPO

class myModel(optOrtModel):

    def _getModel(self):
        # sense
        self.modelSense = EPO.MAXIMIZE
        # create a model
        m = pywraplp.Solver.CreateSolver("SCIP")
        # variables
        x = {i: m.BoolVar(f"x_{i}") for i in range(5)}
        # constraints
        m.Add(3 * x[0] + 4 * x[1] + 3 * x[2] + 6 * x[3] + 4 * x[4] <= 12)
        m.Add(4 * x[0] + 5 * x[1] + 2 * x[2] + 3 * x[3] + 5 * x[4] <= 10)
        m.Add(5 * x[0] + 4 * x[1] + 6 * x[2] + 2 * x[3] + 3 * x[4] <= 15)
        return m, x

myoptmodel = myModel(solver="scip")
cost = [random.random() for _ in range(myoptmodel.num_cost)] # random cost vector
myoptmodel.setObj(cost) # set objective function
myoptmodel.solve() # solve

CP-SAT — Inherit from pyepo.model.ort.optOrtCpModel and implement _getModel. CP-SAT is an integer-only solver; float cost vectors are automatically scaled internally.

class pyepo.model.ort.optOrtCpModel

This is an abstract class for an OR-Tools CP-SAT optimization model

_model

OR-Tools CP-SAT model

Type:

cp_model.CpModel

__init__()
abstract _getModel()

An abstract method to build a model from an optimization solver

Returns:

optimization model and variables

Return type:

tuple

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

from ortools.sat.python import cp_model

from pyepo.model.ort import optOrtCpModel
from pyepo import EPO

class myCpModel(optOrtCpModel):

    def _getModel(self):
        # sense
        self.modelSense = EPO.MAXIMIZE
        # create a model
        m = cp_model.CpModel()
        # variables
        x = {i: m.NewBoolVar(f"x_{i}") for i in range(5)}
        # constraints (integer coefficients)
        m.Add(3 * x[0] + 4 * x[1] + 3 * x[2] + 6 * x[3] + 4 * x[4] <= 12)
        m.Add(4 * x[0] + 5 * x[1] + 2 * x[2] + 3 * x[3] + 5 * x[4] <= 10)
        m.Add(5 * x[0] + 4 * x[1] + 6 * x[2] + 2 * x[3] + 3 * x[4] <= 15)
        return m, x

myoptmodel = myCpModel()

Note

CP-SAT does not support LP relaxation. Calling relax() will raise a RuntimeError.

User-defined MPAX Models

MPAX (Mathematical Programming in JAX) is a hardware-accelerated mathematical programming framework based on the PDHG (Primal-Dual Hybrid Gradient) algorithm, designed for large-scale LP problems.

optMpaxModel is a PyEPO model that uses MPAX to solve LP relaxations via PDHG. It accepts constraints in matrix/vector form:

  • A, b: Equality constraints \(Ax = b\). Omit if there are no equality constraints.

  • G, h: Inequality constraints \(Gx \leq h\). Omit if there are no inequality constraints.

  • l: Lower bounds (default: 0, i.e., non-negative variables).

  • u: Upper bounds (default: infinity, i.e., unbounded).

  • use_sparse_matrix (default: True): Whether to use sparse matrix storage.

  • minimize (default: True): Whether to minimize the objective.

class pyepo.model.mpax.optMpaxModel(A=None, b=None, G=None, h=None, l=None, u=None, use_sparse_matrix=True, minimize=True)

This is an abstract class for an MPAX-based optimization model

A

The matrix of equality constraints.

Type:

jnp.ndarray, BCOO or BCSR

b

The right hand side of equality constraints.

Type:

jnp.ndarray

G

The matrix for inequality constraints.

Type:

jnp.ndarray, BCOO or BCSR

h

The right hand side of inequality constraints.

Type:

jnp.ndarray

l

The lower bound of the variables.

Type:

jnp.ndarray

u

The upper bound of the variables.

Type:

jnp.ndarray

use_sparse_matrix

Whether to use sparse matrix format, by default True.

Type:

bool

minimize

Whether to minimize objective, by default True.

Type:

bool

__init__(A=None, b=None, G=None, h=None, l=None, u=None, use_sparse_matrix=True, minimize=True)
_getModel()

Placeholder method for MPAX. MPAX does not require an explicit model creation.

property num_cost

number of costs to be predicted

relax()

An unimplemented method to relax the MIP model

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (jnp.float32)

Return type:

tuple

from pyepo.model.mpax import optMpaxModel
optmodel = optMpaxModel(A=A, b=b, G=G, h=h, use_sparse_matrix=False, minimize=True)

optmodel.setObj(cost) # set objective function
optmodel.solve() # solve

User-defined Models from Scratch

For complete flexibility, pyepo.model.opt.optModel allows users to build models with any solver or algorithm. Override _getModel, setObj, solve, and num_cost to integrate a custom solver.

class pyepo.model.opt.optModel

This is an abstract class for an optimization model

_model

underlying solver model object

Type:

optimization model

__init__()
abstract _getModel()

An abstract method to build a model from an optimization solver

Returns:

optimization model and variables

Return type:

tuple

property num_cost

number of costs to be predicted

abstract setObj(c)

An abstract method to set the objective function

Parameters:

c (ndarray) – cost of objective function

abstract solve()

An abstract method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

Warning

optModel requires setting modelSense in _getModel. If not set, the default is minimization.

The following example uses networkx with the Dijkstra algorithm to solve a shortest path problem:

import random

import numpy as np
import networkx as nx

from pyepo.model.opt import optModel

class myShortestPathModel(optModel):

    def __init__(self, grid):
        """
        Args:
            grid (tuple): size of grid network
        """
        self.grid = grid
        self.arcs = self._getArcs()
        super().__init__()

    def _getArcs(self):
        """
        A method to get list of arcs for grid network

        Returns:
            list: arcs
        """
        arcs = []
        for i in range(self.grid[0]):
            # edges on rows
            for j in range(self.grid[1] - 1):
                v = i * self.grid[1] + j
                arcs.append((v, v + 1))
            # edges in columns
            if i == self.grid[0] - 1:
                continue
            for j in range(self.grid[1]):
                v = i * self.grid[1] + j
                arcs.append((v, v + self.grid[1]))
        return arcs

    def _getModel(self):
        """
        A method to build model

        Returns:
            tuple: optimization model and variables
        """
        # build graph as optimization model
        g = nx.Graph()
        # add arcs as variables
        g.add_edges_from(self.arcs, cost=0)
        return g, g.edges

    def setObj(self, c):
        """
        A method to set objective function

        Args:
            c (ndarray): cost of objective function
        """
        for i, e in enumerate(self.arcs):
            self._model.edges[e]["cost"] = c[i]

    def solve(self):
        """
        A method to solve model

        Returns:
            tuple: optimal solution (list) and objective value (float)
        """
        # dijkstra
        path = nx.shortest_path(self._model, weight="cost", source=0, target=self.grid[0]*self.grid[1]-1)
        # convert path into active edges
        edges = []
        u = 0
        for v in path[1:]:
            edges.append((u,v))
            u = v
        # init sol & obj
        sol = np.zeros(self.num_cost)
        obj = 0
        # convert active edges into solution and obj
        for i, e in enumerate(self.arcs):
            if e in edges:
                sol[i] = 1 # active edge
                obj += self._model.edges[e]["cost"] # cost of active edge
        return sol, obj

# solve model
grid = (5,5)
myoptmodel = myShortestPathModel(grid)
cost = [random.random() for _ in range(myoptmodel.num_cost)] # random cost vector
myoptmodel.setObj(cost) # set objective function
sol, obj = myoptmodel.solve() # solve
# print res
print('Obj: {}'.format(obj))
for i, e in enumerate(myoptmodel.arcs):
    if sol[i] > 1e-3:
        print(e)

Pre-defined Models

PyEPO includes pre-defined models for several classic optimization problems.

Shortest Path

The shortest path problem finds the minimum-cost path from the northwest corner to the southeast corner of an (h, w) grid network. The default grid size is (5, 5).

Shortest Path on the Grid Graph

The problem is formulated as a minimum cost flow linear program.

GurobiPy

class pyepo.model.grb.shortestPathModel(grid)

This class is an optimization model for the shortest path problem

_model

Gurobi model

Type:

GurobiPy model

grid

Size of grid network

Type:

tuple of int

arcs

List of arcs

Type:

list

__init__(grid)
Parameters:

grid (tuple of int) – size of grid network

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

grid = (5,5) # network grid
optmodel = pyepo.model.grb.shortestPathModel(grid) # build model

The setObj and solve methods can be called manually, but they are invoked automatically during training.

import random
cost = [random.random() for _ in range(optmodel.num_cost)] # random cost vector
optmodel.setObj(cost) # set objective function
optmodel.solve() # solve

Pyomo

class pyepo.model.omo.shortestPathModel(grid, solver='glpk')

This class is an optimization model for the shortest path problem

_model

Pyomo model

Type:

Pyomo model

solver

optimization solver in the background

Type:

str

grid

size of grid network

Type:

tuple of int

arcs

list of arcs

Type:

list

__init__(grid, solver='glpk')
Parameters:
  • grid (tuple of int) – size of grid network

  • solver (str) – optimization solver in the background

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

Pyomo supports multiple backend solvers (e.g., BARON, CBC, CPLEX, Gurobi). Specify the solver via the solver parameter:

import pyepo

grid = (5,5) # network grid
optmodel = pyepo.model.omo.shortestPathModel(grid, solver="glpk") # build model with GLPK
optmodel = pyepo.model.omo.shortestPathModel(grid, solver="gurobi") # build model with Gurobi

To list available solvers:

pyomo help --solvers

COPT

class pyepo.model.copt.shortestPathModel(grid)

This class is an optimization model for the shortest path problem

_model

COPT model

Type:

COPT model

grid

size of grid network

Type:

tuple of int

arcs

list of arcs

Type:

list

__init__(grid)
Parameters:

grid (tuple of int) – size of grid network

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

grid = (5,5) # network grid
optmodel = pyepo.model.copt.shortestPathModel(grid) # build model

OR-Tools

OR-Tools provides two approaches: pywraplp (LP/MIP) and CP-SAT (constraint programming).

class pyepo.model.ort.shortestPathModel(grid, solver='glop')

This class is an optimization model for the shortest path problem

_model

OR-Tools linear solver

Type:

pywraplp.Solver

solver

solver backend

Type:

str

grid

size of grid network

Type:

tuple of int

arcs

list of arcs

Type:

list

__init__(grid, solver='glop')
Parameters:
  • grid (tuple of int) – size of grid network

  • solver (str) – solver backend for pywraplp

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

grid = (5,5) # network grid
optmodel = pyepo.model.ort.shortestPathModel(grid) # pywraplp with GLOP (default)
optmodel = pyepo.model.ort.shortestPathModel(grid, solver="scip") # pywraplp with SCIP
class pyepo.model.ort.shortestPathCpModel(grid)

This class is an optimization model for the shortest path problem using CP-SAT

_model

OR-Tools CP-SAT model

Type:

cp_model.CpModel

grid

size of grid network

Type:

tuple of int

arcs

list of arcs

Type:

list

__init__(grid)
Parameters:

grid (tuple of int) – size of grid network

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

grid = (5,5) # network grid
optmodel = pyepo.model.ort.shortestPathCpModel(grid) # CP-SAT

MPAX

class pyepo.model.mpax.shortestPathModel(grid)

This class is an optimization model for the shortest path problem

grid

Size of grid network

Type:

tuple of int

arcs

List of arcs

Type:

list

__init__(grid)
Parameters:

grid (tuple of int) – size of grid network

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (jnp.float32)

Return type:

tuple

import pyepo

grid = (5,5) # network grid
optmodel = pyepo.model.mpax.shortestPathModel(grid) # build model

Knapsack

The multi-dimensional knapsack problem is a maximization problem: select a subset of items such that total weight does not exceed resource capacities and total value is maximized. Consider a 3-dimensional example:

\[\begin{split}\begin{aligned} \max_{x} & \sum_{i=0}^4 c_i x_i \\ s.t. \quad & 3 x_0 + 4 x_1 + 3 x_2 + 6 x_3 + 4 x_4 \leq 12 \\ & 4 x_0 + 5 x_1 + 2 x_2 + 3 x_3 + 5 x_4 \leq 10 \\ & 5 x_0 + 4 x_1 + 6 x_2 + 2 x_3 + 3 x_4 \leq 15 \\ & \forall x_i \in \{0, 1\} \end{aligned}\end{split}\]

The constraint coefficients weights and right-hand sides capacities define the problem.

Note

The number of dimensions and items are determined by the shape of weights and capacities.

GurobiPy

class pyepo.model.grb.knapsackModel(weights, capacity)

This class is an optimization model for the knapsack problem

_model

Gurobi model

Type:

GurobiPy model

weights

Weights of items

Type:

np.ndarray / list

capacity

Total capacity

Type:

np.ndarray / list

items

List of item index

Type:

list

__init__(weights, capacity)
Parameters:
  • weights (np.ndarray / list) – weights of items

  • capacity (np.ndarray / list) – total capacity

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

weights = [[3, 4, 3, 6, 4],
           [4, 5, 2, 3, 5],
           [5, 4, 6, 2, 3]] # constraints coefficients
capacities = [12, 10, 15] # constraints rhs
optmodel = pyepo.model.grb.knapsackModel(weights, capacities) # build model
import random
cost = [random.random() for _ in range(optmodel.num_cost)] # random cost vector
optmodel.setObj(cost) # set objective function
optmodel.solve() # solve

The relax method returns an LP relaxation by removing integrality constraints:

optmodel_rel = optmodel.relax() # relax

Pyomo

class pyepo.model.omo.knapsackModel(weights, capacity, solver='glpk')

This class is an optimization model for the knapsack problem

_model

Pyomo model

Type:

Pyomo model

solver

optimization solver in the background

Type:

str

weights

weights of items

Type:

np.ndarray

capacity

total capacity

Type:

np.ndarray

items

list of item index

Type:

list

__init__(weights, capacity, solver='glpk')
Parameters:
  • weights (np.ndarray / list) – weights of items

  • capacity (np.ndarray / list) – total capacity

  • solver (str) – optimization solver in the background

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

weights = [[3, 4, 3, 6, 4],
           [4, 5, 2, 3, 5],
           [5, 4, 6, 2, 3]] # constraints coefficients
capacities = [12, 10, 15] # constraints rhs
# build model with GLPK
optmodel = pyepo.model.omo.knapsackModel(weights, capacities, solver="glpk")
# build model with Gurobi
optmodel = pyepo.model.omo.knapsackModel(weights, capacities, solver="gurobi")

COPT

class pyepo.model.copt.knapsackModel(weights, capacity)

This class is an optimization model for the knapsack problem

_model

COPT model

Type:

COPT model

weights

weights of items

Type:

np.ndarray

capacity

total capacity

Type:

np.ndarray

items

list of item index

Type:

list

__init__(weights, capacity)
Parameters:
  • weights (np.ndarray / list) – weights of items

  • capacity (np.ndarray / list) – total capacity

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

weights = [[3, 4, 3, 6, 4],
           [4, 5, 2, 3, 5],
           [5, 4, 6, 2, 3]] # constraints coefficients
capacities = [12, 10, 15] # constraints rhs
optmodel = pyepo.model.copt.knapsackModel(weights, capacities) # build model

OR-Tools

class pyepo.model.ort.knapsackModel(weights, capacity, solver='scip')

This class is an optimization model for the knapsack problem

_model

OR-Tools linear solver

Type:

pywraplp.Solver

solver

solver backend

Type:

str

weights

weights of items

Type:

np.ndarray

capacity

total capacity

Type:

np.ndarray

items

list of item index

Type:

list

__init__(weights, capacity, solver='scip')
Parameters:
  • weights (np.ndarray / list) – weights of items

  • capacity (np.ndarray / list) – total capacity

  • solver (str) – solver backend for pywraplp

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

weights = [[3, 4, 3, 6, 4],
           [4, 5, 2, 3, 5],
           [5, 4, 6, 2, 3]] # constraints coefficients
capacities = [12, 10, 15] # constraints rhs
optmodel = pyepo.model.ort.knapsackModel(weights, capacities) # pywraplp with SCIP (default)
class pyepo.model.ort.knapsackCpModel(weights, capacity)

This class is an optimization model for the knapsack problem using CP-SAT

_model

OR-Tools CP-SAT model

Type:

cp_model.CpModel

weights

weights of items

Type:

np.ndarray

capacity

total capacity

Type:

np.ndarray

items

list of item index

Type:

list

__init__(weights, capacity)
Parameters:
  • weights (np.ndarray / list) – weights of items

  • capacity (np.ndarray / list) – total capacity

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo

weights = [[3, 4, 3, 6, 4],
           [4, 5, 2, 3, 5],
           [5, 4, 6, 2, 3]] # integer coefficients for CP-SAT
capacities = [12, 10, 15] # constraints rhs
optmodel = pyepo.model.ort.knapsackCpModel(weights, capacities) # CP-SAT

Note

CP-SAT requires integer coefficients. Float weights will be truncated to integers.

MPAX

MPAX solves the LP relaxation of the knapsack problem using the PDHG algorithm.

class pyepo.model.mpax.knapsackModel(weights, capacity)

This class is an optimization model for the relaxed knapsack problem

_model

MPAX model

weights

Weights of items

Type:

np.ndarray / list

capacity

Total capacity

Type:

np.ndarray / list

items

List of item index

Type:

list

__init__(weights, capacity)
Parameters:
  • weights (np.ndarray / list) – weights of items

  • capacity (np.ndarray / list) – total capacity

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (jnp.float32)

Return type:

tuple

import pyepo
import numpy as np

weights = np.array([[3, 4, 3, 6, 4],
                     [4, 5, 2, 3, 5],
                     [5, 4, 6, 2, 3]]) # constraints coefficients
capacities = [12, 10, 15] # constraints rhs
optmodel = pyepo.model.mpax.knapsackModel(weights, capacities) # build model

Traveling Salesman

The traveling salesman problem (TSP) seeks the shortest route that visits each city exactly once and returns to the origin. We consider the symmetric TSP with 20 nodes.

Three ILP formulations are available: Dantzig-Fulkerson-Johnson (DFJ), Gavish-Graves (GG), and Miller-Tucker-Zemlin (MTZ).

Note

The DFJ formulation uses lazy constraints and is available with GurobiPy and COPT. The GG and MTZ formulations are available with GurobiPy, Pyomo, and COPT.

GurobiPy

DFJ Formulation
class pyepo.model.grb.tspDFJModel(num_nodes)

This class is an optimization model for the traveling salesman problem based on Danzig–Fulkerson–Johnson (DFJ) formulation and constraint generation.

_model

Gurobi model

Type:

GurobiPy model

num_nodes

Number of nodes

Type:

int

edges

List of edge index

Type:

list

__init__(num_nodes)
Parameters:

num_nodes (int) – number of nodes

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (list) – cost vector

solve()

A method to solve model

The DFJ formulation has exponentially many subtour elimination constraints, solved via column generation. LP relaxation is not supported.

import pyepo
import random

num_nodes = 20 # number of nodes
optmodel = pyepo.model.grb.tspDFJModel(num_nodes) # build model

cost = [random.random() for _ in range(optmodel.num_cost)] # random cost vector
optmodel.setObj(cost) # set objective function
optmodel.solve() # solve
GG Formulation
class pyepo.model.grb.tspGGModel(num_nodes)

This class is an optimization model for the traveling salesman problem based on Gavish–Graves (GG) formulation.

_model

Gurobi model

Type:

GurobiPy model

num_nodes

Number of nodes

Type:

int

edges

List of edge index

Type:

list

__init__(num_nodes)
Parameters:

num_nodes (int) – number of nodes

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (list) – cost vector

solve()

A method to solve model

import pyepo
import random

num_nodes = 20 # number of nodes
optmodel = pyepo.model.grb.tspGGModel(num_nodes) # build model

cost = [random.random() for _ in range(optmodel.num_cost)] # random cost vector
optmodel.setObj(cost) # set objective function
optmodel.solve() # solve

optmodel.relax() # relax
MTZ Formulation
class pyepo.model.grb.tspMTZModel(num_nodes)

This class is an optimization model for the traveling salesman problem based on Miller-Tucker-Zemlin (MTZ) formulation.

_model

Gurobi model

Type:

GurobiPy model

num_nodes

Number of nodes

Type:

int

edges

List of edge index

Type:

list

__init__(num_nodes)
Parameters:

num_nodes (int) – number of nodes

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (list) – cost vector

solve()

A method to solve model

import pyepo
import random

num_nodes = 20 # number of nodes
optmodel = pyepo.model.grb.tspMTZModel(num_nodes) # build model

cost = [random.random() for _ in range(optmodel.num_cost)] # random cost vector
optmodel.setObj(cost) # set objective function
optmodel.solve() # solve

optmodel.relax() # relax

Pyomo

The GG and MTZ formulations are available with Pyomo. The DFJ formulation is not supported in Pyomo due to the lack of a native callback API.

class pyepo.model.omo.tspGGModel(num_nodes, solver='glpk')

This class is an optimization model for the traveling salesman problem based on Gavish-Graves (GG) formulation.

_model

Pyomo model

Type:

Pyomo model

solver

optimization solver in the background

Type:

str

num_nodes

Number of nodes

Type:

int

edges

List of edge index

Type:

list

__init__(num_nodes, solver='glpk')
Parameters:
  • num_nodes (int) – number of nodes

  • solver (str) – optimization solver in the background

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (list) – cost vector

solve()

A method to solve model

class pyepo.model.omo.tspMTZModel(num_nodes, solver='glpk')

This class is an optimization model for the traveling salesman problem based on Miller-Tucker-Zemlin (MTZ) formulation.

_model

Pyomo model

Type:

Pyomo model

solver

optimization solver in the background

Type:

str

num_nodes

Number of nodes

Type:

int

edges

List of edge index

Type:

list

__init__(num_nodes, solver='glpk')
Parameters:
  • num_nodes (int) – number of nodes

  • solver (str) – optimization solver in the background

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (list) – cost vector

solve()

A method to solve model

import pyepo
import random

num_nodes = 20 # number of nodes

# GG formulation with Gurobi solver
optmodel = pyepo.model.omo.tspGGModel(num_nodes, solver="gurobi")
# MTZ formulation with GLPK solver
optmodel = pyepo.model.omo.tspMTZModel(num_nodes, solver="glpk")

cost = [random.random() for _ in range(optmodel.num_cost)] # random cost vector
optmodel.setObj(cost) # set objective function
optmodel.solve() # solve

COPT

All three formulations (DFJ, GG, MTZ) are available with COPT. The DFJ formulation uses COPT’s callback API for lazy subtour elimination constraints.

class pyepo.model.copt.tspDFJModel(num_nodes)

This class is an optimization model for the traveling salesman problem based on Danzig-Fulkerson-Johnson (DFJ) formulation and constraint generation.

_model

COPT model

Type:

COPT model

num_nodes

Number of nodes

Type:

int

edges

List of edge index

Type:

list

__init__(num_nodes)
Parameters:

num_nodes (int) – number of nodes

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (list) – cost vector

solve()

A method to solve model

class pyepo.model.copt.tspGGModel(num_nodes)

This class is an optimization model for the traveling salesman problem based on Gavish-Graves (GG) formulation.

_model

COPT model

Type:

COPT model

num_nodes

Number of nodes

Type:

int

edges

List of edge index

Type:

list

__init__(num_nodes)
Parameters:

num_nodes (int) – number of nodes

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (list) – cost vector

solve()

A method to solve model

class pyepo.model.copt.tspMTZModel(num_nodes)

This class is an optimization model for the traveling salesman problem based on Miller-Tucker-Zemlin (MTZ) formulation.

_model

COPT model

Type:

COPT model

num_nodes

Number of nodes

Type:

int

edges

List of edge index

Type:

list

__init__(num_nodes)
Parameters:

num_nodes (int) – number of nodes

property num_cost

number of costs to be predicted

relax()

A method to get linear relaxation model

setObj(c)

A method to set the objective function

Parameters:

c (list) – cost vector

solve()

A method to solve model

import pyepo
import random

num_nodes = 20 # number of nodes

# DFJ formulation
optmodel = pyepo.model.copt.tspDFJModel(num_nodes)
# GG formulation
optmodel = pyepo.model.copt.tspGGModel(num_nodes)
# MTZ formulation
optmodel = pyepo.model.copt.tspMTZModel(num_nodes)

cost = [random.random() for _ in range(optmodel.num_cost)] # random cost vector
optmodel.setObj(cost) # set objective function
optmodel.solve() # solve

Portfolio

Portfolio optimization selects an asset allocation that maximizes expected return for a given level of risk:

\[\begin{split}\begin{aligned} \max_{x} & \sum_{i} r_i x_i \\ s.t. \quad & \sum_{i} x_i = 1 \\ & \mathbf{x}^{\intercal} \mathbf{\Sigma} \mathbf{x} \leq \gamma \bar{\Sigma}\\ & \forall x_i \geq 0 \end{aligned}\end{split}\]

GurobiPy

class pyepo.model.grb.portfolioModel(num_assets, covariance, gamma=2.25)

This class is an optimization model for the portfolio problem

_model

Gurobi model

Type:

GurobiPy model

num_assets

number of assets

Type:

int

covariance

covariance matrix of the returns

Type:

numpy.ndarray

risk_level

risk level

Type:

float

__init__(num_assets, covariance, gamma=2.25)
Parameters:
  • num_assets (int) – number of assets

  • covariance (numpy.ndarray) – covariance matrix of the returns

  • gamma (float) – risk level parameter

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo
import numpy as np

m = 50 # number of assets
cov = np.cov(np.random.randn(10, m), rowvar=False) # covariance matrix
optmodel = pyepo.model.grb.portfolioModel(m, cov) # build model
import random
revenue = [random.random() for _ in range(optmodel.num_cost)] # random cost vector
optmodel.setObj(revenue) # set objective function
optmodel.solve() # solve

Pyomo

class pyepo.model.omo.portfolioModel(num_assets, covariance, gamma=2.25, solver='glpk')

This class is an optimization model for the portfolio problem

_model

Pyomo model

Type:

Pyomo model

solver

optimization solver in the background

Type:

str

num_assets

number of assets

Type:

int

covariance

covariance matrix of the returns

Type:

numpy.ndarray

risk_level

risk level

Type:

float

__init__(num_assets, covariance, gamma=2.25, solver='glpk')
Parameters:
  • num_assets (int) – number of assets

  • covariance (numpy.ndarray) – covariance matrix of the returns

  • gamma (float) – risk level parameter

  • solver (str) – optimization solver in the background

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo
import numpy as np

m = 50 # number of assets
cov = np.cov(np.random.randn(10, m), rowvar=False) # covariance matrix
optmodel = pyepo.model.omo.portfolioModel(m, cov, solver="gurobi") # build model

COPT

class pyepo.model.copt.portfolioModel(num_assets, covariance, gamma=2.25)

This class is an optimization model for the portfolio problem

_model

COPT model

Type:

COPT model

num_assets

number of assets

Type:

int

covariance

covariance matrix of the returns

Type:

numpy.ndarray

risk_level

risk level

Type:

float

__init__(num_assets, covariance, gamma=2.25)
Parameters:
  • num_assets (int) – number of assets

  • covariance (numpy.ndarray) – covariance matrix of the returns

  • gamma (float) – risk level parameter

property num_cost

number of costs to be predicted

setObj(c)

A method to set the objective function

Parameters:

c (np.ndarray / list) – cost of objective function

solve()

A method to solve the model

Returns:

optimal solution (list) and objective value (float)

Return type:

tuple

import pyepo
import numpy as np

m = 50 # number of assets
cov = np.cov(np.random.randn(10, m), rowvar=False) # covariance matrix
optmodel = pyepo.model.copt.portfolioModel(m, cov) # build model