예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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 == []
예제 #4
0
    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]))
예제 #5
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
예제 #6
0
    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)
예제 #7
0
    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 == []
예제 #8
0
    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 == []
예제 #9
0
    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
예제 #10
0
    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
예제 #11
0
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
예제 #12
0
 def __init__(self, problem, bounds, monotonicity, convexity):
     super().__init__()
     self._ctx = ProblemContext(problem, bounds, monotonicity, convexity)
     self._underestimator = self._root_underestimator()