def test_power(self, problem): ctx = ProblemContext(problem) r = McCormickExpressionRelaxation() power = problem.constraint('power').root_expr ctx.set_polynomiality(power, PolynomialDegree(2)) assert r.can_relax(problem, power, ctx)
def test_trilinear_terms(self, problem): ctx = ProblemContext(problem) r = McCormickExpressionRelaxation() trilinear = problem.constraint('trilinear').root_expr ctx.set_polynomiality(trilinear, PolynomialDegree(3)) assert not r.can_relax(problem, trilinear, ctx)
def test_univariate_concave(self, problem, constraint_name): ctx = ProblemContext(problem) r = UnivariateConcaveExpressionRelaxation() constraint_expr = problem.constraint(constraint_name).root_expr ctx.set_convexity(constraint_expr, Convexity.Concave) assert r.can_relax(problem, constraint_expr, ctx) result = r.relax(problem, constraint_expr, ctx) assert result.constraints == []
def test_bilinear_with_coef_2(self, problem): ctx = ProblemContext(problem) r = McCormickExpressionRelaxation() bilinear = problem.constraint('bilinear_coef_2').root_expr ctx.set_polynomiality(bilinear, PolynomialDegree(2)) assert r.can_relax(problem, bilinear, ctx) result = r.relax(problem, bilinear, ctx) self._check_constraints(result) expr = result.expression assert expr.expression_type == ExpressionType.Linear assert np.allclose(expr.coefficient(expr.children[0]), np.array([6.0]))
def test_bilinear_sum(self, problem): ctx = ProblemContext(problem) r = McCormickExpressionRelaxation() bilinear = problem.constraint('bilinear_sum').root_expr ctx.set_polynomiality(bilinear, PolynomialDegree(2)) assert r.can_relax(problem, bilinear, ctx) result = r.relax(problem, bilinear, ctx) assert len(result.constraints) == 12 expr = result.expression assert expr.expression_type == ExpressionType.Linear assert len(expr.children) == 3
def test_nonlinear_terms(self, problem): ctx = ProblemContext(problem) r = LinearExpressionRelaxation() nonlinear = problem.constraint('not_linear').root_expr assert not r.can_relax(problem, nonlinear, ctx)
def test_quadratic_expression(self, problem): ctx = ProblemContext(problem) r = ConvexExpressionRelaxation() constraint_expr = problem.constraint('c0').root_expr ctx.set_convexity(constraint_expr, Convexity.Unknown) assert r.can_relax(problem, constraint_expr, ctx) result = r.relax(problem, constraint_expr, ctx) expr = result.expression assert expr.expression_type == ExpressionType.Quadratic assert len(expr.terms) == 2 for term in expr.terms: assert term.var1 == term.var2 assert term.coefficient == 2.0 or term.coefficient == 4.0 assert result.constraints == []
def test_sum_of_convex_expressions(self, problem): ctx = ProblemContext(problem) r = ConvexExpressionRelaxation() constraint_expr = problem.objective.root_expr ctx.set_convexity(constraint_expr, Convexity.Convex) assert r.can_relax(problem, constraint_expr, ctx) result = r.relax(problem, constraint_expr, ctx) assert len(result.expression.children) == 2 assert result.expression.expression_type == ExpressionType.Sum a, b = result.expression.children assert a.expression_type == ExpressionType.UnaryFunction assert b.expression_type == ExpressionType.UnaryFunction assert result.constraints == []
def test_linear_terms(self, problem): ctx = ProblemContext(problem) r = LinearExpressionRelaxation() linear = problem.constraint('linear').root_expr assert r.can_relax(problem, linear, ctx) result = r.relax(problem, linear, ctx) assert result.constraints == [] assert result.expression == linear
def test_bilinear_terms(self, problem): r = McCormickExpressionRelaxation() ctx = ProblemContext(problem) bilinear = problem.constraint('bilinear').root_expr assert r.can_relax(problem, bilinear, ctx) result = r.relax(problem, bilinear, ctx) self._check_constraints(result) assert result.expression.expression_type == ExpressionType.Linear assert len(result.expression.children) == 1 aux_var = result.expression.children[0] assert aux_var.is_auxiliary
def detect_special_structure(problem, maxiter, timelimit): """Perform special structure detection on `problem`.""" ctx = ProblemContext(problem) bounds_tightener = BoundsTightener( FBBTStopCriterion(max_iter=maxiter, timelimit=timelimit), ) _initialize_bounds(problem, ctx.bounds, ctx.get_bounds, ctx.set_bounds) bounds_tightener.tighten(problem, ctx.bounds) _manage_infinity_bounds(problem, ctx.bounds, ctx.get_bounds, ctx.set_bounds) propagate_special_structure(problem, ctx) return ctx
def __init__(self, problem, bounds, monotonicity, convexity): super().__init__() self._ctx = ProblemContext(problem, bounds, monotonicity, convexity) self._underestimator = self._root_underestimator()