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 |
NameError |
If the name of |
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 |
NameError |
If the name of |
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 |
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 |
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))