Skip to content

model

Model(name=None, solver=None, solver_env=None, use_var_names=False, sense=None)

The object that holds all the variables, constraints, and the objective.

Parameters:

Name Type Description Default
name

The name of the model. Currently it is not used for much.

None
solver Optional[SUPPORTED_SOLVER_TYPES]

The solver to use. If None, Config.default_solver will be used. If Config.default_solver has not been set (None), Pyoframe will try to detect whichever solver is already installed.

None
solver_env Optional[Dict[str, str]]

Gurobi only: a dictionary of parameters to set when creating the Gurobi environment.

None
use_var_names

Whether to pass variable names to the solver. Set to True if you'd like outputs from e.g. Model.write() to be legible.

False
sense Union[ObjSense, ObjSenseValue, None]

Either "min" or "max". Indicates whether it's a minmization or maximization problem. Typically, this parameter can be omitted (None) as it will automatically be set when the objective is set using .minimize or .maximize.

None

Examples:

>>> m = pf.Model()
>>> m.X = pf.Variable()
>>> m.my_constraint = m.X <= 10
>>> m
<Model vars=1 constrs=1 objective=False>

Try setting the Gurobi license:

>>> m = pf.Model(solver="gurobi", solver_env=dict(ComputeServer="myserver", ServerPassword="mypassword"))
Traceback (most recent call last):
...
RuntimeError: Could not resolve host: myserver (code 6, command POST http://myserver/api/v1/cluster/jobs)
Source code in pyoframe/model.py
def __init__(
    self,
    name=None,
    solver: Optional[SUPPORTED_SOLVER_TYPES] = None,
    solver_env: Optional[Dict[str, str]] = None,
    use_var_names=False,
    sense: Union[ObjSense, ObjSenseValue, None] = None,
):
    self.poi, self.solver_name = Model.create_poi_model(solver, solver_env)
    self._variables: List[Variable] = []
    self._constraints: List[Constraint] = []
    self.sense = ObjSense(sense) if sense is not None else None
    self._objective: Optional[Objective] = None
    self.var_map = (
        NamedVariableMapper(Variable) if Config.print_uses_variable_names else None
    )
    self.name = name

    self.params = Container(self._set_param, self._get_param)
    self.attr = Container(self._set_attr, self._get_attr)
    self._use_var_names = use_var_names

binary_variables property

Examples:

>>> m = pf.Model()
>>> m.X = pf.Variable(vtype=pf.VType.BINARY)
>>> m.Y = pf.Variable()
>>> len(list(m.binary_variables))
1

integer_variables property

Examples:

>>> m = pf.Model()
>>> m.X = pf.Variable(vtype=pf.VType.INTEGER)
>>> m.Y = pf.Variable()
>>> len(list(m.integer_variables))
1

compute_IIS()

Computes the Irreducible Infeasible Set (IIS) of the model.

Gurobi only

This method only works with the Gurobi solver. Open an issue if you'd like to see support for other solvers.

Examples:

>>> m = pf.Model(solver="gurobi")
>>> m.X = pf.Variable(lb=0, ub=2)
>>> m.Y = pf.Variable(lb=0, ub=2)
>>> m.bad_constraint = m.X >= 3
>>> m.minimize = m.X + m.Y
>>> m.optimize()
>>> m.attr.TerminationStatus
<TerminationStatusCode.INFEASIBLE: 3>
>>> m.bad_constraint.attr.IIS
Traceback (most recent call last):
...
polars.exceptions.ComputeError: RuntimeError: Unable to retrieve attribute 'IISConstr'
>>> m.compute_IIS()
>>> m.bad_constraint.attr.IIS
True
Source code in pyoframe/model.py
@for_solvers("gurobi", "copt")
def compute_IIS(self):
    """
    Computes the Irreducible Infeasible Set (IIS) of the model.

    !!! warning "Gurobi only"
        This method only works with the Gurobi solver. Open an issue if you'd like to see support for other solvers.

    Examples:
        >>> m = pf.Model(solver="gurobi")
        >>> m.X = pf.Variable(lb=0, ub=2)
        >>> m.Y = pf.Variable(lb=0, ub=2)
        >>> m.bad_constraint = m.X >= 3
        >>> m.minimize = m.X + m.Y
        >>> m.optimize()
        >>> m.attr.TerminationStatus
        <TerminationStatusCode.INFEASIBLE: 3>
        >>> m.bad_constraint.attr.IIS
        Traceback (most recent call last):
        ...
        polars.exceptions.ComputeError: RuntimeError: Unable to retrieve attribute 'IISConstr'
        >>> m.compute_IIS()
        >>> m.bad_constraint.attr.IIS
        True
    """
    self.poi.computeIIS()

convert_to_fixed()

Turns a mixed integer program into a continuous one by fixing all the integer and binary variables to their solution values.

Gurobi only

This method only works with the Gurobi solver. Open an issue if you'd like to see support for other solvers.

Examples:

>>> m = pf.Model(solver="gurobi")
>>> m.X = pf.Variable(vtype=pf.VType.BINARY, lb=0)
>>> m.Y = pf.Variable(vtype=pf.VType.INTEGER, lb=0)
>>> m.Z = pf.Variable(lb=0)
>>> m.my_constraint = m.X + m.Y + m.Z <= 10
>>> m.maximize = 3 * m.X + 2 * m.Y + m.Z
>>> m.optimize()
>>> m.X.solution, m.Y.solution, m.Z.solution
(1.0, 9.0, 0.0)
>>> m.my_constraint.dual
Traceback (most recent call last):
...
polars.exceptions.ComputeError: RuntimeError: Unable to retrieve attribute 'Pi'
>>> m.convert_to_fixed()
>>> m.optimize()
>>> m.my_constraint.dual
1.0

Only works for Gurobi:

>>> m = pf.Model("max", solver="highs")
>>> m.convert_to_fixed()
Traceback (most recent call last):
...
NotImplementedError: Method 'convert_to_fixed' is not implemented for solver 'highs'.
Source code in pyoframe/model.py
@for_solvers("gurobi")
def convert_to_fixed(self) -> None:
    """
    Turns a mixed integer program into a continuous one by fixing
    all the integer and binary variables to their solution values.

    !!! warning "Gurobi only"
        This method only works with the Gurobi solver. Open an issue if you'd like to see support for other solvers.

    Examples:
        >>> m = pf.Model(solver="gurobi")
        >>> m.X = pf.Variable(vtype=pf.VType.BINARY, lb=0)
        >>> m.Y = pf.Variable(vtype=pf.VType.INTEGER, lb=0)
        >>> m.Z = pf.Variable(lb=0)
        >>> m.my_constraint = m.X + m.Y + m.Z <= 10
        >>> m.maximize = 3 * m.X + 2 * m.Y + m.Z
        >>> m.optimize()
        >>> m.X.solution, m.Y.solution, m.Z.solution
        (1.0, 9.0, 0.0)
        >>> m.my_constraint.dual
        Traceback (most recent call last):
        ...
        polars.exceptions.ComputeError: RuntimeError: Unable to retrieve attribute 'Pi'
        >>> m.convert_to_fixed()
        >>> m.optimize()
        >>> m.my_constraint.dual
        1.0

        Only works for Gurobi:

        >>> m = pf.Model("max", solver="highs")
        >>> m.convert_to_fixed()
        Traceback (most recent call last):
        ...
        NotImplementedError: Method 'convert_to_fixed' is not implemented for solver 'highs'.
    """
    self.poi._converttofixed()

dispose()

Tries to close the solver connection by deleting the model and forcing the garbage collector to run.

Gurobi only. Once this method is called, this model is no longer usable.

This method will not work if you have a variable that references self.poi. Unfortunately, this is a limitation from the underlying solver interface library. See https://github.com/metab0t/PyOptInterface/issues/36 for context.

Examples:

>>> m = pf.Model(solver="gurobi")
>>> m.X = pf.Variable(ub=1)
>>> m.maximize = m.X
>>> m.optimize()
>>> m.X.solution
1.0
>>> m.dispose()
>>> m.X.solution
Traceback (most recent call last):
...
AttributeError: 'Model' object has no attribute 'poi'
Source code in pyoframe/model.py
@for_solvers("gurobi")
def dispose(self):
    """
    Tries to close the solver connection by deleting the model and forcing the garbage collector to run.

    Gurobi only. Once this method is called, this model is no longer usable.

    This method will not work if you have a variable that references self.poi.
    Unfortunately, this is a limitation from the underlying solver interface library.
    See https://github.com/metab0t/PyOptInterface/issues/36 for context.

    Examples:
        >>> m = pf.Model(solver="gurobi")
        >>> m.X = pf.Variable(ub=1)
        >>> m.maximize = m.X
        >>> m.optimize()
        >>> m.X.solution
        1.0
        >>> m.dispose()
        >>> m.X.solution
        Traceback (most recent call last):
        ...
        AttributeError: 'Model' object has no attribute 'poi'
    """
    import gc

    env = self.poi._env
    del self.poi
    gc.collect()
    del env
    gc.collect()