Low Level Model Building API#

This section documents low level routines that build models directly from input data, rather than using operator overloading to build models by adding variables and constraints one at a time. This can be an advantage for performance, but at the cost of code readability. This is considered advanced usage of gurobipy.

The main advantage of this approach is that it avoids creating modeling objects (Var, Constr, etc), which can be expensive. You should be aware of some limitations on the resulting Model object. For example calling a method such as Model.getVars, or adding additional variables using Model.addVar will create modeling objects and incur the associated overhead anyway.

gurobipy.loadModel(*, env, numvars, numconstrs, modelsense=GRB.MINIMIZE, objcon=0.0, obj=None, lb=None, ub=None, vtype=None, constr_csc=None, sense=None, rhs=None, qobj_coo=None, name=None)#

Create a new optimization model, using the provided arguments to initialize the model data (objective function, variable bounds, constraint matrix, etc.). The model is then ready for optimization.

This function allows you to build models with only linear constraints, and linear or quadratic objectives.

You’ll need numpy installed to use this function. All arguments to this function are keyword-only.

You should only interact with the returned Model object via the attribute interface, optimization methods, and the write method. Any other calls, such as adding additional variables or constraints, may create internal modeling objects which incur overhead. See the examples below for more details.

Parameters:
  • env – The environment in which the new model should be created.

  • numvars – The number of variables in the model.

  • numconstrs – The number of constraints in the model.

  • modelsense – The sense of the objective function. Allowed values are GRB.MINIMIZE or GRB.MAXIMIZE. Defaults to GRB.MINIMIZE.

  • objcon – Constant objective offset (defaults to 0.0).

  • obj – (optional) Objective coefficients for the model variables, as a list or 1-D array of length numvars. If not provided, all linear objective coefficients in the model are set to 0.0.

  • lb – (optional) Lower bounds for the model variables, as a list or 1-D array of length numvars. If not provided, all variables will have lower bounds of 0.0.

  • ub – (optional) Upper bounds for the model variables, as a list or 1-D array of length numvars. If not provided, all variables will have infinite upper bounds.

  • vtype – (optional) Types for the variables, as a list or 1-D array of length numvars. Options are GRB.CONTINUOUS, GRB.BINARY, GRB.INTEGER, GRB.SEMICONT, or GRB.SEMIINT. If not provided, all variables will be continuous.

  • constr_csc – (optional) Linear constraint data in Compressed Sparse Column format (CSC) as a tuple (data, indices, indptr). In this format the constraint indices for variable \(i\) are stored in indices[indptr[i]:indptr[i+1]] and their corresponding coefficients are stored in data[indptr[i]:indptr[i+1]]. The format is the same as that used by scipy.sparse.csc_array. This argument can be omitted if no linear constraints are being added.

  • sense – (optional) The senses for the model constraints, as a list or 1-D array of length numconstrs. Options are GRB.EQUAL, GRB.LESS_EQUAL, or GRB.GREATER_EQUAL. Can be omitted if no linear constraints are being added.

  • rhs – (optional) Right-hand side values for the new constraints, as a list or 1-D array of length numconstrs. Can be omitted if no linear constraints are being added.

  • qobj_coo – (optional) Quadratic objective matrix in coordinate format as a tuple (qval, (qrow, qcol)). The \(i^{th}\) quadratic term is represented using three values: a pair of indices (stored in qrow[i] and qcol[i]), and a coefficient (stored in qval[i]). The format is the same as that used by scipy.sparse.coo_array. This argument can be omitted if no quadratic objective terms are being added.

  • name – (optional) The name of the model.

Returns:

New populated Model object

Important

We generally recommend that you build models using modeling objects via the methods addVar, addConstr, and others. This approach produces code that is much easier to read, write, and maintain. You should only use loadModel in performance critical scenarios where the overhead of the modeling objects is prohibitive and you are willing to sacrifice code readability.

The following code builds and solves the mip1.py and extracts the solution as a list of variable values:

# Build and solve the MIP model:
#
#  maximize
#        x +   y + 2 z
#  subject to
#        x + 2 y + 3 z <= 4
#        x +   y       >= 1
#        x, y, z binary

import numpy as np
import gurobipy as gp
from gurobipy import GRB

# Prepare input data for the model

numvars = 3
numconstrs = 2

vtype = np.array([GRB.BINARY, GRB.BINARY, GRB.BINARY])

modelsense = GRB.MAXIMIZE
obj = np.array([1.0, 1.0, 2.0])

constr_csc = (
    np.array([ 1.0, 1.0, 3.2, 1.3, 3.0    ]),  # coefficients
    np.array([   0,   1,   0,   1,   0    ]),  # row indices
    np.array([   0,        2,        4,  5]),  # column index pointers
)
sense = np.array([GRB.LESS_EQUAL, GRB.GREATER_EQUAL])
rhs = np.array([4.0, 1.0])

# Create an environment, load and solve the model

with gp.Env() as env, gp.loadModel(
    env=env,
    numvars=numvars,
    numconstrs=numconstrs,
    modelsense=modelsense,
    vtype=vtype,
    constr_csc=constr_csc,
    sense=sense,
    rhs=rhs,
    obj=obj,
) as model:

    model.optimize()

    # Extract solution as a list of length 'numvars'
    solution = model.getAttr("X")

When you use loadModel to create a model, you can call any methods on the resulting Model object as normal, but you should not use those which require Var, Constr modeling objects to avoid the associated overhead.

You can get and set attributes without creating these modeling objects. To do so, you must provide data for all variables/constraints in the model as lists or arrays of appropriate length. For example, to set a MIP start for the above model before solving, you would add a call to Model.setAttr to provide start values for all 3 variables in the model:

with gp.Env() as env, gp.loadModel(...) as model:
    model.setAttr("Start", [0.0, 1.0, 0.0])
    model.optimize()
    ...

Quadratic objective functions can be included when loading a model. The quadratic terms are in addition to linear terms added using the obj argument. For example to solve a model with quadratic objective function \(2 x_0^2 + x_0 x_1 + x_1^2 + x_0 + x_1\):

# Linear objective coefficients
numvars = 2
obj = [1.0, 1.0]

# 2x2 sparse COO matrix
qval = [2.0, 1.0, 1.0]
qrow = [0, 0, 1]
qcol = [0, 1, 1]

with gp.Env() as env, gp.loadModel(
    env=env,
    numvars=numvars,
    ...
    obj=obj,
    qobj_coo=(qval, (qrow, qcol)),
) as model:
    ...

The model can be written to a file for inspection, and you can optionally set variable and constraint names as attributes to aid readability before doing so:

with gp.Env() as env, gp.loadModel(...) as model:
    model.setAttr("VarName", ["x", "y", "z"])
    model.setAttr("ConstrName", ["c0", "c1"])
    model.write("model.lp")