def f(model, i):
     if i == 0:
         return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0)
     if i == 1:
         return Complementarity.Skip
     if i == 2:
         return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2)
Beispiel #2
0
 def f(model, i):
     if i == 0:
         return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0)
     if i == 1:
         return Complementarity.Skip
     if i == 2:
         return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2)
Beispiel #3
0
 def test_list2(self):
     M = self._setup()
     M.cc = ComplementarityList()
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0))
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 1))
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2))
     M.cc[2].deactivate()
     self._test("list2", M)
 def test_list2(self):
     M = self._setup()
     M.cc = ComplementarityList()
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0))
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 1))
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2))
     M.cc[2].deactivate()
     self._test("list2", M)
 def test_t3b(self):
     # Reversing the expressions in test t3a:
     #    x1 + x2 >= -1  _|_  y + x3 >= 0
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.x1 + M.x2 >= -1, M.y + M.x3 >= 0))
     self._test("t3b", M)
 def test_t4b(self):
     # Reversing the expressions in test t7b:
     #    y + x3  _|_  x1 + 2*x2 + 3*x3 = 1
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.y + M.x3, M.x1 + 2 * M.x2 + 3 * M.x3 == 1))
     self._test("t4b", M)
 def test_t9(self):
     # Testing that we can skip deactivated complementarity conditions
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.y + M.x3, M.x1 +
                                             2 * M.x2 == 1))
     M.cc.deactivate()
     self._test("t9", M)
 def test_t1a(self):
     # y + x1 >= 0  _|_  x1 + 2*x2 + 3*x3 >= 1
     M = self._setup()
     M.c = Constraint(expr=M.y + M.x3 >= M.x2)
     M.cc = Complementarity(
         expr=complements(M.y + M.x1 >= 0, M.x1 + 2 * M.x2 + 3 * M.x3 >= 1))
     self._test("t1a", M)
 def test_t1b(self):
     # Reversing the expressions in test t1a:
     #    x1 + 2*x2 + 3*x3 >= 1  _|_  y + x1 >= 0
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.x1 + 2 * M.x2 + 3 * M.x3 >= 1, M.y + M.x1 >= 0))
     self._test("t1b", M)
 def test_t2b(self):
     # Reversing the expressions in test t2a:
     #    x2 - x3 <= -1  _|_  y + x2 >= 0
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.x2 - M.x3 <= -1, M.y + M.x2 >= 0))
     self._test("t2b", M)
Beispiel #11
0
 def test_list5(self):
     M = self._setup()
     M.cc = ComplementarityList(
         rule=( complements(M.y + M.x3, M.x1 + 2*M.x2 == i)
                for i in range(3) )
     )
     self._test("list5", M)
Beispiel #12
0
 def test_cov11(self):
     # Testing construction with a badly formed expression
     M = self._setup()
     M.cc = Complementarity(expr=complements(1 <= M.x1 <= M.y, M.x2))
     try:
         M.cc.to_standard_form()
         self.fail("Expected a RuntimeError")
     except RuntimeError:
         pass
 def test_cov11(self):
     # Testing construction with a badly formed expression
     M = self._setup()
     M.cc = Complementarity(expr=complements(1 <= M.x1 <= M.y, M.x2))
     try:
         M.cc.to_standard_form()
         self.fail("Expected a RuntimeError")
     except RuntimeError:
         pass
Beispiel #14
0
 def test_t9(self):
     # Testing that we can skip deactivated complementarity conditions
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.y + M.x3, M.x1 +
                                             2 * M.x2 == 1))
     M.cc.deactivate()
     # AMPL needs at least one variable in the problem therefore
     # we need to have a constraint that keeps them around
     M.keep_var_con = Constraint(expr=M.x1 == 0.5)
     self._test("t9", M)
Beispiel #15
0
    def get_model(self):
        m = ConcreteModel()
        m.x = Var(bounds=(-100, 100))

        m.obj = Objective(expr=m.x)

        m.disjunct1 = Disjunct()
        m.disjunct1.comp = Complementarity(expr=complements(m.x >= 0, 4*m.x - 3 >= 0))
        m.disjunct2 = Disjunct()
        m.disjunct2.cons = Constraint(expr=m.x >= 2)

        m.disjunction = Disjunction(expr=[m.disjunct1, m.disjunct2])

        return m
Beispiel #16
0
 def test_t4c(self):
     # 1 = x1 + 2*x2 + 3*x3  _|_  y + x3
     M = self._setup()
     M.cc = Complementarity(expr=complements(1 == M.x1 + 2 * M.x2 + 3 * M.x3, M.y + M.x3))
     self._test("t4c", M)
 def f(M, i):
     if i == 1:
         return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0)
     elif i == 2:
         return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2)
     return ComplementarityList.End
 def test_list1(self):
     M = self._setup()
     M.cc = ComplementarityList()
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0))
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2))
     self._test("list1", M)
Beispiel #19
0
 def test_t9(self):
     # Testing that we can skip deactivated complementarity conditions
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.y + M.x3, M.x1 + 2 * M.x2 == 1))
     M.cc.deactivate()
     self._test("t9", M)
 def test_t11(self):
     # 2 <= y + x1 <= 3  _|_  x1
     M = self._setup()
     M.cc = Complementarity(expr=complements(inequality(2, M.y +
                                                        M.x1, 3), M.x1))
     self._test("t11", M)
Beispiel #21
0
 def f(M, i):
     if i == 1:
         return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0)
     elif i == 2:
         return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2)
     return ComplementarityList.End
Beispiel #22
0
# ex1e.py
import pyomo.environ as pyo
from pyomo.mpec import ComplementarityList, complements

n = 5

model = pyo.ConcreteModel()

model.x = pyo.Var(range(1, n + 1))

model.f = pyo.Objective(expr=sum(i * (model.x[i] - 1)**2
                                 for i in range(1, n + 1)))

model.compl = ComplementarityList(
    rule=(complements(model.x[i] >= 0, model.x[i + 1] >= 0)
          for i in range(1, n)))
Beispiel #23
0
 def test_t2a(self):
     # y + x2 >= 0  _|_  x2 - x3 <= -1
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.y + M.x2 >= 0, M.x2 - M.x3 <= -1))
     self._test("t2a", M)
Beispiel #24
0
 def test_t1c(self):
     # y >= - x1  _|_  x1 + 2*x2 >= 1 - 3*x3
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.y >= -M.x1, M.x1 + 2 * M.x2 >= 1 - 3 * M.x3))
     self._test("t1c", M)
Beispiel #25
0
 def test_t1b(self):
     # Reversing the expressions in test t1a:
     #    x1 + 2*x2 + 3*x3 >= 1  _|_  y + x1 >= 0
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.x1 + 2 * M.x2 + 3 * M.x3 >= 1, M.y + M.x1 >= 0))
     self._test("t1b", M)
Beispiel #26
0
 def test_t1a(self):
     # y + x1 >= 0  _|_  x1 + 2*x2 + 3*x3 >= 1
     M = self._setup()
     M.c = Constraint(expr=M.y + M.x3 >= M.x2)
     M.cc = Complementarity(expr=complements(M.y + M.x1 >= 0, M.x1 + 2 * M.x2 + 3 * M.x3 >= 1))
     self._test("t1a", M)
Beispiel #27
0
 def test_list5(self):
     M = self._setup()
     M.cc = ComplementarityList(rule=(complements(M.y + M.x3, M.x1 + 2 * M.x2 == i) for i in range(3)))
     self._test("list5", M)
Beispiel #28
0
 def f(M):
     yield complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0)
     yield complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2)
     yield ComplementarityList.End
 def test_t1c(self):
     # y >= - x1  _|_  x1 + 2*x2 >= 1 - 3*x3
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.y >= -M.x1, M.x1 + 2 * M.x2 >= 1 - 3 * M.x3))
     self._test("t1c", M)
Beispiel #30
0
 def test_t4a(self):
     # x1 + 2*x2 + 3*x3 = 1  _|_  y + x3
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.x1 + 2 * M.x2 + 3 * M.x3 == 1, M.y + M.x3))
     self._test("t4a", M)
Beispiel #31
0
 def test_t2b(self):
     # Reversing the expressions in test t2a:
     #    x2 - x3 <= -1  _|_  y + x2 >= 0
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.x2 - M.x3 <= -1, M.y + M.x2 >= 0))
     self._test("t2b", M)
Beispiel #32
0
def compl_(model, i):
    return complements(model.x[i] >= 0, model.x[i+1] >= 0)
Beispiel #33
0
 def test_t3a(self):
     # y + x3 >= 0  _|_  x1 + x2 >= -1
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.y + M.x3 >= 0, M.x1 + M.x2 >= -1))
     self._test("t3a", M)
Beispiel #34
0
 def test_t11(self):
     # 2 <= y + x1 <= 3  _|_  x1
     M = self._setup()
     M.cc = Complementarity(expr=complements(2 <= M.y + M.x1 <= 3, M.x1))
     self._test("t11", M)
Beispiel #35
0
 def test_t3b(self):
     # Reversing the expressions in test t3a:
     #    x1 + x2 >= -1  _|_  y + x3 >= 0
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.x1 + M.x2 >= -1, M.y + M.x3 >= 0))
     self._test("t3b", M)
 def test_t12(self):
     # x1  _|_  2 <= y + x1 <= 3"""
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.x1, inequality(2, M.y + M.x1, 3)))
     self._test("t12", M)
Beispiel #37
0
    def _add_optimality_conditions(self, instance, submodel):
        """
        Add optimality conditions for the submodel

        This assumes that the original model has the form:

            min c1*x + d1*y
                A3*x <= b3
                A1*x + B1*y <= b1
                min c2*x + d2*y + x'*Q*y
                    A2*x + B2*y + x'*E2*y <= b2
                    y >= 0

        NOTE THE VARIABLE BOUNDS!
        """
        #
        # Populate the block with the linear constraints.
        # Note that we don't simply clone the current block.
        # We need to collect a single set of equations that
        # can be easily expressed.
        #
        d2 = {}
        B2 = {}
        vtmp = {}
        utmp = {}
        sids_set = set()
        sids_list = []
        #
        block = Block(concrete=True)
        block.u = VarList()
        block.v = VarList()
        block.c1 = ConstraintList()
        block.c2 = ComplementarityList()
        block.c3 = ComplementarityList()
        #
        # Collect submodel objective terms
        #
        # TODO: detect fixed variables
        #
        for odata in submodel.component_data_objects(Objective, active=True):
            if odata.sense == maximize:
                d_sense = -1
            else:
                d_sense = 1
            #
            # Iterate through the variables in the representation
            #
            o_terms = generate_standard_repn(odata.expr, compute_values=False)
            #
            # Linear terms
            #
            for i, var in enumerate(o_terms.linear_vars):
                if var.parent_component().local_name in self._fixed_upper_vars:
                    #
                    # Skip fixed upper variables
                    #
                    continue
                #
                # Store the coefficient for the variable.  The coefficient is
                # negated if the objective is maximized.
                #
                id_ = id(var)
                d2[id_] = d_sense * o_terms.linear_coefs[i]
                if not id_ in sids_set:
                    sids_set.add(id_)
                    sids_list.append(id_)
            #
            # Quadratic terms
            #
            for i, var in enumerate(o_terms.quadratic_vars):
                if var[0].parent_component().local_name in self._fixed_upper_vars:
                    if var[1].parent_component().local_name in self._fixed_upper_vars:
                        #
                        # Skip fixed upper variables
                        #
                        continue
                    #
                    # Add the linear term
                    #
                    id_ = id(var[1])
                    d2[id_] = d2.get(id_,0) + d_sense * o_terms.quadratic_coefs[i] * var[0]
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
                elif var[1].parent_component().local_name in self._fixed_upper_vars:
                    #
                    # Add the linear term
                    #
                    id_ = id(var[0])
                    d2[id_] = d2.get(id_,0) + d_sense * o_terms.quadratic_coefs[i] * var[1]
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
                else:
                    raise RuntimeError("Cannot apply this transformation to a problem with quadratic terms where both variables are in the lower level.")
            #
            # Stop after the first objective
            #
            break
        #
        # Iterate through all lower level variables, adding dual variables
        # and complementarity slackness conditions for y bound constraints
        #
        for vcomponent in instance.component_objects(Var, active=True):
            if vcomponent.local_name in self._fixed_upper_vars:
                #
                # Skip fixed upper variables
                #
                continue
            for ndx in vcomponent:
                #
                # For each index, get the bounds for the variable
                #
                lb, ub = vcomponent[ndx].bounds
                if not lb is None:
                    #
                    # Add the complementarity slackness condition for a lower bound
                    #
                    v = block.v.add()
                    block.c3.add( complements(vcomponent[ndx] >= lb, v >= 0) )
                else:
                    v = None
                if not ub is None:
                    #
                    # Add the complementarity slackness condition for an upper bound
                    #
                    w = block.v.add()
                    vtmp[id(vcomponent[ndx])] = w
                    block.c3.add( complements(vcomponent[ndx] <= ub, w >= 0) )
                else:
                    w = None
                if not (v is None and w is None):
                    #
                    # Record the variables for which complementarity slackness conditions
                    # were created.
                    #
                    id_ = id(vcomponent[ndx])
                    vtmp[id_] = (v,w)
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
        #
        # Iterate through all constraints, adding dual variables and
        # complementary slackness conditions (for inequality constraints)
        #
        for cdata in submodel.component_data_objects(Constraint, active=True):
            if cdata.equality:
                # Don't add a complementary slackness condition for an equality constraint
                u = block.u.add()
                utmp[id(cdata)] = (None,u)
            else:
                if not cdata.lower is None:
                    #
                    # Add the complementarity slackness condition for a greater-than inequality
                    #
                    u = block.u.add()
                    block.c2.add( complements(- cdata.body <= - cdata.lower, u >= 0) )
                else:
                    u = None
                if not cdata.upper is None:
                    #
                    # Add the complementarity slackness condition for a less-than inequality
                    #
                    w = block.u.add()
                    block.c2.add( complements(cdata.body <= cdata.upper, w >= 0) )
                else:
                    w = None
                if not (u is None and w is None):
                    utmp[id(cdata)] = (u,w)
            #
            # Store the coefficients for the constraint variables that are not fixed
            #
            c_terms = generate_standard_repn(cdata.body, compute_values=False)
            #
            # Linear terms
            #
            for i, var in enumerate(c_terms.linear_vars):
                if var.parent_component().local_name in self._fixed_upper_vars:
                    continue
                id_ = id(var)
                B2.setdefault(id_,{}).setdefault(id(cdata),c_terms.linear_coefs[i])
                if not id_ in sids_set:
                    sids_set.add(id_)
                    sids_list.append(id_)
            #
            # Quadratic terms
            #
            for i, var in enumerate(c_terms.quadratic_vars):
                if var[0].parent_component().local_name in self._fixed_upper_vars:
                    if var[1].parent_component().local_name in self._fixed_upper_vars:
                        continue
                    id_ = id(var[1])
                    if id_ in B2:
                        B2[id_][id(cdata)] = c_terms.quadratic_coefs[i] * var[0]
                    else:
                        B2.setdefault(id_,{}).setdefault(id(cdata),c_terms.quadratic_coefs[i] * var[0])
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
                elif var[1].parent_component().local_name in self._fixed_upper_vars:
                    id_ = id(var[0])
                    if id_ in B2:
                        B2[id_][id(cdata)] = c_terms.quadratic_coefs[i] * var[1]
                    else:
                        B2.setdefault(id_,{}).setdefault(id(cdata),c_terms.quadratic_coefs[i] * var[1])
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
                else:
                    raise RuntimeError("Cannot apply this transformation to a problem with quadratic terms where both variables are in the lower level.")
        #
        # Generate stationarity equations
        #
        tmp__ = (None, None)
        for vid in sids_list:
            exp = d2.get(vid,0)
            #
            lb_dual, ub_dual = vtmp.get(vid, tmp__)
            if vid in vtmp:
                if not lb_dual is None:
                    exp -= lb_dual             # dual for variable lower bound
                if not ub_dual is None:
                    exp += ub_dual             # dual for variable upper bound
            #
            B2_ = B2.get(vid,{})
            utmp_keys = list(utmp.keys())
            if self._deterministic:
                utmp_keys.sort(key=lambda x:utmp[x][0].local_name if utmp[x][1] is None else utmp[x][1].local_name)
            for uid in utmp_keys:
                if uid in B2_:
                    lb_dual, ub_dual = utmp[uid]
                    if not lb_dual is None:
                        exp -= B2_[uid] * lb_dual
                    if not ub_dual is None:
                        exp += B2_[uid] * ub_dual
            if type(exp) in six.integer_types or type(exp) is float:
                # TODO: Annotate the model as unbounded
                raise IOError("Unbounded variable without side constraints")
            else:
                block.c1.add( exp == 0 )
        #
        # Return block
        #
        return block
 def f(model):
     return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 1)
Beispiel #39
0
    def _apply_solver(self):
        start_time = time.time()
        M=self.options.dual_bound
        if not self.options.dual_bound:
            M=1e6
            print(f'Dual bound not specified, set to default {M}')
        delta = self.options.delta
        if not self.options.delta:
            delta = 0.05 #What should default robustness delta be if not specified? Or should I raise an error?
            print(f'Robustness parameter not specified, set to default {delta}')
        # matrix representation for bilevel problem
        matrix_repn = BilevelMatrixRepn(self._instance,standard_form=False)

        # each lower-level problem
        submodel = [block for block in self._instance.component_objects(SubModel)][0]
        if len(submodel) != 1:
            raise Exception('Problem encountered, this is not a valid bilevel model for the solver.')
        self._instance.reclassify_component_type(submodel, Block)
        #varref(submodel)
        #dataref(submodel)

        all_vars = {key: var for (key, var) in matrix_repn._all_vars.items()}

        # get the variables that are fixed for the submodel (lower-level block)
        fixed_vars = {key: var for (key, var) in matrix_repn._all_vars.items() if key in matrix_repn._fixed_var_ids[submodel.name]}
        
        #Is there a way to get integer, continuous, etc for the upper level rather than lumping them all into fixed?

        # continuous variables in SubModel
        c_vars = {key: var for (key, var) in matrix_repn._all_vars.items() if key in matrix_repn._c_var_ids - fixed_vars.keys()}

        # binary variables in SubModel SHOULD BE EMPTY FOR THIS SOLVER
        b_vars = {key: var for (key, var) in matrix_repn._all_vars.items() if key in matrix_repn._b_var_ids - fixed_vars.keys()}
        if len(b_vars)!= 0:
            raise Exception('Problem encountered, this is not a valid bilevel model for the solver. Binary variables present!')
            
        # integer variables in SubModel SHOULD BE EMPTY FOR THIS SOLVER
        i_vars = {key: var for (key, var) in matrix_repn._all_vars.items() if key in matrix_repn._i_var_ids - fixed_vars.keys()}
        if len(i_vars) != 0:
            raise Exception('Problem encountered, this is not a valid bilevel model for the solver. Integer variables present!')
            
        # get constraint information related to constraint id, sign, and rhs value
        sub_cons = matrix_repn._cons_sense_rhs[submodel.name]
        
        cons= matrix_repn._cons_sense_rhs[self._instance.name]
        
        # construct the high-point problem (LL feasible, no LL objective)
        # s0 <- solve the high-point
        # if s0 infeasible then return high_point_infeasible
        xfrm = TransformationFactory('pao.bilevel.highpoint')
        xfrm.apply_to(self._instance)
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:
            solver = 'gurobi'

        for c in self._instance.component_objects(Block, descend_into=False): 
            if 'hp' in c.name:
            #if '_hp' in c.name:
                c.activate()
                with pyomo.opt.SolverFactory(solver) as opt:
                    self.results.append(opt.solve(c,
                                              tee=self._tee,
                                              timelimit=self._timelimit))
                _check_termination_condition(self.results[-1])
                c.deactivate()
        if self.options.do_print==True:
            print('Solution to the Highpoint Relaxation')
            for _, var in all_vars.items():
                var.pprint()
        
        # s1 <- solve the optimistic bilevel (linear/linear) problem (call solver3)
        # if s1 infeasible then return optimistic_infeasible'
        with pyomo.opt.SolverFactory('pao.bilevel.blp_global') as opt:
            opt.options.solver = solver
            self.results.append(opt.solve(self._instance,tee=self._tee,timelimit=self._timelimit))
        _check_termination_condition(self.results[-1])
        if self.options.do_print==True:
            print('Solution to the Optimistic Bilevel')
            for _, var in all_vars.items():
                var.pprint()
        #self._instance.pprint() #checking for active blocks left over from previous solves
        
        # sk <- solve the dual adversarial  problem
        # if infeasible then return dual_adversarial_infeasible

        # Collect the vertices solutions for the dual adversarial problem
        
        #Collect up the matrix B and the vector d for use in all adversarial feasibility problems 
        n=len(c_vars.items())
        m=len(sub_cons.items())
        K=len(cons.items())
        B=np.empty([m,n])
        L=np.empty([K,1])
        i=0
        p=0
        for _, var in c_vars.items():
            (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
            B[:,i]=np.transpose(np.array(A))
            i+=1
        
        _ad_block_name='_adversarial'
        self._instance.add_component(_ad_block_name, Block(Any))
        _Vertices_name='_Vertices'
        _Vertices_B_name='_VerticesB'
        self._instance.add_component(_Vertices_name,Param(cons.keys()*NonNegativeIntegers*sub_cons.keys(),mutable=True))
        Vertices=getattr(self._instance,_Vertices_name)
        self._instance.add_component(_Vertices_B_name,Param(cons.keys()*NonNegativeIntegers,mutable=True))
        VerticesB=getattr(self._instance,_Vertices_B_name)
        adversarial=getattr(self._instance,_ad_block_name)
        #Add Adversarial blocks
        for _cidS, _ in cons.items(): # <for each constraint in the upper-level problem>
            (_cid,_)=_cidS
            ad=adversarial[_cid] #shorthand
            ad.alpha=Var(sub_cons.keys(),within=NonNegativeReals) #sub_cons.keys() because it's a dual variable on the lower level constraints
            ad.beta=Var(within=NonNegativeReals)
            Hk=np.empty([n,1])
            i=0
            d=np.empty([n,1])
             
            ad.cons=Constraint(c_vars.keys()) #B^Talpha+beta*d>= H_k, v-dimension constraints so index by c_vars
            lhs_expr = {key: 0. for key in c_vars.keys()}
            rhs_expr = {key: 0. for key in c_vars.keys()}
            for _vid, var in c_vars.items():
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                coef = A #+ dot(A_q.toarray(), _fixed)
                
                (C, C_q, C_constant) = matrix_repn.cost_vectors(submodel, var)
                d[i,0]=float(C)
                lhs_expr[_vid]=float(C)*ad.beta
                
                (A,A_q,sign,b)=matrix_repn.coef_matrices(self._instance,var)
                idx = list(cons.keys()).index(_cidS)
                Hk[i,0]=A[idx]
                i+=1
                
                for _cid2 in sub_cons.keys():
                    idx = list(sub_cons.keys()).index(_cid2)
                    lhs_expr[_vid] += float(coef[idx])*ad.alpha[_cid2]
                
                rhs_expr[_vid] = float(A[idx])
                expr = lhs_expr[_vid] >= rhs_expr[_vid]
                if not type(expr) is bool:
                    ad.cons[_vid] = expr
                else:
                    ad.cons[_vid] = Constraint.Skip
             
            ad.Obj=Objective(expr=0) #THIS IS A FEASIBILITY PROBLEM
            with pyomo.opt.SolverFactory(solver) as opt:
                    self.results.append(opt.solve(ad,
                                              tee=self._tee,
                                              timelimit=self._timelimit))
            _check_termination_condition(self.results[-1]) 
            ad.deactivate()
        
            Bd=np.hstack((np.transpose(B),d))
            Eye=np.identity(m+1)
            Bd=np.vstack((Bd,Eye))
            Hk=np.vstack((Hk,np.zeros((m+1,1))))
            
            
            mat=np.hstack((-Hk,Bd))
            mat=cdd.Matrix(mat,number_type='float') 
            
            mat.rep_type=cdd.RepType.INEQUALITY
            poly=cdd.Polyhedron(mat)
            ext=poly.get_generators()
            extreme=np.array(ext)
            if self.options.do_print==True:
                print(ext)
            
            (s,t)=extreme.shape
            l=1
            for i in range(0,s):
                j=1
                if extreme[0,i]==1:
                    for _scid in sub_cons.keys():  
                    #for j in range(1,t-1): #Need to loop over extreme 1 to t-1 and link those to the cons.keys for alpha? 
                        Vertices[(_cidS,l,_scid)]=extreme[i,j] #Vertex l of the k-th polytope
                        j+=1
                    VerticesB[(_cidS,l)]=extreme[i,t-1]                    
                    l+=1
            L[p,0]=l-1  
            p+=1
        #vertex enumeration goes from 1 to L
        
        
        # Solving the full problem sn0
        _model_name = '_extended'
        _model_name = unique_component_name(self._instance, _model_name)
        
        xfrm = TransformationFactory('pao.bilevel.highpoint') #5.6a-c
        kwds = {'submodel_name': _model_name}
        xfrm.apply_to(self._instance, **kwds)    
        extended=getattr(self._instance,_model_name)
        extended.sigma=Var(c_vars.keys(),within=NonNegativeReals,bounds=(0,M))
        extended.lam=Var(sub_cons.keys(),within=NonNegativeReals,bounds=(0,M))
        
        #5.d   
        extended.d = Constraint(c_vars.keys()) #indexed by lower level variables
        d_expr= {key: 0. for key in c_vars.keys()}
        for _vid, var in c_vars.items():
            (C, C_q, C_constant) = matrix_repn.cost_vectors(submodel, var) #gets d_i
            d_expr[_vid]+=float(C)
            d_expr[_vid]=d_expr[_vid]-extended.sigma[_vid]
            (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
            for _cid, _ in sub_cons.items():
                idx = list(sub_cons.keys()).index(_cid)
                d_expr[_vid]+=extended.lam[_cid]*float(A[idx])
        expr = d_expr[_vid] == 0
        if not type(expr) is bool:
            extended.d[_vid] = expr
        else:
            extended.d[_vid] = Constraint.Skip   
        #5.e (Complementarity)
        extended.e = ComplementarityList()
        for _cid, _ in sub_cons.items():
            idx=list(sub_cons.keys()).index(_cid)
            expr=0
            for _vid, var in fixed_vars.items(): #A_i*x
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                expr+=float(A[idx])*fixed_vars[_vid]  
            for _vid, var in c_vars.items(): #B_i*v
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                expr+=float(A[idx])*c_vars[_vid]
            expr=expr-float(b[idx])
            extended.e.add(complements(extended.lam[_cid] >= 0, expr <= 0))
            
        
        #5.f (Complementarity)
        extended.f = ComplementarityList()
        for _vid,var in c_vars.items():
            extended.f.add(complements(extended.sigma[_vid]>=0,var>=0))
        
        #Replace 5.h-5.j with 5.7 Disjunction
        extended.disjunction=Block(cons.keys()) #One disjunction per adversarial problem, one adversarial problem per upper level constraint
        k=0
        for _cidS,_ in cons.items():
            idxS=list(cons.keys()).index(_cidS)
            [_cid,sign]=_cidS
            disjunction=extended.disjunction[_cidS] #shorthand
            disjunction.Lset=RangeSet(1,L[k,0])
            disjunction.disjuncts=Disjunct(disjunction.Lset)
            for i in disjunction.Lset: #defining the L disjuncts
                l_expr=0
                for _vid, var in c_vars.items():
                    (C, C_q, C_constant) = matrix_repn.cost_vectors(submodel, var)
                    l_expr+=float(C)*var #d^Tv 
                l_expr+=delta
                l_expr=VerticesB[(_cidS,i)]*l_expr #beta(d^Tv+delta)
            
                for _cid, Scons in sub_cons.items(): #SUM over i to ml
                    Ax=0
                    idx=list(sub_cons.keys()).index(_cid)
                    for _vid, var in fixed_vars.items():
                        (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                        Ax += float(A[idx])*var
                    l_expr+=Vertices[(_cidS,i,_cid)]*(float(b[idx])-Ax)
                         
                r_expr=0
                for _vid,var in fixed_vars.items():
                    (A, A_q, sign, b) = matrix_repn.coef_matrices(self._instance, var) #get q and G
                    r_expr=r_expr-float(A[idxS])*var
                r_expr+=float(b[idxS])
                        
                disjunction.disjuncts[i].cons=Constraint(expr= l_expr<=r_expr)
    
            disjunction.seven=Disjunction(expr=[disjunction.disjuncts[i] for i in disjunction.Lset],xor=False)    
            k+=1
        #extended.pprint()
        TransformationFactory('mpec.simple_disjunction').apply_to(extended)
        bigm = TransformationFactory('gdp.bigm')
        bigm.apply_to(extended)
        with pyomo.opt.SolverFactory(solver) as opt:
            self.results.append(opt.solve(extended,
                                             tee=self._tee,
                                             timelimit=self._timelimit))
            _check_termination_condition(self.results[-1]) 
        # Return the sn0 solution
        if self.options.do_print==True:
            print('Robust Solution')
            for _vid, _ in fixed_vars.items():
                fixed_vars[_vid].pprint()
            for _vid, _ in c_vars.items():
                c_vars[_vid].pprint()
                extended.lam.pprint()
                extended.sigma.pprint()
        stop_time = time.time()
        self.wall_time = stop_time - start_time
        return pyutilib.misc.Bunch(rc=getattr(opt, '_rc', None),
                                           log=getattr(opt, '_log', None))
Beispiel #40
0
 def test_t4d(self):
     # x1 + 2*x2 == 1 - 3*x3  _|_  y + x3
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.x1 + 2 * M.x2 == 1 - 3 * M.x3, M.y + M.x3))
     self._test("t4d", M)
Beispiel #41
0
from pyomo import environ, mpec

model = environ.ConcreteModel()

# define the model variables
model.x1 = environ.Var()
model.x2 = environ.Var()
model.x3 = environ.Var()

# define the complementarity conditions
model.f1 = mpec.Complementarity(
    expr=mpec.complements(model.x1 >= 0, model.x1 + 2 * model.x2 +
                          3 * model.x3 >= 1))
model.f2 = mpec.Complementarity(
    expr=mpec.complements(model.x2 >= 0, model.x2 - model.x3 >= -1))
model.f3 = mpec.Complementarity(
    expr=mpec.complements(model.x3 >= 0, model.x1 + model.x2 >= -1))
 def f(M):
     yield complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0)
     yield complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2)
     yield ComplementarityList.End
Beispiel #43
0
 def f(model):
     return complements(M.y + M.x3, M.x1 + 2 * M.x2 == 1)
Beispiel #44
0
 def test_t4b(self):
     # Reversing the expressions in test t7b:
     #    y + x3  _|_  x1 + 2*x2 + 3*x3 = 1
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.y + M.x3, M.x1 + 2 * M.x2 + 3 * M.x3 == 1))
     self._test("t4b", M)
 def test_t4a(self):
     # x1 + 2*x2 + 3*x3 = 1  _|_  y + x3
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.x1 + 2 * M.x2 + 3 * M.x3 == 1, M.y + M.x3))
     self._test("t4a", M)
 def test_t2a(self):
     # y + x2 >= 0  _|_  x2 - x3 <= -1
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.y + M.x2 >= 0, M.x2 - M.x3 <= -1))
     self._test("t2a", M)
Beispiel #47
0
 def test_t12(self):
     # x1  _|_  2 <= y + x1 <= 3"""
     M = self._setup()
     M.cc = Complementarity(expr=complements(M.x1, 2 <= M.y + M.x1 <= 3))
     self._test("t12", M)
 def test_t3a(self):
     # y + x3 >= 0  _|_  x1 + x2 >= -1
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.y + M.x3 >= 0, M.x1 + M.x2 >= -1))
     self._test("t3a", M)
 def test_t4c(self):
     # 1 = x1 + 2*x2 + 3*x3  _|_  y + x3
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(1 == M.x1 + 2 * M.x2 + 3 * M.x3, M.y + M.x3))
     self._test("t4c", M)
Beispiel #50
0
    def _add_optimality_conditions(self, instance, submodel):
        """
        Add optimality conditions for the submodel

        This assumes that the original model has the form:

            min c1*x + d1*y
                A3*x <= b3
                A1*x + B1*y <= b1
                min c2*x + d2*y + x'*Q*y
                    A2*x + B2*y + x'*E2*y <= b2
                    y >= 0

        NOTE THE VARIABLE BOUNDS!
        """
        #
        # Populate the block with the linear constraints.
        # Note that we don't simply clone the current block.
        # We need to collect a single set of equations that
        # can be easily expressed.
        #
        d2 = {}
        B2 = {}
        vtmp = {}
        utmp = {}
        sids_set = set()
        sids_list = []
        #
        block = Block(concrete=True)
        block.u = VarList()
        block.v = VarList()
        block.c1 = ConstraintList()
        block.c2 = ComplementarityList()
        block.c3 = ComplementarityList()
        #
        # Collect submodel objective terms
        #
        # TODO: detect fixed variables
        #
        for odata in submodel.component_data_objects(Objective, active=True):
            if odata.sense == maximize:
                d_sense = -1
            else:
                d_sense = 1
            #
            # Iterate through the variables in the representation
            #
            o_terms = generate_standard_repn(odata.expr, compute_values=False)
            #
            # Linear terms
            #
            for i, var in enumerate(o_terms.linear_vars):
                if var.parent_component().local_name in self._fixed_upper_vars:
                    #
                    # Skip fixed upper variables
                    #
                    continue
                #
                # Store the coefficient for the variable.  The coefficient is
                # negated if the objective is maximized.
                #
                id_ = id(var)
                d2[id_] = d_sense * o_terms.linear_coefs[i]
                if not id_ in sids_set:
                    sids_set.add(id_)
                    sids_list.append(id_)
            #
            # Quadratic terms
            #
            for i, var in enumerate(o_terms.quadratic_vars):
                if var[0].parent_component(
                ).local_name in self._fixed_upper_vars:
                    if var[1].parent_component(
                    ).local_name in self._fixed_upper_vars:
                        #
                        # Skip fixed upper variables
                        #
                        continue
                    #
                    # Add the linear term
                    #
                    id_ = id(var[1])
                    d2[id_] = d2.get(
                        id_, 0) + d_sense * o_terms.quadratic_coefs[i] * var[0]
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
                elif var[1].parent_component(
                ).local_name in self._fixed_upper_vars:
                    #
                    # Add the linear term
                    #
                    id_ = id(var[0])
                    d2[id_] = d2.get(
                        id_, 0) + d_sense * o_terms.quadratic_coefs[i] * var[1]
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
                else:
                    raise RuntimeError(
                        "Cannot apply this transformation to a problem with quadratic terms where both variables are in the lower level."
                    )
            #
            # Stop after the first objective
            #
            break
        #
        # Iterate through all lower level variables, adding dual variables
        # and complementarity slackness conditions for y bound constraints
        #
        for vcomponent in instance.component_objects(Var, active=True):
            if vcomponent.local_name in self._fixed_upper_vars:
                #
                # Skip fixed upper variables
                #
                continue
            for ndx in vcomponent:
                #
                # For each index, get the bounds for the variable
                #
                lb, ub = vcomponent[ndx].bounds
                if not lb is None:
                    #
                    # Add the complementarity slackness condition for a lower bound
                    #
                    v = block.v.add()
                    block.c3.add(complements(vcomponent[ndx] >= lb, v >= 0))
                else:
                    v = None
                if not ub is None:
                    #
                    # Add the complementarity slackness condition for an upper bound
                    #
                    w = block.v.add()
                    vtmp[id(vcomponent[ndx])] = w
                    block.c3.add(complements(vcomponent[ndx] <= ub, w >= 0))
                else:
                    w = None
                if not (v is None and w is None):
                    #
                    # Record the variables for which complementarity slackness conditions
                    # were created.
                    #
                    id_ = id(vcomponent[ndx])
                    vtmp[id_] = (v, w)
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
        #
        # Iterate through all constraints, adding dual variables and
        # complementary slackness conditions (for inequality constraints)
        #
        for cdata in submodel.component_data_objects(Constraint, active=True):
            if cdata.equality:
                # Don't add a complementary slackness condition for an equality constraint
                u = block.u.add()
                utmp[id(cdata)] = (None, u)
            else:
                if not cdata.lower is None:
                    #
                    # Add the complementarity slackness condition for a greater-than inequality
                    #
                    u = block.u.add()
                    block.c2.add(
                        complements(-cdata.body <= -cdata.lower, u >= 0))
                else:
                    u = None
                if not cdata.upper is None:
                    #
                    # Add the complementarity slackness condition for a less-than inequality
                    #
                    w = block.u.add()
                    block.c2.add(complements(cdata.body <= cdata.upper,
                                             w >= 0))
                else:
                    w = None
                if not (u is None and w is None):
                    utmp[id(cdata)] = (u, w)
            #
            # Store the coefficients for the contraint variables that are not fixed
            #
            c_terms = generate_standard_repn(cdata.body, compute_values=False)
            #
            # Linear terms
            #
            for i, var in enumerate(c_terms.linear_vars):
                if var.parent_component().local_name in self._fixed_upper_vars:
                    continue
                id_ = id(var)
                B2.setdefault(id_, {}).setdefault(id(cdata),
                                                  c_terms.linear_coefs[i])
                if not id_ in sids_set:
                    sids_set.add(id_)
                    sids_list.append(id_)
            #
            # Quadratic terms
            #
            for i, var in enumerate(c_terms.quadratic_vars):
                if var[0].parent_component(
                ).local_name in self._fixed_upper_vars:
                    if var[1].parent_component(
                    ).local_name in self._fixed_upper_vars:
                        continue
                    id_ = id(var[1])
                    if id_ in B2:
                        B2[id_][id(
                            cdata)] = c_terms.quadratic_coefs[i] * var[0]
                    else:
                        B2.setdefault(id_, {}).setdefault(
                            id(cdata), c_terms.quadratic_coefs[i] * var[0])
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
                elif var[1].parent_component(
                ).local_name in self._fixed_upper_vars:
                    id_ = id(var[0])
                    if id_ in B2:
                        B2[id_][id(
                            cdata)] = c_terms.quadratic_coefs[i] * var[1]
                    else:
                        B2.setdefault(id_, {}).setdefault(
                            id(cdata), c_terms.quadratic_coefs[i] * var[1])
                    if not id_ in sids_set:
                        sids_set.add(id_)
                        sids_list.append(id_)
                else:
                    raise RuntimeError(
                        "Cannot apply this transformation to a problem with quadratic terms where both variables are in the lower level."
                    )
        #
        # Generate stationarity equations
        #
        tmp__ = (None, None)
        for vid in sids_list:
            exp = d2.get(vid, 0)
            #
            lb_dual, ub_dual = vtmp.get(vid, tmp__)
            if vid in vtmp:
                if not lb_dual is None:
                    exp -= lb_dual  # dual for variable lower bound
                if not ub_dual is None:
                    exp += ub_dual  # dual for variable upper bound
            #
            B2_ = B2.get(vid, {})
            utmp_keys = list(utmp.keys())
            if self._deterministic:
                utmp_keys.sort(key=lambda x: utmp[x][0].local_name if utmp[x][
                    1] is None else utmp[x][1].local_name)
            for uid in utmp_keys:
                if uid in B2_:
                    lb_dual, ub_dual = utmp[uid]
                    if not lb_dual is None:
                        exp -= B2_[uid] * lb_dual
                    if not ub_dual is None:
                        exp += B2_[uid] * ub_dual
            if type(exp) in six.integer_types or type(exp) is float:
                # TODO: Annotate the model as unbounded
                raise IOError("Unbounded variable without side constraints")
            else:
                block.c1.add(exp == 0)
        #
        # Return block
        #
        return block
 def test_t4d(self):
     # x1 + 2*x2 == 1 - 3*x3  _|_  y + x3
     M = self._setup()
     M.cc = Complementarity(
         expr=complements(M.x1 + 2 * M.x2 == 1 - 3 * M.x3, M.y + M.x3))
     self._test("t4d", M)
Beispiel #52
0
# ex1b.py
import pyomo.environ as pyo
from pyomo.mpec import ComplementarityList, complements

n = 5

model = pyo.ConcreteModel()

model.x = pyo.Var(range(1, n + 1))

model.f = pyo.Objective(expr=sum(i * (model.x[i] - 1)**2
                                 for i in range(1, n + 1)))

model.compl = ComplementarityList()
model.compl.add(complements(model.x[1] >= 0, model.x[2] >= 0))
model.compl.add(complements(model.x[2] >= 0, model.x[3] >= 0))
model.compl.add(complements(model.x[3] >= 0, model.x[4] >= 0))
model.compl.add(complements(model.x[4] >= 0, model.x[5] >= 0))
Beispiel #53
0
 def test_list1(self):
     M = self._setup()
     M.cc = ComplementarityList()
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 0))
     M.cc.add(complements(M.y + M.x3, M.x1 + 2 * M.x2 == 2))
     self._test("list1", M)