コード例 #1
0
def create_master(model_data, k=1):
    """
    Create the upper-level (master) of the bilevel problem

    Arguments:
        model_data: An Egret dict of dict that stores data for the power system
        k: A positive integer indicating the number of relays that can be attacked

    Returns: Tuple with the following values:
        model: A Pyomo model representing the algebraic form of the bilevel problem
        md: The model_data object associated to the model
    """
    ### power system data
    md = model_data

    ### create dictionaries of object sets
    gens = dict(md.elements(element_type='generator'))
    buses = dict(md.elements(element_type='bus'))
    loads = dict(md.elements(element_type='load'))
    branches = dict(md.elements(element_type='branch'))

    ### create dictionaries across object attributes for an object of the same set type
    bus_attrs = md.attributes(element_type='bus')
    gen_attrs = md.attributes(element_type='generator')
    branch_attrs = md.attributes(element_type='branch')

    ### declare new Pyomo model
    model = pe.ConcreteModel()

    ### declare (and fix) the loads at the buses
    bus_p_loads, _ = tx_utils.dict_of_bus_loads(buses, loads)
    buses_with_loads = list(k for k in bus_p_loads.keys()
                            if bus_p_loads[k] != 0.)
    ### upper-level (attacker) variables
    decl.declare_var('load_shed',
                     model,
                     buses_with_loads,
                     initialize=0.0,
                     domain=pe.NonNegativeReals)
    decl.declare_var('delta_k', model, branch_attrs['names'],
                     domain=pe.Binary)  # line compromised
    decl.declare_var('delta_g', model, gen_attrs['names'],
                     domain=pe.Binary)  # gen compromised
    decl.declare_var('delta_b', model, bus_attrs['names'],
                     domain=pe.Binary)  # bus compromised
    decl.declare_var('u', model, buses_with_loads,
                     domain=pe.Binary)  # load available
    decl.declare_var('v', model, gen_attrs['names'],
                     domain=pe.Binary)  # generator available
    decl.declare_var('w', model, branch_attrs['names'],
                     domain=pe.Binary)  # line available

    ### upper-level constraints
    cons.declare_component_budget(model, k, branch_attrs['name'],\
        gen_attrs['name'], bus_attrs['names']) # note that all k are costed equally in current implementation
    cons.declare_load_compromised(model, relay_load_tuple)
    cons.declare_load_uncompromised(model, buses_with_loads, load_relays)
    cons.declare_branch_compromised(model, relay_branch_tuple)
    cons.declare_branch_uncompromised(model, branch_attrs['names'],
                                      branch_relays)
    cons.declare_gen_compromised(model, relay_gen_tuple)
    cons.declare_gen_uncompromised(model, gen_attrs['names'], gen_relays)

    ### upper-level objective for interdiction problem (opposite to lower-level objective)
    model.obj = pe.Objective(expr=sum(model.load_shed[l]
                                      for l in buses_with_loads),
                             sense=pe.maximize)

    return model, md
コード例 #2
0
def create_master(model_data, omega, k=1):
    """
    Create the upper-level (master) of the stochastic bilevel problem

    Arguments:
        model_data: An Egret dict of dict that stores data for the power system
        omega: A dict of scenario name <key> and probability per scenario <value>
        where the probabilities add to 1
        k: A positive integer indicating the number of relays that can be attacked

    Returns: Tuple with the following values:
        model: A Pyomo model representing the algebraic form of the bilevel problem
        md: The model_data object associated to the model
    """
    ### power system data
    md = model_data

    ### create dictionaries of object sets
    relays = dict(md.elements(element_type='relay'))
    gens = dict(md.elements(element_type='generator'))
    buses = dict(md.elements(element_type='bus'))
    loads = dict(md.elements(element_type='load'))
    branches = dict(md.elements(element_type='branch'))

    ### create dictionaries across object attributes for an object of the same set type
    relay_attrs = md.attributes(element_type='relay')
    gen_attrs = md.attributes(element_type='generator')
    branch_attrs = md.attributes(element_type='branch')

    ### declare new Pyomo model
    model = pe.ConcreteModel()

    ### scenarios
    scenarios = omega.keys()

    ### declare (and fix) the loads at the buses
    bus_p_loads, _ = tx_utils.dict_of_bus_loads(buses, loads)
    buses_with_loads = list(k for k in bus_p_loads.keys()
                            if bus_p_loads[k] != 0.)

    ### relay-to-power-device mappings
    relay_branches = utils.dict_of_relay_branches(relays, branches)
    branch_relays = utils.dict_of_branch_relays(relays, branches)
    relay_branch_tuple = utils.relay_branch_tuple(relay_branches)
    relay_gens = utils.dict_of_relay_gens(relays, gens)
    gen_relays = utils.dict_of_gen_relays(relays, gens)
    relay_gen_tuple = utils.relay_branch_tuple(relay_gens)
    relay_loads = utils.dict_of_relay_loads(relays, loads, buses_with_loads)
    load_relays = utils.dict_of_load_relays(relays, buses_with_loads)
    relay_load_tuple = utils.relay_branch_tuple(relay_loads)

    ### upper-level (attacker) variables
    scenarios_loads = pe.Set(initialize=scenarios) * pe.Set(
        initialize=buses_with_loads)
    decl.declare_var('load_shed',
                     model,
                     scenarios_loads,
                     initialize=0.0,
                     domain=pe.NonNegativeReals)
    decl.declare_var('delta',
                     model,
                     relay_attrs['names'],
                     domain=pe.Binary,
                     bounds=(0, 1))  # relays compromised
    decl.declare_var('u',
                     model,
                     buses_with_loads,
                     domain=pe.Binary,
                     bounds=(0, 1))  # load available
    decl.declare_var('v',
                     model,
                     gen_attrs['names'],
                     domain=pe.Binary,
                     bounds=(0, 1))  # generator available
    decl.declare_var('w',
                     model,
                     branch_attrs['names'],
                     domain=pe.Binary,
                     bounds=(0, 1))  # line available

    ### upper-level constraints
    cons.declare_budget(
        model, k,
        relays)  # note that all k are costed equally in current implementation
    cons.declare_load_compromised(model, relay_load_tuple)
    cons.declare_load_uncompromised(model, buses_with_loads, load_relays)
    cons.declare_branch_compromised(model, relay_branch_tuple)
    cons.declare_branch_uncompromised(model, branch_attrs['names'],
                                      branch_relays)
    cons.declare_gen_compromised(model, relay_gen_tuple)
    cons.declare_gen_uncompromised(model, gen_attrs['names'], gen_relays)

    ### upper-level objective for stochastic interdiction problem (opposite to lower-level objective)
    model.obj = pe.Objective(expr=sum(omega[p]['probability'] *
                                      model.load_shed[p, l]
                                      for (p, l) in scenarios_loads),
                             sense=pe.maximize)

    return model, md