示例#1
0
    def _generate_model(self):
        self.model = ConcreteModel()
        model = self.model
        model._name = self.description

        model.s = Set(initialize=[1,2])
        model.x = Var()
        model.y = Var()
        model.z = Var(bounds=(0,None))

        model.obj = Objective(model.s,
                              rule=inactive_index_LP_obj_rule)
        model.OBJ = Objective(expr=model.x+model.y)
        model.obj[1].deactivate()
        model.OBJ.deactivate()
        model.c1 = ConstraintList()
        model.c1.add(model.x<=1)   # index=1
        model.c1.add(model.x>=-1)  # index=2
        model.c1.add(model.y<=1)   # index=3
        model.c1.add(model.y>=-1)  # index=4
        model.c1[1].deactivate()
        model.c1[4].deactivate()
        model.c2 = Constraint(model.s,
                              rule=inactive_index_LP_c2_rule)

        model.b = Block()
        model.b.c = Constraint(expr=model.z >= 2)
        model.B = Block(model.s)
        model.B[1].c = Constraint(expr=model.z >= 3)
        model.B[2].c = Constraint(expr=model.z >= 1)

        model.b.deactivate()
        model.B.deactivate()
        model.B[2].activate()
示例#2
0
def EXTERNAL_initialize_for_admm(manager, scenario):
    if manager.get_option("verbose"):
        print("Initializing scenario %s for admm algorithm" % (scenario.name))
    admm_block = Block(concrete=True)
    assert not hasattr(scenario._instance, ".admm")
    scenario._instance.add_component(".admm", admm_block)

    # Augment the objective with lagrangian and penalty terms
    # and weight the original objective by the scenario probability.
    # The langrangian and penalty terms will be computed after
    # the parameters are created.
    user_cost_expression = scenario._instance_cost_expression
    admm_block.cost_expression = Expression(initialize=\
        scenario.probability * user_cost_expression)
    admm_block.lagrangian_expression = Expression(initialize=0.0)
    admm_block.penalty_expression = Expression(initialize=0.0)
    # these are used in the objective, they can be toggled
    # between the expression above or something else (e.g., 0.0)
    admm_block.cost_term = Expression(initialize=admm_block.cost_expression)
    admm_block.lagrangian_term = Expression(
        initialize=admm_block.lagrangian_expression)
    admm_block.penalty_term = Expression(
        initialize=admm_block.penalty_expression)
    objective_direction = 1
    if manager.objective_sense == maximize:
        objective_direction = -1
    scenario._instance_objective.expr = \
        admm_block.cost_term + \
        admm_block.lagrangian_term * objective_direction + \
        admm_block.penalty_term * objective_direction

    # add objective parameters to admm block
    for tree_node in scenario.node_list[:-1]:
        assert not tree_node.is_leaf_node()
        node_block = Block(concrete=True)
        admm_block.add_component(tree_node.name, node_block)
        node_block.node_index_set = Set(ordered=True,
                                        initialize=sorted(
                                            tree_node._standard_variable_ids))
        node_block.z = Param(node_block.node_index_set,
                             initialize=0.0,
                             mutable=True)
        node_block.y = Param(node_block.node_index_set,
                             initialize=0.0,
                             mutable=True)
        node_block.rho = Param(node_block.node_index_set,
                               initialize=0.0,
                               mutable=True)

        for id_ in node_block.node_index_set:
            varname, index = tree_node._variable_ids[id_]
            var = scenario._instance.find_component(varname)[index]
            admm_block.lagrangian_expression.expr += \
                node_block.y[id_] * (var - node_block.z[id_])
            admm_block.penalty_expression.expr += \
                (node_block.rho[id_] / 2.0) * (var - node_block.z[id_])**2

    # The objective has changed so flag this if necessary.
    if manager.preprocessor is not None:
        manager.preprocessor.objective_updated[scenario.name] = True
示例#3
0
 def test_nested_blocks(self):
     """Test with nested blocks."""
     m = ConcreteModel()
     m.b = Block()
     m.inactive_b = Block()
     m.inactive_b.deactivate()
     m.b.x = Var()
     m.b.x2 = Var(domain=Binary)
     m.b.x3 = Var(domain=Integers)
     m.inactive_b.x = Var()
     m.b.c = Constraint(expr=m.b.x == m.b.x2)
     m.inactive_b.c = Constraint(expr=m.b.x == 1)
     m.inactive_b.c2 = Constraint(expr=m.inactive_b.x == 15)
     model_size = build_model_size_report(m)
     self.assertEqual(model_size.activated.variables, 2)
     self.assertEqual(model_size.overall.variables, 4)
     self.assertEqual(model_size.activated.binary_variables, 1)
     self.assertEqual(model_size.overall.binary_variables, 1)
     self.assertEqual(model_size.activated.integer_variables, 0)
     self.assertEqual(model_size.overall.integer_variables, 1)
     self.assertEqual(model_size.activated.constraints, 1)
     self.assertEqual(model_size.overall.constraints, 3)
     self.assertEqual(model_size.activated.disjuncts, 0)
     self.assertEqual(model_size.overall.disjuncts, 0)
     self.assertEqual(model_size.activated.disjunctions, 0)
     self.assertEqual(model_size.overall.disjunctions, 0)
示例#4
0
def makeNetworkDisjunction(minimize=True):
    """ creates a GDP model with pyomo.network components """
    m = ConcreteModel()

    m.feed = feed = Block()
    m.wkbx = wkbx = Block()
    m.dest = dest = Block()

    m.orange = orange = Disjunct()
    m.blue = blue = Disjunct()

    m.orange_or_blue = Disjunction(expr=[orange,blue])

    blue.blue_box = blue_box = Block()

    feed.x = Var(bounds=(0,1))
    wkbx.x = Var(bounds=(0,1))
    dest.x = Var(bounds=(0,1))

    wkbx.inlet = ntwk.Port(initialize={"x":wkbx.x})
    wkbx.outlet = ntwk.Port(initialize={"x":wkbx.x})

    feed.outlet = ntwk.Port(initialize={"x":feed.x})
    dest.inlet = ntwk.Port(initialize={"x":dest.x})

    blue_box.x = Var(bounds=(0,1))
    blue_box.x_wkbx = Var(bounds=(0,1))
    blue_box.x_dest = Var(bounds=(0,1))


    blue_box.inlet_feed = ntwk.Port(initialize={"x":blue_box.x})
    blue_box.outlet_wkbx = ntwk.Port(initialize={"x":blue_box.x})

    blue_box.inlet_wkbx = ntwk.Port(initialize={"x":blue_box.x_wkbx})
    blue_box.outlet_dest = ntwk.Port(initialize={"x":blue_box.x_dest})

    blue_box.multiplier_constr = Constraint(expr=blue_box.x_dest == \
                                            2*blue_box.x_wkbx)

    # orange arcs
    orange.a1 = ntwk.Arc(source=feed.outlet, destination=wkbx.inlet)
    orange.a2 = ntwk.Arc(source=wkbx.outlet, destination=dest.inlet)

    # blue arcs
    blue.a1 = ntwk.Arc(source=feed.outlet, destination=blue_box.inlet_feed)
    blue.a2 = ntwk.Arc(source=blue_box.outlet_wkbx, destination=wkbx.inlet)
    blue.a3 = ntwk.Arc(source=wkbx.outlet, destination=blue_box.inlet_wkbx)
    blue.a4 = ntwk.Arc(source=blue_box.outlet_dest, destination=dest.inlet)

    # maximize/minimize "production"
    if minimize:
        m.obj = Objective(expr=m.dest.x)
    else:
        m.obj = Objective(expr=m.dest.x, sense=maximize)

    # create a completely fixed model
    feed.x.fix(0.42)

    return m
示例#5
0
 def test_getname_error(self):
     m = ConcreteModel()
     m.b = Block()
     m.b.v = Var()
     m.c = Block()
     self.assertRaises(RuntimeError,
                       m.b.v.getname,
                       fully_qualified=True,
                       relative_to=m.c)
示例#6
0
    def _add_transformation_block(self, instance):
        # make a transformation block on instance to put transformed disjuncts
        # on
        transBlockName = unique_component_name(instance,
                                               '_pyomo_gdp_bigm_relaxation')
        transBlock = Block()
        instance.add_component(transBlockName, transBlock)
        transBlock.relaxedDisjuncts = Block(NonNegativeIntegers)
        transBlock.lbub = Set(initialize=['lb', 'ub'])

        return transBlock
示例#7
0
 def disj_rule(d, flag):
     m = d.model()
     if flag:
         d.b = Block()
         d.b.c = Constraint(expr=m.x == 0)
         d.add_component('b.c', Constraint(expr=m.y >= 9))
         d.b.anotherblock = Block()
         d.b.anotherblock.c = Constraint(expr=m.y >= 11)
         d.bb = Block([1])
         d.bb[1].c = Constraint(expr=m.x == 0)
     else:
         d.c = Constraint(expr=m.x >= 80)
示例#8
0
def makeHierarchicalNested_DeclOrderMatchesInstantationOrder():
    """Here, we put the disjunctive components on Blocks, but we do it in the 
    same order that we declared the blocks, that is, on each block, decl order
    matches instantiation order."""
    m = ConcreteModel()
    m.I = RangeSet(1, 4)
    m.x = Var(m.I, bounds=(-2, 6))
    m.disjunct_block = Block()
    m.disjunction_block = Block()
    instantiate_hierarchical_nested_model(m)

    return m
示例#9
0
def makeHierarchicalNested_DeclOrderOppositeInstantationOrder():
    """Here, we declare the Blocks in the opposite order. This means that 
    decl order will be *opposite* instantiation order, which means that we 
    can break our targets preprocessing without even using targets if we 
    are not correctly identifying what is nested in what!"""
    m = ConcreteModel()
    m.I = RangeSet(1, 4)
    m.x = Var(m.I, bounds=(-2, 6))
    m.disjunction_block = Block()
    m.disjunct_block = Block()
    instantiate_hierarchical_nested_model(m)

    return m
示例#10
0
文件: models.py 项目: pazochoa/pyomo
def makeTwoTermDisj_IndexedConstraints():
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.a = Var(m.s)
    m.b = Block()

    def disj1_rule(disjunct):
        m = disjunct.model()

        def c_rule(d, s):
            return m.a[s] == 0

        disjunct.c = Constraint(m.s, rule=c_rule)

    m.b.simpledisj1 = Disjunct(rule=disj1_rule)

    def disj2_rule(disjunct):
        m = disjunct.model()

        def c_rule(d, s):
            return m.a[s] <= 3

        disjunct.c = Constraint(m.s, rule=c_rule)

    m.b.simpledisj2 = Disjunct(rule=disj2_rule)
    m.b.disjunction = Disjunction(expr=[m.b.simpledisj1, m.b.simpledisj2])
    return m
示例#11
0
    def _apply_to(self, instance, **kwds):
        # TODO: This data should be stored differently.  We cannot nest this transformation with itself
        if getattr(instance, 'bilinear_data_', None) is None:
            instance.bilinear_data_ = Block()
            instance.bilinear_data_.cache = {}
            instance.bilinear_data_.vlist = VarList()
            instance.bilinear_data_.vlist_boolean = []
            instance.bilinear_data_.IDX = Set()
            instance.bilinear_data_.disjuncts_ = Disjunct(
                instance.bilinear_data_.IDX * [0, 1])
            instance.bilinear_data_.disjunction_data = {}
            instance.bilinear_data_.o_expr = {}
            instance.bilinear_data_.c_body = {}
        #
        # Iterate over all blocks
        #
        for block in instance.block_data_objects(
                active=True, sort=SortComponents.deterministic):
            self._transformBlock(block, instance)
        #
        # WEH: I wish I had a DisjunctList and DisjunctionList object...
        #
        def rule(block, i):
            return instance.bilinear_data_.disjunction_data[i]

        instance.bilinear_data_.disjunction_ = Disjunction(
            instance.bilinear_data_.IDX, rule=rule)
示例#12
0
    def test_rules_with_None_in_set(self):
        def noarg_rule(b):
            b.args = ()
        def onearg_rule(b, i):
            b.args = (i,)
        def twoarg_rule(b, i, j):
            b.args = (i,j)
        m = ConcreteModel()
        m.b1 = Block(rule=noarg_rule)
        self.assertEqual(m.b1.args, ())

        m.b2 = Block([None], rule=onearg_rule)
        self.assertEqual(m.b2[None].args, (None,))

        m.b3 = Block([(None,1)], rule=twoarg_rule)
        self.assertEqual(m.b3[None,1].args, ((None,1)))
示例#13
0
文件: util.py 项目: dilr/pyomo
def reformulate_integer_variables(model, config):
    integer_vars = list(v for v in model.component_data_objects(
        ctype=Var, descend_into=(Block, Disjunct))
                        if v.is_integer() and not v.fixed)
    if len(integer_vars) == 0:
        return  # if no free integer variables, no reformulation needed.

    if config.reformulate_integer_vars_using is None:
        config.logger.warning(
            "Model contains unfixed integer variables. "
            "GDPopt will reformulate using base 2 binary variables "
            "by default. To specify a different method, see the "
            "reformulate_integer_vars_using configuration option.")
        config.reformulate_integer_vars_using = 'base2_binary'

    config.logger.info(
        "Reformulating integer variables using the %s strategy." %
        config.reformulate_integer_vars_using)

    # Set up reformulation block
    reform_block = model.GDPopt_utils.integer_reform = Block(
        doc="Holds variables and constraints for reformulating "
        "integer variables to binary variables.")
    reform_block.new_binary_var = Var(
        Any,
        domain=Binary,
        dense=False,
        doc="Binary variable with index (int_var.name, indx)")
    reform_block.integer_to_binary_constraint = Constraint(
        Any,
        doc="Equality constraints mapping the binary variable values "
        "to the integer variable value.")

    # check that variables are bounded and non-negative
    for int_var in integer_vars:
        if not (int_var.has_lb() and int_var.has_ub()):
            raise ValueError(
                "Integer variable %s is missing an "
                "upper or lower bound. LB: %s; UB: %s. "
                "GDPopt does not support unbounded integer variables." %
                (int_var.name, int_var.lb, int_var.ub))
        if int_var.lb < 0:
            raise ValueError("Integer variable %s can be negative. "
                             "GDPopt currently only supports positive integer "
                             "variables." % (int_var.name))
        # do the reformulation
        highest_power = floor(log(value(int_var.ub), 2))
        var_name = int_var.name
        reform_block.integer_to_binary_constraint.add(
            var_name,
            expr=int_var == sum(reform_block.new_binary_var[var_name, pwr] *
                                (2**pwr)
                                for pwr in range(0,
                                                 int(highest_power) + 1)))
        int_var.domain = NonNegativeReals

    config.logger.info("Reformulated %s integer variables using "
                       "%s binary variables and %s constraints." %
                       (len(integer_vars), len(reform_block.new_binary_var),
                        len(reform_block.integer_to_binary_constraint)))
示例#14
0
文件: util.py 项目: ZedongPeng/pyomo
def generate_norm_inf_objective_function(model, setpoint_model, discrete_only=False):
    """This function generates objective (PF-OA main problem) for minimum Norm Infinity distance to setpoint_model.

    Norm-Infinity distance of (x,y) = \max_i |x_i - y_i|.

    Args:
        model (Pyomo model): the model that needs new objective function.
        setpoint_model (Pyomo model): the model that provides the base point for us to calculate the distance.
        discrete_only (bool, optional): whether only optimize on distance between the discrete variables. Defaults to False.

    Returns:
        Objective: the norm infinity objective function
    """
    # skip objective_value variable and slack_var variables
    var_filter = (lambda v: v.is_integer()) if discrete_only \
        else (lambda v: v.name != 'MindtPy_utils.objective_value' and
              'MindtPy_utils.feas_opt.slack_var' not in v.name)
    model_vars = list(filter(var_filter, model.MindtPy_utils.variable_list))
    setpoint_vars = list(
        filter(var_filter, setpoint_model.MindtPy_utils.variable_list))
    assert len(model_vars) == len(
        setpoint_vars), 'Trying to generate Norm Infinity objective function for models with different number of variables'
    model.MindtPy_utils.del_component('L_infinity_obj')
    obj_blk = model.MindtPy_utils.L_infinity_obj = Block()
    obj_blk.L_infinity_obj_var = Var(domain=Reals, bounds=(0, None))
    obj_blk.abs_reform = ConstraintList()
    for v_model, v_setpoint in zip(model_vars,
                                   setpoint_vars):
        obj_blk.abs_reform.add(
            expr=v_model - v_setpoint.value >= -obj_blk.L_infinity_obj_var)
        obj_blk.abs_reform.add(
            expr=v_model - v_setpoint.value <= obj_blk.L_infinity_obj_var)

    return Objective(expr=obj_blk.L_infinity_obj_var)
示例#15
0
    def _generate_model(self):
        self.model = ConcreteModel()
        model = self.model
        model._name = self.description

        model.b = Block()
        model.B = Block([1,2,3])
        model.a = Param(initialize=1.0, mutable=True)
        model.b.x = Var(within=NonNegativeReals)
        model.B[1].x = Var(within=NonNegativeReals)

        model.obj = Objective(expr=model.b.x + 3.0*model.B[1].x)
        model.obj.deactivate()
        model.B[2].c = Constraint(expr=-model.B[1].x <= -model.a)
        model.B[2].obj = Objective(expr=model.b.x + 3.0*model.B[1].x + 2)
        model.B[3].c = Constraint(expr=2.0 <= model.b.x/model.a - model.B[1].x <= 10)
示例#16
0
def create_submodel_hp_block(instance):
    """
    Creates highpoint relaxation with the given specified model; does
    not include any submodel or block that is deactivated
    """
    block = Block(concrete=True)

    # get the objective for the master problem
    for c in instance.component_objects(Objective, descend_into=False):
        block.add_component(c.name, Reference(c))

    # get the variables of the model (if there are more submodels, then
    # extraneous variables may be added to the block)
    for c in instance.component_objects(Var,
                                        sort=True,
                                        descend_into=True,
                                        active=True):
        block.add_component(c.name, Reference(c))

    # get the constraints from the main model
    for c in instance.component_objects(Constraint,
                                        sort=True,
                                        descend_into=True,
                                        active=True):
        block.add_component(c.name, Reference(c))

    # deactivate the highpoint relaxation
    block.deactivate()

    return block
示例#17
0
def add_affine_cuts(nlp_result, solve_data, config):
    with time_code(solve_data.timing, "affine cut generation"):
        m = solve_data.linear_GDP
        if config.calc_disjunctive_bounds:
            with time_code(solve_data.timing, "disjunctive variable bounding"):
                TransformationFactory(
                    'contrib.compute_disj_var_bounds').apply_to(
                        m,
                        solver=config.mip_solver
                        if config.obbt_disjunctive_bounds else None)
        config.logger.info("Adding affine cuts.")
        GDPopt = m.GDPopt_utils
        counter = 0
        for var, val in zip(GDPopt.variable_list, nlp_result.var_values):
            if val is not None and not var.fixed:
                var.value = val

        for constr in constraints_in_True_disjuncts(m, config):
            # Note: this includes constraints that are deactivated in the current model (linear_GDP)

            disjunctive_var_bounds = disjunctive_bounds(constr.parent_block())

            if constr.body.polynomial_degree() in (1, 0):
                continue

            vars_in_constr = list(identify_variables(constr.body))
            if any(var.value is None for var in vars_in_constr):
                continue  # a variable has no values

            # mcpp stuff
            mc_eqn = mc(constr.body, disjunctive_var_bounds)
            # mc_eqn = mc(constr.body)
            ccSlope = mc_eqn.subcc()
            cvSlope = mc_eqn.subcv()
            ccStart = mc_eqn.concave()
            cvStart = mc_eqn.convex()
            ub_int = min(
                constr.upper,
                mc_eqn.upper()) if constr.has_ub() else mc_eqn.upper()
            lb_int = max(
                constr.lower,
                mc_eqn.lower()) if constr.has_lb() else mc_eqn.lower()

            parent_block = constr.parent_block()
            # Create a block on which to put outer approximation cuts.
            aff_utils = parent_block.component('GDPopt_aff')
            if aff_utils is None:
                aff_utils = parent_block.GDPopt_aff = Block(
                    doc="Block holding affine constraints")
                aff_utils.GDPopt_aff_cons = ConstraintList()
            aff_cuts = aff_utils.GDPopt_aff_cons
            concave_cut = sum(ccSlope[var] * (var - var.value)
                              for var in vars_in_constr) + ccStart >= lb_int
            convex_cut = sum(cvSlope[var] * (var - var.value)
                             for var in vars_in_constr) + cvStart <= ub_int
            aff_cuts.add(expr=concave_cut)
            aff_cuts.add(expr=convex_cut)
            counter += 2

        config.logger.info("Added %s affine cuts" % counter)
示例#18
0
def _process_container(blk, config):
    if not hasattr(blk, '_induced_linearity_info'):
        blk._induced_linearity_info = Block()
    else:
        assert blk._induced_linearity_info.ctype == Block
    eff_discr_vars = detect_effectively_discrete_vars(
        blk, config.equality_tolerance)
    # TODO will need to go through this for each disjunct, since it does
    # not (should not) descend into Disjuncts.

    # Determine the valid values for the effectively discrete variables
    possible_var_values = determine_valid_values(blk, eff_discr_vars, config)

    # Collect find bilinear expressions that can be reformulated using
    # knowledge of effectively discrete variables
    bilinear_map = _bilinear_expressions(blk)

    # Relevant constraints are those with bilinear terms that involve
    # effectively_discrete_vars
    processed_pairs = ComponentSet()
    for v1, var_values in possible_var_values.items():
        v1_pairs = bilinear_map.get(v1, ())
        for v2, bilinear_constrs in v1_pairs.items():
            if (v1, v2) in processed_pairs:
                continue
            _process_bilinear_constraints(blk, v1, v2, var_values,
                                          bilinear_constrs)
            processed_pairs.add((v2, v1))
示例#19
0
def makeTwoTermDisj_IndexedConstraints():
    """Single two-term disjunction with IndexedConstraints on both disjuncts.  
    Does not bound the variables, so cannot be transformed by hull at all and 
    requires specifying m values in bigm.
    """
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.a = Var(m.s)
    m.b = Block()

    def disj1_rule(disjunct):
        m = disjunct.model()

        def c_rule(d, s):
            return m.a[s] == 0

        disjunct.c = Constraint(m.s, rule=c_rule)

    m.b.simpledisj1 = Disjunct(rule=disj1_rule)

    def disj2_rule(disjunct):
        m = disjunct.model()

        def c_rule(d, s):
            return m.a[s] <= 3

        disjunct.c = Constraint(m.s, rule=c_rule)

    m.b.simpledisj2 = Disjunct(rule=disj2_rule)
    m.b.disjunction = Disjunction(expr=[m.b.simpledisj1, m.b.simpledisj2])
    return m
示例#20
0
    def test_gdp_tree(self):
        m = ConcreteModel()
        m.x = Var()
        m.block = Block()
        m.block.d1 = Disjunct()
        m.block.d1.dd1 = Disjunct()
        m.disj1 = Disjunct()
        m.block.disjunction = Disjunction(expr=[m.block.d1, m.disj1])
        m.block.d1.b = Block()
        m.block.d1.b.dd2 = Disjunct()
        m.block.d1.b.dd3 = Disjunct()
        m.block.d1.disjunction = Disjunction(
            expr=[m.block.d1.dd1, m.block.d1.b.dd2, m.block.d1.b.dd3])
        m.block.d1.b.dd2.disjunction = Disjunction(
            expr=[[m.x >= 1], [m.x <= -1]])
        targets = (m, )
        knownBlocks = {}
        tree = get_gdp_tree(targets, m, knownBlocks)

        # check tree structure first
        vertices = tree.vertices
        self.assertEqual(len(vertices), 10)
        in_degrees = {
            m.block.d1: 1,
            m.block.disjunction: 0,
            m.disj1: 1,
            m.block.d1.disjunction: 1,
            m.block.d1.dd1: 1,
            m.block.d1.b.dd2: 1,
            m.block.d1.b.dd3: 1,
            m.block.d1.b.dd2.disjunction: 1,
            m.block.d1.b.dd2.disjunction.disjuncts[0]: 1,
            m.block.d1.b.dd2.disjunction.disjuncts[1]: 1
        }
        for key, val in in_degrees.items():
            self.assertEqual(tree.in_degree(key), val)

        # This should be deterministic, so we can just check the order
        topo_sort = [
            m.block.disjunction, m.disj1, m.block.d1, m.block.d1.disjunction,
            m.block.d1.b.dd3, m.block.d1.b.dd2, m.block.d1.b.dd2.disjunction,
            m.block.d1.b.dd2.disjunction.disjuncts[1],
            m.block.d1.b.dd2.disjunction.disjuncts[0], m.block.d1.dd1
        ]
        sort = tree.topological_sort()
        for i, node in enumerate(sort):
            self.assertIs(node, topo_sort[i])
示例#21
0
 def _add_relaxation_block(self, instance, name):
     # creates transformation block with a unique name based on name, adds it
     # to instance, and returns it.
     transBlockName = unique_component_name(
         instance, '_pyomo_gdp_cuttingplane_relaxation')
     transBlock = Block()
     instance.add_component(transBlockName, transBlock)
     return transBlockName, transBlock
示例#22
0
 def test_active_parent_block(self):
     m = ConcreteModel()
     m.d1 = Block()
     m.d1.sub1 = Disjunct()
     m.d1.sub2 = Disjunct()
     m.d1.disj = Disjunction(expr=[m.d1.sub1, m.d1.sub2])
     with self.assertRaises(GDP_Error):
         TransformationFactory('gdp.reclassify').apply_to(m)
示例#23
0
 def _transfer_var_references(self, fromBlock, toBlock):
     disjunctList = toBlock.relaxedDisjuncts
     for idx, disjunctBlock in iteritems(fromBlock.relaxedDisjuncts):
         # move all the of the local var references
         newblock = disjunctList[len(disjunctList)]
         newblock.localVarReferences = Block()
         newblock.localVarReferences.transfer_attributes_from(
             disjunctBlock.localVarReferences)
    def make_tiny_model_where_bounds_matter(self):
        m = ConcreteModel()
        m.b = Block()
        m.x = Var(bounds=(0, 15))
        m.y = Var(bounds=(3, 5))
        m.b.c = Constraint(expr=m.x + m.y <= 8)

        return m
示例#25
0
def piecewise_nd(tri: qhull.Delaunay,
                 values: List[float],
                 input: List[SimpleVar] = None,
                 output: SimpleVar = None,
                 bound: str = 'eq',
                 repn: str = 'cc', parent=None, **kw):
    """
    添加多维线性插值,values 必须是float类型的浮点数,不能是np的
    tri (scipy.spatial.Delaunay): A triangulation over
            the discretized variable domain. Can be
            generated using a list of variables using the
            utility function :func:`util.generate_delaunay`.
            Required attributes:
              - points: An (npoints, D) shaped array listing
                the D-dimensional coordinates of the
                discretization points.
              - simplices: An (nsimplices, D+1) shaped array
                of integers specifying the D+1 indices of
                the points vector that define each simplex
                of the triangulation.
    values (numpy.array): An (npoints,) shaped array of
        the values of the piecewise function at each of
        coordinates in the triangulation points array.
    input: A D-length list of variables or expressions
        bound as the inputs of the piecewise function.
    output: The variable constrained to be the output of
        the piecewise linear function.
    bound (str): The type of bound to impose on the
        output expression. Can be one of:
              - 'lb': y <= f(x)
              - 'eq': y  = f(x)
              - 'ub': y >= f(x)
    repn (str): The type of piecewise representation to
        use. Can be one of:
            - 'cc': convex combination

    """
    if repn == "cc":
        pf = cc
    elif repn == "dlog":
        pf = dlog
    elif repn == "log":
        pf = log
    elif repn == "log_lp":
        pf = log_lp
    else:
        raise RuntimeError(f'{repn} 不支持!')

    _f = partial(pf, tri=tri, values=values, input=input, output=output, bound=bound, **kw)

    if parent is None:
        # raise RuntimeError("parent 不能为空,必须提前声明好,否则无法添加到model中")
        m = Block(rule=_f)
    else:
        m = parent
        _f(m)
    return m
示例#26
0
    def _transform_disjunct(self, obj, transBlock, bigM, arg_list, suffix_list):
        # deactivated -> either we've already transformed or user deactivated
        if not obj.active:
            if obj.indicator_var.is_fixed():
                if value(obj.indicator_var) == 0:
                    # The user cleanly deactivated the disjunct: there
                    # is nothing for us to do here.
                    return
                else:
                    raise GDP_Error(
                        "The disjunct '%s' is deactivated, but the "
                        "indicator_var is fixed to %s. This makes no sense."
                        % ( obj.name, value(obj.indicator_var) ))
            if obj._transformation_block is None:
                raise GDP_Error(
                    "The disjunct '%s' is deactivated, but the "
                    "indicator_var is not fixed and the disjunct does not "
                    "appear to have been relaxed. This makes no sense. "
                    "(If the intent is to deactivate the disjunct, fix its "
                    "indicator_var to 0.)"
                    % ( obj.name, ))

        if obj._transformation_block is not None:
            # we've transformed it, which means this is the second time it's
            # appearing in a Disjunction
            raise GDP_Error(
                    "The disjunct '%s' has been transformed, but a disjunction "
                    "it appears in has not. Putting the same disjunct in "
                    "multiple disjunctions is not supported." % obj.name)

        # add reference to original disjunct on transformation block
        relaxedDisjuncts = transBlock.relaxedDisjuncts
        relaxationBlock = relaxedDisjuncts[len(relaxedDisjuncts)]
        # we will keep a map of constraints (hashable, ha!) to a tuple to
        # indicate where their m value came from, either (arg dict, key) if it
        # came from args, (Suffix, key) if it came from Suffixes, or (M_lower,
        # M_upper) if we calcualted it ourselves. I am keeping it here because I
        # want it to move with the disjunct transformation blocks in the case of
        # nested constraints, to make it easier to query.
        relaxationBlock.bigm_src = {}
        relaxationBlock.localVarReferences = Block()
        obj._transformation_block = weakref_ref(relaxationBlock)
        relaxationBlock._srcDisjunct = weakref_ref(obj)

        # This is crazy, but if the disjunction has been previously
        # relaxed, the disjunct *could* be deactivated.  This is a big
        # deal for Hull, as it uses the component_objects /
        # component_data_objects generators.  For BigM, that is OK,
        # because we never use those generators with active=True.  I am
        # only noting it here for the future when someone (me?) is
        # comparing the two relaxations.
        #
        # Transform each component within this disjunct
        self._transform_block_components(obj, obj, bigM, arg_list, suffix_list)

        # deactivate disjunct to keep the writers happy
        obj._deactivate_without_fixing_indicator()
示例#27
0
 def test_is_child_of(self):
     m = ConcreteModel()
     m.b = Block()
     m.b.b_indexed = Block([1,2])
     m.b_parallel = Block()
     
     knownBlocks = {}
     self.assertFalse(is_child_of(parent=m.b, child=m.b_parallel,
                                  knownBlocks=knownBlocks))
     self.assertEqual(len(knownBlocks), 2)
     self.assertFalse(knownBlocks.get(m))
     self.assertFalse(knownBlocks.get(m.b_parallel))
     self.assertTrue(is_child_of(parent=m.b, child=m.b.b_indexed[1],
                                 knownBlocks=knownBlocks))
     self.assertEqual(len(knownBlocks), 4)
     self.assertFalse(knownBlocks.get(m))
     self.assertFalse(knownBlocks.get(m.b_parallel))
     self.assertTrue(knownBlocks.get(m.b.b_indexed[1]))
     self.assertTrue(knownBlocks.get(m.b.b_indexed))
示例#28
0
 def _get_block_model(self):
     model = ConcreteModel()
     model.s = Set(initialize=[1, 2])
     b = Block(concrete=True)
     b.s = Set(initialize=[1, 2])
     b.x = Var()
     b.X = Var(model.s)
     model.b1 = b.clone()
     model.b2 = b.clone()
     model.b3 = b.clone()
     model.b4 = b.clone()
     model.B1 = Block(model.s, rule=lambda _, i: b.clone())
     model.B2 = Block(model.s, rule=lambda _, i: b.clone())
     model.B3 = Block(model.s, rule=lambda _, i: b.clone())
     model.B4 = Block(model.s, rule=lambda _, i: b.clone())
     model.FirstStageCost = Expression(expr=0.0)
     model.SecondStageCost = Expression(expr=0.0)
     model.obj = Objective(expr=0.0)
     return model
示例#29
0
    def _create_transformation_block(self, context):
        new_xfrm_block_name = unique_component_name(context, 'logic_to_linear')
        new_xfrm_block = Block(doc="Transformation objects for logic_to_linear")
        setattr(context, new_xfrm_block_name, new_xfrm_block)

        new_xfrm_block.transformed_constraints = ConstraintList()
        new_xfrm_block.augmented_vars = BooleanVarList()
        new_xfrm_block.augmented_vars_asbinary = VarList( domain=Binary)

        return new_xfrm_block
示例#30
0
    def _add_transformation_block(self, instance):
        # make a transformation block on instance where we will store
        # transformed components
        transBlockName = unique_component_name(
            instance, '_pyomo_gdp_hull_reformulation')
        transBlock = Block()
        instance.add_component(transBlockName, transBlock)
        transBlock.relaxedDisjuncts = Block(NonNegativeIntegers)
        transBlock.lbub = Set(initialize=['lb', 'ub', 'eq'])
        # We will store all of the disaggregation constraints for any
        # Disjunctions we transform onto this block here.
        transBlock.disaggregationConstraints = Constraint(
            NonNegativeIntegers, Any)

        # This will map from srcVar to a map of srcDisjunction to the
        # disaggregation constraint corresponding to srcDisjunction
        transBlock._disaggregationConstraintMap = ComponentMap()

        return transBlock