def test_breakdown(self, lhs, rhs): constraint = LpConstraint(lhs, 'eq', rhs, 'test_constraint') lower_bound_constraint, upper_bound_constraint = constraint.breakdown() assert lower_bound_constraint.sense == 'geq' assert lower_bound_constraint.name == 'test_constraint_lb' assert upper_bound_constraint.sense == 'leq' assert upper_bound_constraint.name == 'test_constraint_ub'
def test_to_lp_terms(self, x, y): # 2x + 3y + 7 lhs = LpExpression('lhs', {x: 2, y: 3}, 7) # x + 5y + 2 rhs = LpExpression('rhs', {x: 1, y: 5}, 2) constraint = LpConstraint(lhs, 'leq', rhs, 'test_constraint') assert constraint.to_lp_terms() == ['x', '- 2 y', '<=', '-5']
def test_invalid_sense(self, lhs): with pytest.raises(ValueError) as e: LpConstraint(lhs, 'invalid') assert 'sense' in e.message.lower() with pytest.raises(ValueError) as e: LpConstraint(lhs, 1) assert 'sense' in e.message.lower()
def test_lower_bound(self, lhs, rhs): constraint = LpConstraint(lhs, 'leq', rhs, 'test_constraint') assert constraint.lower_bound is None assert constraint.upper_bound == -5 constraint = LpConstraint(lhs, 'geq', rhs, 'test_constraint') assert constraint.upper_bound is None assert constraint.lower_bound == -5 constraint = LpConstraint(lhs, 'eq', rhs, 'test_constraint') assert constraint.upper_bound == -5 assert constraint.lower_bound == -5
def test_invalid_exprs(self, lhs): # test LHS with pytest.raises(ValueError) as e: LpConstraint('invalid', 'leq') assert 'lhs' in e.message.lower() # test RHS with pytest.raises(ValueError) as e: LpConstraint(lhs, 'leq', 'invalid') assert 'rhs' in e.message.lower()
def test_check(self, x, y, lhs, rhs): lp_constraint = LpConstraint(lhs, 'geq', rhs) x.set_value(5) y.set_value(0) assert lp_constraint.check() lp_constraint = LpConstraint(lhs, 'leq', rhs) assert not lp_constraint.check() lp_constraint.slack = True lp_constraint.slack_variable.set_value(100) assert lp_constraint.check() lp_constraint.slack = False assert not lp_constraint.check()
def test_add_constraint(self, problem, x): rhs = LpExpression('rhs', {x: 1}) lhs = LpExpression('lhs', {x: 1}, 2) constraint = LpConstraint(rhs, 'geq', lhs, 'constraint') problem.add_constraint(constraint) assert problem.lp_constraints[constraint.name] == constraint assert problem.lp_variables[x.name] == x constraint = LpConstraint(lhs, 'geq', rhs, 'constraint') with pytest.raises(Exception) as e: problem.add_constraint(constraint) assert e.value.args == ( 'LP constraint name %s conflicts with an existing LP constraint' % constraint.name, ) with pytest.raises(Exception) as e: problem.add_constraint(10) assert e.value.args == ('%s is not an LpConstraint' % 10, )
def test_write_no_objective(self, problem, x): rhs = LpExpression('rhs', {x: 1}) lhs = LpExpression('lhs', {}, -2) constraint = LpConstraint(rhs, 'geq', lhs, 'constraint') problem.add_constraint(constraint) buffer = StringIO() with pytest.raises(Exception) as e: problem.write_lp(buffer) assert e.value.args == ('No objective', )
def test_write(self, problem, x): objective = LpObjective(name='minimize_cpm', expression={x: 998}, constant=8) rhs = LpExpression('rhs', {x: 1}) lhs = LpExpression('lhs', {}, -2) constraint = LpConstraint(rhs, 'geq', lhs, 'constraint') problem.add_constraint(constraint) problem.set_objective(objective) buffer = StringIO() problem.write_lp(buffer) flipy_string = buffer.getvalue() assert flipy_string == '\\* test_problem *\\\nMinimize\nminimize_cpm: 998 x + 8\nSubject To\nconstraint: x >= -2\nBounds\nx <= 10\nEnd'
def test_write_with_empty_constraint(self, problem, x): objective = LpObjective(name='minimize_cpm', expression={x: 998}, constant=8, sense=Maximize) constraint = LpConstraint(LpExpression('lhs', {x: 0}), 'leq', LpExpression('rhs', {}), 'constraint') problem.add_constraint(constraint) problem.set_objective(objective) buffer = StringIO() problem.write_lp(buffer) flipy_string = buffer.getvalue() assert flipy_string == '\\* test_problem *\\\nMaximize\nminimize_cpm: 998 x + 8\nSubject To\nBounds\nx <= 10\nEnd'
def test_write_slack(self, problem, x): objective = LpObjective(name='minimize_cpm', expression={x: 998}, constant=8, sense=Maximize) rhs = LpExpression('rhs', {x: 1}) lhs = LpExpression('lhs', {}, -2) constraint = LpConstraint(rhs, 'leq', lhs, 'constraint', True, 100) problem.add_constraint(constraint) problem.set_objective(objective) buffer = StringIO() problem.write_lp(buffer) flipy_string = buffer.getvalue() assert flipy_string == '\\* test_problem *\\\nMaximize\nminimize_cpm: 998 x - 100 constraint_slack_variable + 8\nSubject To\nconstraint: - constraint_slack_variable + x <= -2\nBounds\nx <= 10\nEnd'
def test_write_long(self, problem, x): a = LpVariable('a', low_bound=0, up_bound=10, var_type=VarType.Integer) b = LpVariable('b', low_bound=0, up_bound=10, var_type=VarType.Integer) c = LpVariable('c', low_bound=0, up_bound=10, var_type=VarType.Integer) d = LpVariable('d', low_bound=0, up_bound=10, var_type=VarType.Integer) e = LpVariable('e', var_type=VarType.Binary) f = LpVariable('f', var_type=VarType.Binary) g = LpVariable('g', var_type=VarType.Binary) h = LpVariable('h', var_type=VarType.Binary) vars = [a, b, c, d, e, f, g, h] # make sure objective is long enough to test the line break objective = LpObjective(name='minimize_cpm', expression={v: 3.1415926535 for v in vars}, constant=8) rhs = LpExpression('rhs', {a: 1000, b: 1000, c: 1000, d: 1000}) lhs = LpExpression('lhs', {}, -2) constraint = LpConstraint(rhs, 'geq', lhs, 'constraint') problem.add_constraint(constraint) problem.set_objective(objective) buffer = StringIO() problem.write_lp(buffer) lp_str = buffer.getvalue() assert lp_str.split('\n') == [ '\\* test_problem *\\', 'Minimize', 'minimize_cpm: 3.1415926535 a + 3.1415926535 b + 3.1415926535 c + 3.1415926535 d', '+ 3.1415926535 e + 3.1415926535 f + 3.1415926535 g + 3.1415926535 h + 8', 'Subject To', 'constraint: 1000 a + 1000 b + 1000 c + 1000 d >= -2', 'Bounds', '0 <= a <= 10', '0 <= b <= 10', '0 <= c <= 10', '0 <= d <= 10', '0 <= e <= 1', '0 <= f <= 1', '0 <= g <= 1', '0 <= h <= 1', 'Generals', 'a', 'b', 'c', 'd', 'Binaries', 'e', 'f', 'g', 'h', 'End' ]
def test_invalid_slack(self, lhs): with pytest.raises(ValueError) as e: LpConstraint(lhs, 'leq', slack='invalid') assert 'slack' in e.message.lower()
def test_init_no_rhs(self, lhs): lp_constraint = LpConstraint(lhs, 'leq') assert lp_constraint.rhs == LpExpression()
def lp_constraint_with_slack(lhs, rhs): return LpConstraint(lhs, 'leq', rhs, 'test_constraint', True, 10.)
def lp_constraint(lhs, rhs): return LpConstraint(lhs, 'leq', rhs, 'test_constraint')
def read(cls, obj: Union[str, IO, TextIO, io.StringIO]) -> LpProblem: """ Reads in an LP file and parse it into a flipy.LpProblem object Raises ------ ValueError If `obj` is unreadable and is not a LP string Parameters ---------- obj: str or buffer Returns ------- LpProblem Parsed LpProblem based on the LP file """ if hasattr(obj, 'read'): content = obj.read() elif isinstance(obj, (str, bytes)): content = obj try: if os.path.isfile(content): with open(content, "rb") as f: content = f.read() except (TypeError, ValueError): pass else: raise ValueError("Cannot read object of type %r" % type(obj).__name__) content = content.strip() problem_name = cls._find_problem_name(content) is_maximize, sections = cls._split_content_by_sections( cls._remove_comments(content)) obj_name, obj_expr, obj_coeff = cls._parse_named_expression( sections['objective']) constraints = cls._parse_constraints( sections['constraints']) if 'constraints' in sections else [] bounds = cls._parse_bounds( sections['bounds']) if 'bounds' in sections else [] generals = cls._parse_generals( sections['generals']) if 'generals' in sections else [] binaries = cls._parse_binaries( sections['binaries']) if 'binaries' in sections else [] lp_variables = {} lp_objective = LpObjective(obj_name, constant=obj_coeff, sense=Maximize if is_maximize else Minimize) for obj_var_name, obj_coeff in obj_expr.items(): obj_var = cls._find_variable(lp_variables, obj_var_name) lp_objective.expr[obj_var] = obj_coeff lp_constraints = [] for constraint in constraints: lhs_expr = LpExpression() for var_name, cons_var_coeff in constraint['lhs'].items(): var = cls._find_variable(lp_variables, var_name) lhs_expr.expr[var] = cons_var_coeff lhs_expr.const = constraint['lhs_const'] rhs_expr = LpExpression() for var_name, cons_var_coeff in constraint['rhs'].items(): var = cls._find_variable(lp_variables, var_name) rhs_expr.expr[var] = cons_var_coeff rhs_expr.const = constraint['rhs_const'] lp_constraints.append( LpConstraint(lhs_expr, constraint['sense'], rhs_expr, name=constraint['name'])) cls._parse_variables(lp_variables, bounds, generals, binaries) return LpProblem(problem_name, lp_objective=lp_objective, lp_constraints=lp_constraints)
def test_invalid_slack_penalty(self, lhs): with pytest.raises(ValueError) as e: LpConstraint(lhs, 'leq', slack_penalty=-1) assert 'slack penalty' in e.message.lower()