Skip to content

LpProblem

A class representing a linear programming problem

Methods

add_constraint(self, lp_constraint)

Adds a constraint to the LP problem and adds all variables. Raises error if namespace conflict.

Parameters:

Name Type Description Default
lp_constraint LpConstraint

The constraint to add

required

Exceptions:

Type Description
TypeError

If lp_constraint is not an LpConstraint object

NameError

If the name of lp_constraint conflicts with an existing constraint in the problem

Source code in flipy/lp_problem.py
def add_constraint(self, lp_constraint: LpConstraint) -> None:
    """ Adds a constraint to the LP problem and adds all variables. Raises error if namespace conflict.

    Raises
    ------
    TypeError
        If `lp_constraint` is not an `LpConstraint` object
    NameError
        If the name of `lp_constraint` conflicts with an existing constraint in the problem

    Parameters
    ----------
    lp_constraint:
        The constraint to add
    """
    if not isinstance(lp_constraint, LpConstraint):
        raise TypeError('%s is not an LpConstraint' % lp_constraint)
    if self.lp_constraints.get(lp_constraint.name, lp_constraint) != lp_constraint:
        raise NameError('LP constraint name %s conflicts with an existing LP constraint' % lp_constraint.name)
    self.lp_constraints[lp_constraint.name] = lp_constraint
    for var in lp_constraint.lhs.expr.keys():
        self.add_variable(var)
    for var in lp_constraint.rhs.expr.keys():
        self.add_variable(var)

add_variable(self, lp_variable)

Adds a variable to the internal dictionary of the problem

Parameters:

Name Type Description Default
lp_variable LpVariable

The variable to add

required

Exceptions:

Type Description
TypeError

If lp_variable is not an LpVariable object

NameError

If the name of lp_variable conflicts with an existing variable in the problem

Source code in flipy/lp_problem.py
def add_variable(self, lp_variable: LpVariable) -> None:
    """ Adds a variable to the internal dictionary of the problem

    Raises
    ------
    TypeError
        If `lp_variable` is not an `LpVariable` object
    NameError
        If the name of `lp_variable` conflicts with an existing variable in the problem

    Parameters
    ----------
    lp_variable:
        The variable to add
    """
    if not isinstance(lp_variable, LpVariable):
        raise TypeError('%s is not an LpVariable' % lp_variable)
    if self.lp_variables.get(lp_variable.name, lp_variable) != lp_variable:
        raise NameError('LP variable name %s conflicts with an existing LP variable' % lp_variable.name)
    self.lp_variables[lp_variable.name] = lp_variable

set_objective(self, lp_objective)

Sets the objective of the LP problem and adds all variables. Raises error if already has an objective.

Parameters:

Name Type Description Default
lp_objective LpObjective

The objective to set

required

Exceptions:

Type Description
TypeError

If lp_objective is not an LpObjective object

Exception

If the objective is already set in the problem

Source code in flipy/lp_problem.py
def set_objective(self, lp_objective: LpObjective) -> None:
    """ Sets the objective of the LP problem and adds all variables. Raises error if already has an objective.

    Raises
    ------
    TypeError
        If `lp_objective` is not an `LpObjective` object
    Exception
        If the objective is already set in the problem

    Parameters
    ----------
    lp_objective:
        The objective to set
    """
    if not isinstance(lp_objective, LpObjective):
        raise TypeError('%s is not an LpObjective' % lp_objective)
    if self.lp_objective:
        raise Exception('LP objective is already set')
    for var, coeff in lp_objective.expr.items():
        self.add_variable(var)
        var.set_obj_coeff(coeff)
    self.lp_objective = lp_objective

write_lp(self, buffer)

Writes the problem in an LP format to a buffer

Parameters:

Name Type Description Default
buffer buffer-like

A buffer-like object with a write method

required

Exceptions:

Type Description
Exception

If the problem doesn't have an objective

Source code in flipy/lp_problem.py
def write_lp(self, buffer):
    """ Writes the problem in an LP format to a buffer

    Raises
    ------
    Exception
        If the problem doesn't have an objective

    Parameters
    ----------
    buffer: buffer-like
        A buffer-like object with a `write` method
    """
    if not self.lp_objective:
        raise Exception('No objective')

    lines = [f'\\* {self.name} *\\']

    if self.lp_objective.sense == Minimize:
        lines.append('Minimize')
    else:
        lines.append('Maximize')

    objective_name = self.lp_objective.name if self.lp_objective.name else "OBJ"

    obj_slack_expr = {constraint.slack_variable: constraint.slack_penalty * (1 if self.lp_objective.sense == Minimize else -1)
                      for constraint in self.lp_constraints.values() if constraint.slack}

    terms = [f'{objective_name}:'] + self.lp_objective.to_lp_terms(slack=obj_slack_expr)

    obj_lines = self._group_terms(terms)

    for obj_line in obj_lines:
        lines.append(obj_line)

    lines.append("Subject To")

    constraint_names = sorted(self.lp_constraints.keys())
    for con in constraint_names:
        constraint = self.lp_constraints[con]

        constraint_terms = constraint.to_lp_terms()
        if not constraint_terms:
            continue

        cons_lines = self._group_terms([f'{con}:'] + constraint_terms)
        for line in cons_lines:
            lines.append(line)

    sorted_lp_variables = sorted(self.lp_variables.values(), key=lambda v: v.name)

    # Bounded variables
    bounded_vars = [var for var in sorted_lp_variables if not var.is_positive_free()]
    if bounded_vars:
        lines.append("Bounds")
        for var in bounded_vars:
            lines.append(f"{var.to_lp_str()}")

    # Integer non-binary variables
    integer_vars = [
        var for var in sorted_lp_variables if (var.var_type is VarType.Integer)
    ]
    if integer_vars:
        lines.append("Generals")
        for var in integer_vars:
            lines.append(f"{var.name}")

    # Binary variables
    binary_vars = [var for var in sorted_lp_variables if var.var_type is VarType.Binary]
    if binary_vars:
        lines.append("Binaries")
        for var in binary_vars:
            lines.append(f"{var.name}")

    lines.append("End")
    buffer.write('\n'.join(lines))