示例#1
0
    def is_bounded(self, config):
        """
        Return True if the uncertainty set is bounded, else False.
        """
        # === Determine bounds on all uncertain params
        bounding_model = ConcreteModel()
        bounding_model.util = Block() # So that boundedness checks work for Cardinality and FactorModel sets
        bounding_model.uncertain_param_vars = IndexedVar(range(len(config.uncertain_params)), initialize=1)
        for idx, param in enumerate(config.uncertain_params):
            bounding_model.uncertain_param_vars[idx].value = param.value

        bounding_model.add_component("uncertainty_set_constraint",
                                     config.uncertainty_set.set_as_constraint(
                                         uncertain_params=bounding_model.uncertain_param_vars,
                                         model=bounding_model,
                                         config=config
                                     ))

        for idx, param in enumerate(list(bounding_model.uncertain_param_vars.values())):
            bounding_model.add_component("lb_obj_" + str(idx), Objective(expr=param, sense=minimize))
            bounding_model.add_component("ub_obj_" + str(idx), Objective(expr=param, sense=maximize))

        for o in bounding_model.component_data_objects(Objective):
            o.deactivate()

        for i in range(len(bounding_model.uncertain_param_vars)):
            for limit in ("lb", "ub"):
                getattr(bounding_model, limit + "_obj_" + str(i)).activate()
                res = config.global_solver.solve(bounding_model, tee=False)
                getattr(bounding_model, limit + "_obj_" + str(i)).deactivate()
                if not check_optimal_termination(res):
                    return False
        return True
示例#2
0
 def __init__(self, pyomo_model):
     """Constructor"""
     args = (Set(),)
     kwargs = {}
     self.pyomo_model = pyomo_model
     Objective.__init__(self, *args, **kwargs)
     #self._data = ObjectiveDataSequence( poek_model )
     self._data = []
示例#3
0
文件: util.py 项目: DLWoodruff/pyomo
def add_bounds_for_uncertain_parameters(model, config):
    '''
    This function solves a set of optimization problems to determine bounds on the uncertain parameters
    given the uncertainty set description. These bounds will be added as additional constraints to the uncertainty_set_constr
    constraint. Should only be called once set_as_constraint() has been called on the separation_model object.
    :param separation_model: the model on which to add the bounds
    :param config: solver config
    :return:
    '''
    # === Determine bounds on all uncertain params
    uncertain_param_bounds = []
    bounding_model = ConcreteModel()
    bounding_model.util = Block()
    bounding_model.util.uncertain_param_vars = IndexedVar(
        model.util.uncertain_param_vars.index_set())
    for tup in model.util.uncertain_param_vars.items():
        bounding_model.util.uncertain_param_vars[tup[0]].value = tup[1].value

    bounding_model.add_component(
        "uncertainty_set_constraint",
        config.uncertainty_set.set_as_constraint(
            uncertain_params=bounding_model.util.uncertain_param_vars,
            model=bounding_model,
            config=config))

    for idx, param in enumerate(
            list(bounding_model.util.uncertain_param_vars.values())):
        bounding_model.add_component("lb_obj_" + str(idx),
                                     Objective(expr=param, sense=minimize))
        bounding_model.add_component("ub_obj_" + str(idx),
                                     Objective(expr=param, sense=maximize))

    for o in bounding_model.component_data_objects(Objective):
        o.deactivate()

    for i in range(len(bounding_model.util.uncertain_param_vars)):
        bounds = []
        for limit in ("lb", "ub"):
            getattr(bounding_model, limit + "_obj_" + str(i)).activate()
            res = config.global_solver.solve(bounding_model, tee=False)
            bounds.append(bounding_model.util.uncertain_param_vars[i].value)
            getattr(bounding_model, limit + "_obj_" + str(i)).deactivate()
        uncertain_param_bounds.append(bounds)

    # === Add bounds as constraints to uncertainty_set_constraint ConstraintList
    for idx, bound in enumerate(uncertain_param_bounds):
        model.util.uncertain_param_vars[idx].setlb(bound[0])
        model.util.uncertain_param_vars[idx].setub(bound[1])

    return
示例#4
0
def make_model_2():
    m = ConcreteModel()
    m.x = Var(initialize=0.1, bounds=(0, 1))
    m.y = Var(initialize=0.1, bounds=(0, 1))
    m.obj = Objective(expr=-m.x**2 - m.y**2)
    m.c = Constraint(expr=m.y <= pe.exp(-m.x))
    return m
示例#5
0
    def is_empty_intersection(self, uncertain_params, nlp_solver):
        """
        Determine if intersection is empty

        Args:
            uncertain_params: list of uncertain parameters
            nlp_solver: a Pyomo Solver object for solving NLPs
        """

        # === Non-emptiness check for the set intersection
        is_empty_intersection = True
        if any(a_set.type == "discrete" for a_set in self.all_sets):
            disc_sets = (a_set for a_set in self.all_sets if a_set.type == "discrete")
            disc_set = min(disc_sets, key=lambda x: len(x.scenarios))  # minimum set of scenarios
            # === Ensure there is at least one scenario from this discrete set which is a member of all other sets
            for scenario in disc_set.scenarios:
                if all(a_set.point_in_set(point=scenario) for a_set in self.all_sets):
                    is_empty_intersection = False
                    break
        else:
            # === Compile constraints and solve NLP
            m = ConcreteModel()
            m.obj = Objective(expr=0) # dummy objective required if using baron
            m.param_vars = Var(uncertain_params.index_set())
            for a_set in self.all_sets:
                m.add_component(a_set.type + "_constraints", a_set.set_as_constraint(uncertain_params=m.param_vars))
            try:
                res = nlp_solver.solve(m)
            except:
                raise ValueError("Solver terminated with an error while checking set intersection non-emptiness.")
            if check_optimal_termination(res):
                is_empty_intersection = False
        return is_empty_intersection
示例#6
0
def build_Block_with_objects():
    """Build an empty Block"""
    obj = Block(concrete=True)
    obj.construct()
    obj.x = Var()
    obj.x._domain = None
    obj.c = Constraint()
    obj.o = Objective()
    return obj
示例#7
0
def build_BlockData_with_objects():
    """Build an empty _BlockData"""
    obj = _BlockData(build_BlockData_with_objects.owner)
    obj.x = Var()
    obj.x._domain = None
    obj.c = Constraint()
    obj.o = Objective()
    obj._component = None
    return obj
示例#8
0
def make_model_tri(n, small_val=1e-7, big_val=1e2):
    m = ConcreteModel()
    m.x = Var(range(n), initialize=0.5)

    def c_rule(m, i):
        return big_val*m.x[i-1] + small_val*m.x[i] + big_val*m.x[i+1] == 1
    
    m.c = Constraint(range(1,n-1), rule=c_rule)

    m.obj = Objective(expr=small_val*sum((m.x[i]-1)**2 for i in range(n)))

    return m
示例#9
0
def make_model():
    m = ConcreteModel()
    m.x = Var([1,2,3], initialize=0)
    m.f = Var([1,2,3], initialize=0)
    m.F = Var(initialize=0)
    m.f[1].fix(1)
    m.f[2].fix(2)

    m.sum_con = Constraint(expr= 
            (1 == m.x[1] + m.x[2] + m.x[3]))
    def bilin_rule(m, i):
        return m.F*m.x[i] == m.f[i]
    m.bilin_con = Constraint([1,2,3], rule=bilin_rule)

    m.obj = Objective(expr=m.F**2)

    return m
示例#10
0
    def make_noisy(self, cov_dict, conf_level=2):
        self.d1.name = "Noisy plant (d1)"
        k = 0
        for x in self.states:
            s = getattr(self.d1, x)  #: state
            xicc = getattr(self.d1, x + "_icc")
            xicc.deactivate()
            for j in self.state_vars[x]:
                self.xp_l.append(s[(1, 0) + j])
                self.xp_key[(x, j)] = k
                k += 1

        self.d1.xS_pnoisy = Set(initialize=[
            i for i in range(0, len(self.xp_l))
        ])  #: Create set of noisy_states
        self.d1.w_pnoisy = Var(self.d1.xS_pnoisy,
                               initialize=0.0)  #: Model disturbance
        self.d1.Q_pnoisy = Param(self.d1.xS_pnoisy, initialize=1, mutable=True)
        self.d1.obj_fun_noisy = Objective(
            sense=maximize,
            expr=0.5 * sum(self.d1.Q_pnoisy[k] * self.d1.w_pnoisy[k]**2
                           for k in self.d1.xS_pnoisy))
        self.d1.ics_noisy = ConstraintList()

        k = 0
        for x in self.states:
            s = getattr(self.d1, x)  #: state
            xic = getattr(self.d1, x + "_ic")
            for j in self.state_vars[x]:
                expr = s[(1, 1) + j] == xic[j] + self.d1.w_pnoisy[k]
                self.d1.ics_noisy.add(expr)
                k += 1

        for key in cov_dict:
            vni = key
            v_i = self.xp_key[vni]
            self.d1.Q_pnoisy[v_i].value = cov_dict[vni]
            self.d1.w_pnoisy[v_i].setlb(-conf_level * cov_dict[vni])
            self.d1.w_pnoisy[v_i].setub(conf_level * cov_dict[vni])

        with open("debug.txt", "w") as f:
            self.d1.Q_pnoisy.display(ostream=f)
            self.d1.obj_fun_noisy.pprint(ostream=f)
            self.d1.ics_noisy.pprint(ostream=f)
            self.d1.w_pnoisy.display(ostream=f)
示例#11
0
文件: util.py 项目: DLWoodruff/pyomo
def model_is_valid(model):
    '''
    Possibilities:
    Deterministic model has a single objective
    Deterministic model has no objective
    Deterministic model has multiple objectives
    :param model: the deterministic model
    :return: True if it satisfies certain properties, else False.
    '''
    objectives = list(model.component_data_objects(Objective))
    for o in objectives:
        o.deactivate()
    if len(objectives) == 1:
        '''
        Ensure objective is a minimization. If not, change the sense.
        '''
        obj = objectives[0]

        if obj.sense is not minimize:
            sympy_obj = sympyify_expression(-obj.expr)
            # Use sympy to distribute the negation so the method for determining first/second stage costs is valid
            min_obj = Objective(expr=sympy2pyomo_expression(
                sympy_obj[1].simplify(), sympy_obj[0]))
            model.del_component(obj)
            model.add_component(
                unique_component_name(model, obj.name + '_min'), min_obj)
        return True

    elif len(objectives) > 1:
        '''
        User should deactivate all Objectives in the model except the one represented by the output of 
        first_stage_objective + second_stage_objective
        '''
        return False
    else:
        '''
        No Objective objects provided as part of the model, please provide an Objective to your model so that
        PyROS can infer first- and second-stage objective.
        '''
        return False
示例#12
0
def solveropfnlp_2(ppc, solver="ipopt"):
    if solver == "ipopt":
        opt = SolverFactory("ipopt", executable="/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/ipopt-linux64/ipopt")
    if solver == "bonmin":
        opt = SolverFactory("bonmin", executable="/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/bonmin-linux64/bonmin")
    if solver == "knitro":
        opt = SolverFactory("knitro", executable="D:/ICT/Artelys/Knitro 10.2.1/knitroampl/knitroampl")

    ppc = ext2int(ppc)      # convert to continuous indexing starting from 0

    # Gather information about the system
    # =============================================================
    baseMVA, bus, gen, branch = \
        ppc["baseMVA"], ppc["bus"], ppc["gen"], ppc["branch"]

    nb = bus.shape[0]       # number of buses
    ng = gen.shape[0]       # number of generators
    nl = branch.shape[0]    # number of lines

    # generator buses
    gb = tolist(np.array(gen[:, GEN_BUS]).astype(int))

    sb = find((bus[:, BUS_TYPE] == REF))    # slack bus index
    fr = branch[:, F_BUS].astype(int)       # from bus indices
    to = branch[:, T_BUS].astype(int)       # to bus indices

    tr = branch[:, TAP]     # transformation ratios
    tr[find(tr == 0)] = 1   # set to 1 transformation ratios that are 0

    r = branch[:, BR_R]     # branch resistances
    x = branch[:, BR_X]     # branch reactances
    b = branch[:, BR_B]     # branch susceptances

    start_time = time.clock()

    # Admittance matrix computation
    # =============================================================
    y = makeYbus(baseMVA, bus, branch)[0]   # admittance matrix

    yk = 1./(r+x*1j)                        # branch admittance
    yft = yk + 0.5j*b                       # branch admittance + susceptance
    gk = yk.real                            # branch resistance
    yk = yk/tr                              # include /tr in yk

    # Optimization
    # =============================================================
    branch[find(branch[:, RATE_A] == 0), RATE_A] = 9999     # set undefined Sflow limit to 9999
    Smax = branch[:, RATE_A] / baseMVA                      # Max. Sflow

    # Power demand parameters
    Pd = bus[:, PD] / baseMVA
    Qd = bus[:, QD] / baseMVA

    # Max and min Pg and Qg
    Pg_max = zeros(nb)
    Pg_max[gb] = gen[:, PMAX] / baseMVA
    Pg_min = zeros(nb)
    Pg_min[gb] = gen[:, PMIN] / baseMVA
    Qg_max = zeros(nb)
    Qg_max[gb] = gen[:, QMAX] / baseMVA
    Qg_min = zeros(nb)
    Qg_min[gb] = gen[:, QMIN] / baseMVA

    # Vmax and Vmin vectors
    Vmax = bus[:, VMAX]
    Vmin = bus[:, VMIN]

    vm = bus[:, VM]
    va = bus[:, VA]*pi/180

    # create a new optimization model
    model = ConcreteModel()

    # Define sets
    # ------------
    model.bus = Set(ordered=True, initialize=range(nb))     # Set of all buses
    model.gen = Set(ordered=True, initialize=gb)                # Set of buses with generation
    model.line = Set(ordered=True, initialize=range(nl))    # Set of all lines

    # Define variables
    # -----------------
    # Voltage magnitudes vector (vm)
    model.vm = Var(model.bus)

    # Voltage angles vector (va)
    model.va = Var(model.bus)

    # Reactive power generation, synchronous machines(SM) (Qg)
    model.Qg = Var(model.gen)
    Qg0 = zeros(nb)
    Qg0[gb] = gen[:, QG]/baseMVA

    # Active power generation, synchronous machines(SM) (Pg)
    model.Pg = Var(model.gen)
    Pg0 = zeros(nb)
    Pg0[gb] = gen[:, PG] / baseMVA

    # Active and reactive power from at all branches
    model.Pf = Var(model.line)
    model.Qf = Var(model.line)

    # Active and reactive power to at all branches
    model.Pt = Var(model.line)
    model.Qt = Var(model.line)

    # Warm start the problem
    # ------------------------
    for i in range(nb):
        model.vm[i] = vm[i]
        model.va[i] = va[i]
        if i in gb:
            model.Pg[i] = Pg0[i]
            model.Qg[i] = Qg0[i]
    for i in range(nl):
        model.Pf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.cos(-ang(yft[i])) -\
                      vm[fr[i]] * vm[to[i]] * abs(yk[i]) * np.cos(va[fr[i]] - va[to[i]] - ang(yk[i]))
        model.Qf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.sin(-ang(yft[i])) -\
                      vm[fr[i]] * vm[to[i]] * abs(yk[i]) * np.sin(va[fr[i]] - va[to[i]] - ang(yk[i]))
        model.Pt[i] = vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) -\
                      vm[to[i]] * vm[fr[i]] * abs(yk[i]) * np.cos(va[to[i]] - va[fr[i]] - ang(yk[i]))
        model.Qt[i] = vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) -\
                      vm[to[i]] * vm[fr[i]] * abs(yk[i]) * np.sin(va[to[i]] - va[fr[i]] - ang(yk[i]))

    # Define constraints
    # ----------------------------

    # Equalities:
    # ------------

    # Active power flow equalities
    def powerflowact(model, i):
        if i in gb:
            return model.Pg[i]-Pd[i] == sum(model.vm[i]*model.vm[j]*abs(y[i, j]) *
                                            cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb))
        else:
            return sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * cos(model.va[i] - model.va[j] -
                                                                  ang(y[i, j])) for j in range(nb)) == -Pd[i]

    model.const1 = Constraint(model.bus, rule=powerflowact)

    # Reactive power flow equalities
    def powerflowreact(model, i):
        if i in gb:
            return model.Qg[i]-Qd[i] == sum(model.vm[i]*model.vm[j]*abs(y[i, j]) *
                                            sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb))
        else:
            return sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * sin(model.va[i] - model.va[j] -
                                                                  ang(y[i, j])) for j in range(nb)) == -Qd[i]

    model.const2 = Constraint(model.bus, rule=powerflowreact)

    # Active power from
    def pfrom(model, i):
        return model.Pf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.cos(-ang(yft[i])) - \
                              model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) * \
                              cos(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))

    model.const3 = Constraint(model.line, rule=pfrom)

    # Reactive power from
    def qfrom(model, i):
        return model.Qf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.sin(-ang(yft[i])) - \
                              model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) * \
                              sin(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))

    model.const4 = Constraint(model.line, rule=qfrom)

    # Active power to
    def pto(model, i):
        return model.Pt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) - \
                              model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) * \
                              cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))

    model.const5 = Constraint(model.line, rule=pto)

    # Reactive power to
    def qto(model, i):
        return model.Qt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) - \
                              model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) * \
                              sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))

    model.const6 = Constraint(model.line, rule=qto)

    # Slack bus phase angle
    model.const7 = Constraint(expr=model.va[sb[0]] == 0)

    # Inequalities:
    # ----------------

    # Active power generator limits Pg_min <= Pg <= Pg_max
    def genplimits(model, i):
        return Pg_min[i] <= model.Pg[i] <= Pg_max[i]

    model.const8 = Constraint(model.gen, rule=genplimits)

    # Reactive power generator limits Qg_min <= Qg <= Qg_max
    def genqlimits(model, i):
        return Qg_min[i] <= model.Qg[i] <= Qg_max[i]

    model.const9 = Constraint(model.gen, rule=genqlimits)

    # Voltage constraints ( Vmin <= V <= Vmax )
    def vlimits(model, i):
        return Vmin[i] <= model.vm[i] <= Vmax[i]

    model.const10 = Constraint(model.bus, rule=vlimits)

    # Sfrom line limit
    def sfrommax(model, i):
        return model.Pf[i]**2 + model.Qf[i]**2 <= Smax[i]**2

    model.const11 = Constraint(model.line, rule=sfrommax)

    # Sto line limit
    def stomax(model, i):
        return model.Pt[i]**2 + model.Qt[i]**2 <= Smax[i]**2

    model.const12 = Constraint(model.line, rule=stomax)

    # Set objective function
    # ------------------------
    def obj_fun(model):
        return sum(gk[i] * ((model.vm[fr[i]] / tr[i])**2 + model.vm[to[i]]**2 -
                         2/tr[i] * model.vm[fr[i]] * model.vm[to[i]] *
                         cos(model.va[fr[i]] - model.va[to[i]])) for i in range(nl))

    model.obj = Objective(rule=obj_fun, sense=minimize)

    mt = time.clock() - start_time                  # Modeling time

    # Execute solve command with the selected solver
    # ------------------------------------------------
    start_time = time.clock()
    results = opt.solve(model, tee=True)
    et = time.clock() - start_time                  # Elapsed time
    print(results)

    # Update the case info with the optimized variables
    # ==================================================
    for i in range(nb):
        bus[i, VM] = model.vm[i].value              # Bus voltage magnitudes
        bus[i, VA] = model.va[i].value*180/pi       # Bus voltage angles
    # Include Pf - Qf - Pt - Qt in the branch matrix
    branchsol = zeros((nl, 17))
    branchsol[:, :-4] = branch
    for i in range(nl):
        branchsol[i, PF] = model.Pf[i].value * baseMVA
        branchsol[i, QF] = model.Qf[i].value * baseMVA
        branchsol[i, PT] = model.Pt[i].value * baseMVA
        branchsol[i, QT] = model.Qt[i].value * baseMVA
    # Update gen matrix variables
    for i in range(ng):
        gen[i, PG] = model.Pg[gb[i]].value * baseMVA
        gen[i, QG] = model.Qg[gb[i]].value * baseMVA
        gen[i, VG] = bus[gb[i], VM]
    # Convert to external (original) numbering and save case results
    ppc = int2ext(ppc)
    ppc['bus'][:, 1:] = bus[:, 1:]
    branchsol[:, 0:2] = ppc['branch'][:, 0:2]
    ppc['branch'] = branchsol
    ppc['gen'][:, 1:] = gen[:, 1:]
    ppc['obj'] = value(obj_fun(model))
    ppc['ploss'] = value(obj_fun(model)) * baseMVA
    ppc['et'] = et
    ppc['mt'] = mt
    ppc['success'] = 1

    # ppc solved case is returned
    return ppc
示例#13
0
def solveropfnlp_4(ppc, solver="ipopt"):
    if solver == "ipopt":
        opt = SolverFactory(
            "ipopt",
            executable=
            "/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/ipopt-linux64/ipopt"
        )
    if solver == "bonmin":
        opt = SolverFactory(
            "bonmin",
            executable=
            "/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/bonmin-linux64/bonmin"
        )
    if solver == "knitro":
        opt = SolverFactory(
            "knitro",
            executable="D:/ICT/Artelys/Knitro 10.2.1/knitroampl/knitroampl")

    ppc = ext2int(ppc)  # convert to continuous indexing starting from 0

    # Gather information about the system
    # =============================================================
    baseMVA, bus, gen, branch = \
        ppc["baseMVA"], ppc["bus"], ppc["gen"], ppc["branch"]

    nb = bus.shape[0]  # number of buses
    ng = gen.shape[0]  # number of generators
    nl = branch.shape[0]  # number of lines

    # generator buses
    gb = tolist(np.array(gen[:, GEN_BUS]).astype(int))

    sb = find((bus[:, BUS_TYPE] == REF))  # slack bus index
    fr = branch[:, F_BUS].astype(int)  # from bus indices
    to = branch[:, T_BUS].astype(int)  # to bus indices

    tr0 = copy(branch[:, TAP])  # transformation ratios
    tr0[find(tr0 == 0)] = 1  # set to 1 transformation ratios that are 0
    tp = find(branch[:, TAP] != 0)  # lines with tap changers
    ntp = find(branch[:, TAP] == 0)  # lines without tap changers

    # Tap changer settings
    dudtap = 0.01  # Voltage per unit variation with tap changes
    tapmax = 10  # Highest tap changer setting
    tapmin = -10  # Lowest tap changer setting

    # Shunt element options
    stepmax = 1  # maximum step of the shunt element

    Bs0 = bus[:, BS] / baseMVA  # shunt elements susceptance
    sd = find(bus[:, BS] != 0)  # buses with shunt devices

    r = branch[:, BR_R]  # branch resistances
    x = branch[:, BR_X]  # branch reactances
    b = branch[:, BR_B]  # branch susceptances

    start_time = time.clock()

    # Admittance matrix computation
    # =============================================================
    # Set tap ratios and shunt elements to neutral position
    branch[:, TAP] = 1
    bus[:, BS] = 0

    y = makeYbus(baseMVA, bus, branch)[0]  # admittance matrix
    yk = 1. / (r + x * 1j)  # branch admittance
    yft = yk + 0.5j * b  # branch admittance + susceptance
    gk = yk.real  # branch resistance

    # Optimization
    # =============================================================
    branch[find(branch[:, RATE_A] == 0),
           RATE_A] = 9999  # set undefined Sflow limit to 9999
    Smax = branch[:, RATE_A] / baseMVA  # Max. Sflow

    # Power demand parameters
    Pd = bus[:, PD] / baseMVA
    Qd = bus[:, QD] / baseMVA

    # Max and min Pg and Qg
    Pg_max = zeros(nb)
    Pg_max[gb] = gen[:, PMAX] / baseMVA
    Pg_min = zeros(nb)
    Pg_min[gb] = gen[:, PMIN] / baseMVA
    Qg_max = zeros(nb)
    Qg_max[gb] = gen[:, QMAX] / baseMVA
    Qg_min = zeros(nb)
    Qg_min[gb] = gen[:, QMIN] / baseMVA

    # Vmax and Vmin vectors
    Vmax = bus[:, VMAX]
    Vmin = bus[:, VMIN]

    vm = bus[:, VM]
    va = bus[:, VA] * pi / 180

    # create a new optimization model
    model = ConcreteModel()

    # Define sets
    # ------------
    model.bus = Set(ordered=True, initialize=range(nb))  # Set of all buses
    model.gen = Set(ordered=True,
                    initialize=gb)  # Set of buses with generation
    model.line = Set(ordered=True, initialize=range(nl))  # Set of all lines
    model.taps = Set(ordered=True,
                     initialize=tp)  # Set of all lines with tap changers
    model.shunt = Set(ordered=True,
                      initialize=sd)  # Set of buses with shunt elements

    # Define variables
    # -----------------
    # Voltage magnitudes vector (vm)
    model.vm = Var(model.bus)

    # Voltage angles vector (va)
    model.va = Var(model.bus)

    # Reactive power generation, synchronous machines(SM) (Qg)
    model.Qg = Var(model.gen)
    Qg0 = zeros(nb)
    Qg0[gb] = gen[:, QG] / baseMVA

    # Active power generation, synchronous machines(SM) (Pg)
    model.Pg = Var(model.gen)
    Pg0 = zeros(nb)
    Pg0[gb] = gen[:, PG] / baseMVA

    # Active and reactive power from at all branches
    model.Pf = Var(model.line)
    model.Qf = Var(model.line)

    # Active and reactive power to at all branches
    model.Pt = Var(model.line)
    model.Qt = Var(model.line)

    # Transformation ratios
    model.tr = Var(model.taps)

    # Tap changer positions + their bounds
    model.tap = Var(model.taps, bounds=(tapmin, tapmax))

    # Shunt susceptance
    model.Bs = Var(model.shunt)

    # Shunt positions + their bounds
    model.s = Var(model.shunt, bounds=(0, stepmax))

    # Warm start the problem
    # ------------------------
    for i in range(nb):
        model.vm[i] = vm[i]
        model.va[i] = va[i]
        if i in gb:
            model.Pg[i] = Pg0[i]
            model.Qg[i] = Qg0[i]
    for i in range(nl):
        model.Pf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr0[i] ** 2) * np.cos(-ang(yft[i])) -\
            vm[fr[i]] * vm[to[i]] * abs(yk[i]) / tr0[i] * np.cos(va[fr[i]] - va[to[i]] - ang(yk[i]))
        model.Qf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr0[i] ** 2) * np.sin(-ang(yft[i])) -\
            vm[fr[i]] * vm[to[i]] * abs(yk[i]) / tr0[i] * np.sin(va[fr[i]] - va[to[i]] - ang(yk[i]))
        model.Pt[i] = vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) -\
            vm[to[i]] * vm[fr[i]] * abs(yk[i]) / tr0[i] * np.cos(va[to[i]] - va[fr[i]] - ang(yk[i]))
        model.Qt[i] = vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) -\
            vm[to[i]] * vm[fr[i]] * abs(yk[i]) / tr0[i] * np.sin(va[to[i]] - va[fr[i]] - ang(yk[i]))
    for i in tp:
        model.tr[i] = tr0[i]
    for i in sd:
        model.Bs[i] = Bs0[i]

    # Define constraints
    # ----------------------------

    # Equalities:
    # ------------

    # Active power flow equalities
    def powerflowact(model, i):
        bfrom_i = tp[find(fr[tp] == i)]  # branches from bus i with transformer
        bto_i = tp[find(to[tp] == i)]  # branches to bus i with transformer
        allbut_i = find(bus[:, BUS_I] != i)  # Set of other buses
        if i in gb:
            return model.Pg[i]-Pd[i] == sum(model.vm[i] * model.vm[j] * abs(y[i, j]) *
                                            cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in allbut_i) - \
                   sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * cos(model.va[i] -
                       model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                   sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * cos(model.va[i] -
                       model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                   model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j]**2 - 1) *
                                           np.cos(- ang(yk[j])) for j in bfrom_i) + real(y[i, i]))
        else:
            return sum(model.vm[i] * model.vm[j] * abs(y[i, j]) *
                       cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in allbut_i) - \
                   sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * cos(model.va[i] -
                       model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                   sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * cos(model.va[i] -
                       model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                   model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j]**2 - 1) *
                                           np.cos(- ang(yk[j])) for j in bfrom_i) + real(y[i, i])) == -Pd[i]

    model.const1 = Constraint(model.bus, rule=powerflowact)

    # Reactive power flow equalities
    def powerflowreact(model, i):
        bfrom_i = tp[find(fr[tp] == i)]  # branches from bus i with transformer
        bto_i = tp[find(to[tp] == i)]  # branches to bus i with transformer
        allbut_i = find(bus[:, BUS_I] != i)  # Set of other buses
        sh = sd[find(sd == i)]  # Detect shunt elements
        if i in gb:
            return model.Qg[i]-Qd[i] == \
                   sum(model.vm[i] * model.vm[j] * abs(y[i, j]) *
                       sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in allbut_i) - \
                   sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * sin(model.va[i] - model.va[to[j]] - ang(yk[j]))
                       * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                   sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * sin(model.va[i] - model.va[fr[j]] - ang(yk[j]))
                       * (1 / model.tr[j] - 1) for j in bto_i) + \
                   model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j] ** 2 - 1) * np.sin(- ang(yk[j]))
                                           for j in bfrom_i) - imag(y[i, i]) - sum(model.Bs[j] for j in sh))
        else:
            return sum(model.vm[i] * model.vm[j] * abs(y[i, j]) *
                       sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in allbut_i) - \
                   sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * sin(model.va[i] -
                       model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                   sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * sin(model.va[i] -
                       model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                   model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j] ** 2 - 1) * np.sin(- ang(yk[j]))
                                           for j in bfrom_i) - imag(y[i, i]) - sum(model.Bs[j] for j in sh)) == - Qd[i]

    model.const2 = Constraint(model.bus, rule=powerflowreact)

    # Active power from
    def pfrom(model, i):
        if i in tp:
            return model.Pf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (model.tr[i] ** 2) * np.cos(-ang(yft[i])) - \
                                  model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) / model.tr[i] * \
                                  cos(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))
        else:
            return model.Pf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / tr0[i] ** 2 * np.cos(-ang(yft[i])) - \
                                  model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) / tr0[i] * \
                                  cos(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))

    model.const3 = Constraint(model.line, rule=pfrom)

    # Reactive power from
    def qfrom(model, i):
        if i in tp:
            return model.Qf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (model.tr[i] ** 2) * np.sin(-ang(yft[i])) - \
                                  model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) / model.tr[i] * \
                                  sin(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))
        else:
            return model.Qf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / tr0[i] ** 2 * np.sin(-ang(yft[i])) - \
                                  model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) / tr0[i] * \
                                  sin(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))

    model.const4 = Constraint(model.line, rule=qfrom)

    # Active power to
    def pto(model, i):
        if i in tp:
            return model.Pt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) - \
                                  model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) / model.tr[i] * \
                                  cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
        else:
            return model.Pt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) - \
                                  model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) / tr0[i] * \
                                  cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))

    model.const5 = Constraint(model.line, rule=pto)

    # Reactive power to
    def qto(model, i):
        if i in tp:
            return model.Qt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) - \
                                  model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) / model.tr[i] * \
                                  sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
        else:
            return model.Qt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) - \
                                  model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) / tr0[i] * \
                                  sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))

    model.const6 = Constraint(model.line, rule=qto)

    # Slack bus phase angle
    model.const7 = Constraint(expr=model.va[sb[0]] == 0)

    # Transformation ratio equalities
    def trfunc(model, i):
        return model.tr[i] == 1 + dudtap * model.tap[i]

    model.const8 = Constraint(model.taps, rule=trfunc)

    # Shunt susceptance equality
    def shuntfunc(model, i):
        return model.Bs[i] == model.s[i] / stepmax * Bs0[i]

    model.const9 = Constraint(model.shunt, rule=shuntfunc)

    # Inequalities:
    # ----------------

    # Active power generator limits Pg_min <= Pg <= Pg_max
    def genplimits(model, i):
        return Pg_min[i] <= model.Pg[i] <= Pg_max[i]

    model.const10 = Constraint(model.gen, rule=genplimits)

    # Reactive power generator limits Qg_min <= Qg <= Qg_max
    def genqlimits(model, i):
        return Qg_min[i] <= model.Qg[i] <= Qg_max[i]

    model.const11 = Constraint(model.gen, rule=genqlimits)

    # Voltage constraints ( Vmin <= V <= Vmax )
    def vlimits(model, i):
        return Vmin[i] <= model.vm[i] <= Vmax[i]

    model.const12 = Constraint(model.bus, rule=vlimits)

    # Sfrom line limit
    def sfrommax(model, i):
        return model.Pf[i]**2 + model.Qf[i]**2 <= Smax[i]**2

    model.const13 = Constraint(model.line, rule=sfrommax)

    # Sto line limit
    def stomax(model, i):
        return model.Pt[i]**2 + model.Qt[i]**2 <= Smax[i]**2

    model.const14 = Constraint(model.line, rule=stomax)

    # Set objective function
    # ------------------------
    def obj_fun(model):
        return sum(gk[i] * ((model.vm[fr[i]] / model.tr[i])**2 + model.vm[to[i]]**2 -
                            2 / model.tr[i] * model.vm[fr[i]] * model.vm[to[i]] *
                            cos(model.va[fr[i]] - model.va[to[i]])) for i in tp) + \
               sum(gk[i] * ((model.vm[fr[i]] / tr0[i]) ** 2 + model.vm[to[i]] ** 2 -
                            2 / tr0[i] * model.vm[fr[i]] * model.vm[to[i]] *
                            cos(model.va[fr[i]] - model.va[to[i]])) for i in ntp)

    model.obj = Objective(rule=obj_fun, sense=minimize)

    mt = time.clock() - start_time  # Modeling time

    # Execute solve command with the selected solver
    # ------------------------------------------------
    start_time = time.clock()
    results = opt.solve(model, tee=True)
    et = time.clock() - start_time  # Elapsed time
    print(results)

    # Update the case info with the optimized variables and approximate the continuous variables to discrete values
    # ==============================================================================================================
    for i in range(nb):
        if i in sd:
            bus[i, BS] = round(model.s[i].value) * Bs0[i] * baseMVA
        bus[i, VM] = model.vm[i].value  # Bus voltage magnitudes
        bus[i, VA] = model.va[i].value * 180 / pi  # Bus voltage angles
    # Update transformation ratios
    for i in range(nl):
        if i in tp:
            branch[i, TAP] = 1 + dudtap * round(model.tap[i].value)
    # Update gen matrix variables
    for i in range(ng):
        gen[i, PG] = model.Pg[gb[i]].value * baseMVA
        gen[i, QG] = model.Qg[gb[i]].value * baseMVA
        gen[i, VG] = bus[gb[i], VM]
    # Convert to external (original) numbering and save case results
    ppc = int2ext(ppc)
    ppc['bus'][:, 1:] = bus[:, 1:]
    branch[:, 0:2] = ppc['branch'][:, 0:2]
    ppc['branch'] = branch
    ppc['gen'][:, 1:] = gen[:, 1:]

    # Execute a second optimization with only the discrete approximated values (requires solveropfnlp_2)
    sol = solveropfnlp_2(ppc)
    sol['mt'] = sol['mt'] + mt
    sol['et'] = sol['et'] + et
    sol['tap'] = zeros((tp.shape[0], 1))
    for i in range(tp.shape[0]):
        sol['tap'][i] = round(model.tap[tp[i]].value)
    sol['shunt'] = zeros((sd.shape[0], 1))
    for i in range(sd.shape[0]):
        sol['shunt'][i] = round(model.s[sd[i]].value)

    # ppc solved case is returned
    return sol
示例#14
0
    def __build_objectives(self):
        """
        Initialize different objectives

        :return:
        """

        self.model.Slack = Var(within=NonNegativeReals)

        def _decl_slack(model):
            return model.Slack == 10**6 * sum(
                comp.obj_slack() for comp in self.iter_components())

        self.model.decl_slack = Constraint(rule=_decl_slack)

        def obj_energy(model):
            return model.Slack + sum(comp.obj_energy()
                                     for comp in self.iter_components())

        def obj_cost(model):
            return model.Slack + sum(comp.obj_fuel_cost()
                                     for comp in self.iter_components()) + sum(
                                         comp.obj_elec_cost()
                                         for comp in self.iter_components())

        def obj_cost_ramp(model):
            return model.Slack + sum(comp.obj_cost_ramp()
                                     for comp in self.iter_components())

        def obj_co2(model):
            return model.Slack + sum(comp.obj_co2()
                                     for comp in self.iter_components())

        def obj_co2_fuel_cost(model):
            return model.Slack + sum(
                comp.obj_co2_cost() + comp.obj_fuel_cost()
                for comp in self.iter_components())

        self.model.OBJ_ENERGY = Objective(rule=obj_energy, sense=minimize)
        self.model.OBJ_COST = Objective(rule=obj_cost, sense=minimize)
        self.model.OBJ_COST_RAMP = Objective(rule=obj_cost_ramp,
                                             sense=minimize)
        self.model.OBJ_CO2 = Objective(rule=obj_co2, sense=minimize)
        self.model.OBJ_COST_CO2_FUEL = Objective(rule=obj_co2_fuel_cost,
                                                 sense=minimize)

        self.objectives = {
            'energy': self.model.OBJ_ENERGY,
            'cost': self.model.OBJ_COST,
            'cost_ramp': self.model.OBJ_COST_RAMP,
            'co2': self.model.OBJ_CO2,
            'cost_fuel_co2': self.model.OBJ_COST_CO2_FUEL
        }

        for objective in self.objectives.values():
            objective.deactivate()

        if self.temperature_driven:

            def obj_temp(model):
                return model.Slack + sum(comp.obj_temp()
                                         for comp in self.iter_components())

            self.model.OBJ_TEMP = Objective(rule=obj_temp, sense=minimize)

            self.objectives['temp'] = self.model.OBJ_TEMP
示例#15
0
# Network arcs
model.A = Set(within=model.N*model.N)

# Source node
model.s = Param(within=model.N)
# Sink node
model.t = Param(within=model.N)
# Flow capacity limits
model.c = Param(model.A)

# The flow over each arc
model.f = Var(model.A, within=NonNegativeReals)

# Maximize the flow into the sink nodes
def total_rule(model):
    return sum(model.f[i,j] for (i, j) in model.A if j == value(model.t))
model.total = Objective(rule=total_rule, sense=maximize)

# Enforce an upper limit on the flow across each arc
def limit_rule(model, i, j):
    return model.f[i,j] <= model.c[i, j]
model.limit = Constraint(model.A, rule=limit_rule)

# Enforce flow through each node
def flow_rule(model, k):
    if k == value(model.s) or k == value(model.t):
        return Constraint.Skip
    inFlow  = sum(model.f[i,j] for (i,j) in model.A if j == k)
    outFlow = sum(model.f[i,j] for (i,j) in model.A if i == k)
    return inFlow == outFlow
model.flow = Constraint(model.N, rule=flow_rule)
示例#16
0
    def create_model(self):
        """
        Create and return the mathematical model.
        """

        if options.DEBUG:
            logging.info("Creating model for day %d" % self.day_id)

        # Obtain the orders book
        book = self.orders
        complexOrders = self.complexOrders

        # Create the optimization model
        model = ConcreteModel()
        model.periods = Set(initialize=book.periods)
        maxPeriod = max(book.periods)
        model.bids = Set(initialize=range(len(book.bids)))
        model.L = Set(initialize=book.locations)
        model.sBids = Set(initialize=[
            i for i in range(len(book.bids)) if book.bids[i].type == 'SB'
        ])
        model.bBids = Set(initialize=[
            i for i in range(len(book.bids)) if book.bids[i].type == 'BB'
        ])
        model.cBids = RangeSet(len(complexOrders))  # Complex orders
        model.C = RangeSet(len(self.connections))
        model.directions = RangeSet(2)  # 1 == up, 2 = down TODO: clean

        # Variables
        model.xs = Var(model.sBids, domain=Reals,
                       bounds=(0.0, 1.0))  # Single period bids acceptance
        model.xb = Var(model.bBids, domain=Binary)  # Block bids acceptance
        model.xc = Var(model.cBids, domain=Binary)  # Complex orders acceptance
        model.pi = Var(model.L * model.periods,
                       domain=Reals,
                       bounds=self.priceCap)  # Market prices
        model.s = Var(model.bids, domain=NonNegativeReals)  # Bids
        model.sc = Var(model.cBids, domain=NonNegativeReals)  # complex orders
        model.complexVolume = Var(model.cBids, model.periods,
                                  domain=Reals)  # Bids
        model.pi_lg_up = Var(model.cBids * model.periods,
                             domain=NonNegativeReals)  # Market prices
        model.pi_lg_down = Var(model.cBids * model.periods,
                               domain=NonNegativeReals)  # Market prices
        model.pi_lg = Var(model.cBids * model.periods,
                          domain=Reals)  # Market prices

        def flowBounds(m, c, d, t):
            capacity = self.connections[c - 1].capacity_up[t] if d == 1 else \
                self.connections[c - 1].capacity_down[t]
            return (0, capacity)

        model.f = Var(model.C * model.directions * model.periods,
                      domain=NonNegativeReals,
                      bounds=flowBounds)
        model.u = Var(model.C * model.directions * model.periods,
                      domain=NonNegativeReals)

        # Objective
        def primalObj(m):
            # Single period bids cost
            expr = summation(
                {i: book.bids[i].price * book.bids[i].volume
                 for i in m.sBids}, m.xs)
            # Block bids cost
            expr += summation(
                {
                    i: book.bids[i].price * sum(book.bids[i].volumes.values())
                    for i in m.bBids
                }, m.xb)
            return -expr

        if options.PRIMAL and not options.DUAL:
            model.obj = Objective(rule=primalObj, sense=maximize)

        def primalDualObj(m):
            return primalObj(m) + sum(1e-5 * m.xc[i] for i in model.cBids)

        if options.PRIMAL and options.DUAL:
            model.obj = Objective(rule=primalDualObj, sense=maximize)

        # Complex order constraint
        if options.PRIMAL and options.DUAL:
            model.deactivate_suborders = ConstraintList()
            for o in model.cBids:
                sub_ids = complexOrders[o - 1].ids
                curves = complexOrders[o - 1].curves
                for id in sub_ids:
                    bid = book.bids[id]
                    if bid.period <= complexOrders[o - 1].SSperiods and bid.price == \
                            curves[bid.period].bids[0].price:
                        pass  # This bid, first step of the cruve in the scheduled stop periods, is not automatically deactivated when MIC constraint is not satisfied
                    else:
                        model.deactivate_suborders.add(
                            model.xs[id] <= model.xc[o])

        # Ramping constraints for complex orders
        def complex_volume_def_rule(m, o, p):
            sub_ids = complexOrders[o - 1].ids
            return m.complexVolume[o, p] == sum(m.xs[i] * book.bids[i].volume
                                                for i in sub_ids
                                                if book.bids[i].period == p)

        if options.PRIMAL:
            model.complex_volume_def = Constraint(model.cBids,
                                                  model.periods,
                                                  rule=complex_volume_def_rule)

        def complex_lg_down_rule(m, o, p):
            if p + 1 > maxPeriod or complexOrders[o - 1].ramp_down == None:
                return Constraint.Skip
            else:
                return m.complexVolume[o, p] - m.complexVolume[o, p + 1] <= complexOrders[
                                                                                o - 1].ramp_down * \
                                                                            m.xc[o]

        if options.PRIMAL and options.APPLY_LOAD_GRADIENT:
            model.complex_lg_down = Constraint(model.cBids,
                                               model.periods,
                                               rule=complex_lg_down_rule)

        def complex_lg_up_rule(m, o, p):
            if p + 1 > maxPeriod or complexOrders[o - 1].ramp_up == None:
                return Constraint.Skip
            else:
                return m.complexVolume[o, p + 1] - m.complexVolume[
                    o, p] <= complexOrders[o - 1].ramp_up

        if options.PRIMAL and options.APPLY_LOAD_GRADIENT:
            model.complex_lg_up = Constraint(
                model.cBids, model.periods,
                rule=complex_lg_up_rule)  # Balance constraint

        # Energy balance constraints
        balanceExpr = {l: {t: 0.0 for t in model.periods} for l in model.L}
        for i in model.sBids:  # Simple bids
            bid = book.bids[i]
            balanceExpr[bid.location][bid.period] += bid.volume * model.xs[i]
        for i in model.bBids:  # Block bids
            bid = book.bids[i]
            for t, v in bid.volumes.items():
                balanceExpr[bid.location][t] += v * model.xb[i]

        def balanceCstr(m, l, t):
            export = 0.0
            for c in model.C:
                if self.connections[c - 1].from_id == l:
                    export += m.f[c, 1, t] - m.f[c, 2, t]
                elif self.connections[c - 1].to_id == l:
                    export += m.f[c, 2, t] - m.f[c, 1, t]
            return balanceExpr[l][t] == export

        if options.PRIMAL:
            model.balance = Constraint(model.L * book.periods,
                                       rule=balanceCstr)

        # Surplus of single period bids
        def sBidSurplus(m, i):  # For the "usual" step orders
            bid = book.bids[i]
            if i in self.plain_single_orders:
                return m.s[i] >= (m.pi[bid.location, bid.period] -
                                  bid.price) * bid.volume
            else:
                return Constraint.Skip

        if options.DUAL:
            model.sBidSurplus = Constraint(model.sBids, rule=sBidSurplus)

        # Surplus definition for complex suborders accounting for impact of load gradient condition
        if options.DUAL:
            model.complex_sBidSurplus = ConstraintList()
            for o in model.cBids:
                sub_ids = complexOrders[o - 1].ids
                l = complexOrders[o - 1].location
                for i in sub_ids:
                    bid = book.bids[i]
                    model.complex_sBidSurplus.add(
                        model.s[i] >=
                        (model.pi[l, bid.period] + model.pi_lg[o, bid.period] -
                         bid.price) * bid.volume)

        def LG_price_def_rule(m, o, p):
            l = complexOrders[o - 1].location

            exp = 0
            if options.APPLY_LOAD_GRADIENT:
                D = complexOrders[o - 1].ramp_down
                U = complexOrders[o - 1].ramp_up
                if D is not None:
                    exp += (m.pi_lg_down[o, p - 1] if p > 1 else
                            0) - (m.pi_lg_down[o, p] if p < maxPeriod else 0)
                if U is not None:
                    exp -= (m.pi_lg_up[o, p - 1] if p > 1 else
                            0) - (m.pi_lg_up[o, p] if p < maxPeriod else 0)

            return m.pi_lg[o, p] == exp

        if options.DUAL:
            model.LG_price_def = Constraint(model.cBids,
                                            model.periods,
                                            rule=LG_price_def_rule)

        # Surplus of block bids
        def bBidSurplus(m, i):
            bid = book.bids[i]
            bidVolume = -sum(bid.volumes.values())
            bigM = (self.priceCap[1] -
                    self.priceCap[0]) * bidVolume  # FIXME tighten BIGM
            return m.s[i] + sum([
                m.pi[bid.location, t] * -v for t, v in bid.volumes.items()
            ]) >= bid.cost * bidVolume + bigM * (1 - m.xb[i])

        if options.DUAL:
            model.bBidSurplus = Constraint(model.bBids, rule=bBidSurplus)

        # Surplus of complex orders
        def cBidSurplus(m, o):
            complexOrder = complexOrders[o - 1]
            sub_ids = complexOrder.ids
            if book.bids[sub_ids[0]].volume > 0:  # supply
                bigM = sum((self.priceCap[1] - book.bids[i].price) *
                           book.bids[i].volume for i in sub_ids)
            else:
                bigM = sum((book.bids[i].price - self.priceCap[0]) *
                           book.bids[i].volume for i in sub_ids)
            return m.sc[o] + bigM * (1 - m.xc[o]) >= sum(m.s[i]
                                                         for i in sub_ids)

        if options.DUAL:
            model.cBidSurplus = Constraint(model.cBids, rule=cBidSurplus)

        # Surplus of complex orders
        def cBidSurplus_2(m, o):
            complexOrder = complexOrders[o - 1]
            expr = 0
            for i in complexOrder.ids:
                bid = book.bids[i]
                if (bid.period <= complexOrder.SSperiods) and (
                        bid.price
                        == complexOrder.curves[bid.period].bids[0].price):
                    expr += m.s[i]
            return m.sc[o] >= expr

        if options.DUAL:
            model.cBidSurplus_2 = Constraint(
                model.cBids, rule=cBidSurplus_2)  # MIC constraint

        def cMIC(m, o):
            complexOrder = complexOrders[o - 1]

            if complexOrder.FT == 0 and complexOrder.VT == 0:
                return Constraint.Skip

            expr = 0
            bigM = complexOrder.FT
            for i in complexOrder.ids:
                bid = book.bids[i]
                if (bid.period <= complexOrder.SSperiods) and (
                        bid.price
                        == complexOrder.curves[bid.period].bids[0].price):
                    bigM += (bid.volume * (self.priceCap[1] - bid.price)
                             )  # FIXME assumes order is supply
                expr += bid.volume * m.xs[i] * (bid.price - complexOrder.VT)

            return m.sc[o] + expr + bigM * (1 - m.xc[o]) >= complexOrder.FT

        if options.DUAL and options.PRIMAL:
            model.cMIC = Constraint(model.cBids, rule=cMIC)

        # Dual connections capacity
        def dualCapacity(m, c, t):
            exportPrices = 0.0
            for l in m.L:
                if l == self.connections[c - 1].from_id:
                    exportPrices += m.pi[l, t]
                elif l == self.connections[c - 1].to_id:
                    exportPrices -= m.pi[l, t]
            return m.u[c, 1, t] - m.u[c, 2, t] + exportPrices == 0.0

        if options.DUAL:
            model.dualCapacity = Constraint(model.C * model.periods,
                                            rule=dualCapacity)

        # Dual optimality
        def dualObj(m):
            dualObj = summation(m.s) + summation(m.sc)

            for o in m.cBids:
                sub_ids = complexOrders[o - 1].ids
                for id in sub_ids:
                    dualObj -= m.s[
                        id]  # Remove contribution of complex suborders which were accounted for in prevous summation over single bids

                if options.APPLY_LOAD_GRADIENT:
                    ramp_down = complexOrders[o - 1].ramp_down
                    ramp_up = complexOrders[o - 1].ramp_up
                    for p in m.periods:
                        if p == maxPeriod:
                            continue
                        if ramp_down is not None:
                            dualObj += ramp_down * m.pi_lg_down[
                                o, p]  # Add contribution of load gradient
                        if ramp_up is not None:
                            dualObj += ramp_up * m.pi_lg_up[
                                o, p]  # Add contribution of load gradient

            for c in model.C:
                for t in m.periods:
                    dualObj += self.connections[c - 1].capacity_up[t] * m.u[c,
                                                                            1,
                                                                            t]
                    dualObj += self.connections[c -
                                                1].capacity_down[t] * m.u[c, 2,
                                                                          t]

            return dualObj

        if not options.PRIMAL:
            model.obj = Objective(rule=dualObj, sense=minimize)

        def primalEqualsDual(m):
            return primalObj(m) >= dualObj(m)

        if options.DUAL and options.PRIMAL:
            model.primalEqualsDual = Constraint(rule=primalEqualsDual)

        self.model = model
示例#17
0
def representative(duration_repr,
                   selection,
                   VWat=75000,
                   solArea=2 * (18300 + 15000),
                   VSTC=75000,
                   pipe_model='ExtensivePipe',
                   time_step=3600):
    """

    Args:
        duration_repr:
        selection:
        VWat:
        solArea:
        VSTC:
        pipe_model:
        time_step:

    Returns:

    """
    unit_sec = 3600 * 24  # Seconds per unit time of duration (seconds per day)

    netGraph = CaseFuture.make_graph(repr=True)

    import pandas as pd
    import time

    begin = time.clock()
    topmodel = ConcreteModel()

    # In[14]:

    optimizers = {}
    epoch = pd.Timestamp('20140101')
    for start_day, duration in selection.items():
        start_time = epoch + pd.Timedelta(days=start_day)
        optmodel = Modesto(graph=netGraph, pipe_model=pipe_model)
        for comp in optmodel.get_node_components(
                filter_type='StorageCondensed').values():
            comp.set_reps(num_reps=int(duration))
        topmodel.add_component(name='repr_' + str(start_day),
                               val=optmodel.model)

        #####################
        # Assign parameters #
        #####################

        optmodel = CaseFuture.set_params(
            optmodel,
            pipe_model=pipe_model,
            repr=True,
            horizon=duration_repr * unit_sec,
            time_step=time_step,
        )
        optmodel.change_param(node='SolarArray',
                              comp='solar',
                              param='area',
                              val=solArea)
        optmodel.change_param(node='SolarArray',
                              comp='tank',
                              param='volume',
                              val=VSTC)
        optmodel.change_param(node='WaterscheiGarden',
                              comp='tank',
                              param='volume',
                              val=VWat)

        optmodel.change_param(node='Production',
                              comp='backup',
                              param='ramp',
                              val=0)
        optmodel.change_param(node='Production',
                              comp='backup',
                              param='ramp_cost',
                              val=0)

        optmodel.compile(start_time=start_time)
        # optmodel.set_objective('energy')

        optimizers[start_day] = optmodel

    # In[ ]:

    ##############################
    # Compile aggregated problem #
    ##############################

    selected_days = selection.keys()

    for i, next_day in enumerate(selected_days):
        current = selected_days[i - 1]

        next_heat = optimizers[next_day].get_node_components(
            filter_type='StorageCondensed')
        current_heat = optimizers[current].get_node_components(
            filter_type='StorageCondensed')

        for component_id in next_heat:
            # Link begin and end of representative periods
            def _link_stor(m):
                """

                Args:
                    m:

                Returns:

                """
                return next_heat[component_id].get_heat_stor_init() == \
                       current_heat[component_id].get_heat_stor_final()

            topmodel.add_component(name='_'.join(
                [component_id, str(current), 'eq']),
                                   val=Constraint(rule=_link_stor))
            # print 'State equation added for storage {} in representative week starting on day {}'.format(
            #     component_id,
            #     current)

    # In[ ]:

    def _top_objective(m):
        """

        Args:
            m:

        Returns:

        """
        return 365 / (duration_repr * (365 // duration_repr)) * sum(
            repetitions * optimizers[start_day].get_objective(objtype='energy',
                                                              get_value=False)
            for start_day, repetitions in selection.items())

    # Factor 365/364 to make up for missing day
    # set get_value to False to return object instead of value of the objective function
    topmodel.obj = Objective(rule=_top_objective, sense=minimize)

    # In[ ]:

    end = time.clock()

    # print 'Writing time:', str(end - begin)

    return topmodel, optimizers
示例#18
0
def minimize_dr_vars(model_data, config):
    """
    Decision rule polishing: For a given optimal design (x) determined in separation,
    and the optimal value for control vars (z), choose min magnitude decision_rule_var
    values.
    """
    #config.progress_logger.info("Executing decision rule variable polishing solve.")
    model = model_data.master_model
    polishing_model = model.clone()

    first_stage_variables = polishing_model.scenarios[
        0, 0].util.first_stage_variables
    decision_rule_vars = polishing_model.scenarios[0,
                                                   0].util.decision_rule_vars

    polishing_model.obj.deactivate()
    index_set = decision_rule_vars[0].index_set()
    polishing_model.tau_vars = []
    # ==========
    for idx in range(len(decision_rule_vars)):
        polishing_model.scenarios[0, 0].add_component(
            "polishing_var_" + str(idx),
            Var(index_set, initialize=1e6, domain=NonNegativeReals))
        polishing_model.tau_vars.append(
            getattr(polishing_model.scenarios[0, 0],
                    "polishing_var_" + str(idx)))
    # ==========
    this_iter = polishing_model.scenarios[
        max(polishing_model.scenarios.keys())[0], 0]
    nom_block = polishing_model.scenarios[0, 0]
    if config.objective_focus == ObjectiveType.nominal:
        obj_val = value(this_iter.second_stage_objective +
                        this_iter.first_stage_objective)
        polishing_model.scenarios[0,0].polishing_constraint = \
            Constraint(expr=obj_val >= nom_block.second_stage_objective + nom_block.first_stage_objective)
    elif config.objective_focus == ObjectiveType.worst_case:
        polishing_model.zeta.fix(
        )  # Searching equivalent optimal solutions given optimal zeta

    # === Make absolute value constraints on polishing_vars
    polishing_model.scenarios[
        0, 0].util.absolute_var_constraints = cons = ConstraintList()
    uncertain_params = nom_block.util.uncertain_params
    if config.decision_rule_order == 1:
        for i, tau in enumerate(polishing_model.tau_vars):
            for j in range(len(this_iter.util.decision_rule_vars[i])):
                if j == 0:
                    cons.add(
                        -tau[j] <= this_iter.util.decision_rule_vars[i][j])
                    cons.add(this_iter.util.decision_rule_vars[i][j] <= tau[j])
                else:
                    cons.add(
                        -tau[j] <= this_iter.util.decision_rule_vars[i][j] *
                        uncertain_params[j - 1])
                    cons.add(this_iter.util.decision_rule_vars[i][j] *
                             uncertain_params[j - 1] <= tau[j])
    elif config.decision_rule_order == 2:
        l = list(range(len(uncertain_params)))
        index_pairs = list(it.combinations(l, 2))
        for i, tau in enumerate(polishing_model.tau_vars):
            Z = this_iter.util.decision_rule_vars[i]
            indices = list(k for k in range(len(Z)))
            for r in indices:
                if r == 0:
                    cons.add(-tau[r] <= Z[r])
                    cons.add(Z[r] <= tau[r])
                elif r <= len(uncertain_params) and r > 0:
                    cons.add(-tau[r] <= Z[r] * uncertain_params[r - 1])
                    cons.add(Z[r] * uncertain_params[r - 1] <= tau[r])
                elif r <= len(indices) - len(uncertain_params) - 1 and r > len(
                        uncertain_params):
                    cons.add(-tau[r] <= Z[r] * uncertain_params[index_pairs[
                        r - len(uncertain_params) - 1][0]] * uncertain_params[
                            index_pairs[r - len(uncertain_params) - 1][1]])
                    cons.add(Z[r] * uncertain_params[index_pairs[
                        r - len(uncertain_params) - 1][0]] *
                             uncertain_params[index_pairs[
                                 r - len(uncertain_params) - 1][1]] <= tau[r])
                elif r > len(indices) - len(uncertain_params) - 1:
                    cons.add(-tau[r] <= Z[r] *
                             uncertain_params[r - len(index_pairs) -
                                              len(uncertain_params) - 1]**2)
                    cons.add(Z[r] * uncertain_params[r - len(index_pairs) -
                                                     len(uncertain_params) -
                                                     1]**2 <= tau[r])
    else:
        raise NotImplementedError(
            "Decision rule variable polishing has not been generalized to decision_rule_order "
            + str(config.decision_rule_order) + ".")

    polishing_model.scenarios[0,0].polishing_obj = \
        Objective(expr=sum(sum(tau[j] for j in tau.index_set()) for tau in polishing_model.tau_vars))

    # === Fix design
    for d in first_stage_variables:
        d.fix()

    # === Unfix DR vars
    num_dr_vars = len(model.scenarios[
        0, 0].util.decision_rule_vars[0])  # there is at least one dr var
    num_uncertain_params = len(config.uncertain_params)

    if model.const_efficiency_applied:
        for d in decision_rule_vars:
            for i in range(1, num_dr_vars):
                d[i].fix(0)
                d[0].unfix()
    elif model.linear_efficiency_applied:
        for d in decision_rule_vars:
            d.unfix()
            for i in range(num_uncertain_params + 1, num_dr_vars):
                d[i].fix(0)
    else:
        for d in decision_rule_vars:
            d.unfix()

    # === Unfix all control var values
    for block in polishing_model.scenarios.values():
        for c in block.util.second_stage_variables:
            c.unfix()
        if model.const_efficiency_applied:
            for d in block.util.decision_rule_vars:
                for i in range(1, num_dr_vars):
                    d[i].fix(0)
                    d[0].unfix()
        elif model.linear_efficiency_applied:
            for d in block.util.decision_rule_vars:
                d.unfix()
                for i in range(num_uncertain_params + 1, num_dr_vars):
                    d[i].fix(0)
        else:
            for d in block.util.decision_rule_vars:
                d.unfix()

    # === Solve the polishing model
    polish_soln = MasterResult()
    solver = config.global_solver

    if not solver.available():
        raise RuntimeError("NLP solver %s is not available." % config.solver)
    try:
        results = solver.solve(polishing_model, tee=config.tee)
        polish_soln.termination_condition = results.solver.termination_condition
    except ValueError as err:
        polish_soln.pyros_termination_condition = pyrosTerminationCondition.subsolver_error
        polish_soln.termination_condition = tc.error
        raise

    polish_soln.fsv_values = list(
        v.value
        for v in polishing_model.scenarios[0, 0].util.first_stage_variables)
    polish_soln.ssv_values = list(
        v.value
        for v in polishing_model.scenarios[0, 0].util.second_stage_variables)
    polish_soln.first_stage_objective = value(nom_block.first_stage_objective)
    polish_soln.second_stage_objective = value(
        nom_block.second_stage_objective)

    # === Process solution by termination condition
    acceptable = [tc.optimal, tc.locallyOptimal, tc.feasible]
    if polish_soln.termination_condition not in acceptable:
        return results

    for i, d in enumerate(
            model_data.master_model.scenarios[0, 0].util.decision_rule_vars):
        for index in d:
            d[index].set_value(polishing_model.scenarios[
                0, 0].util.decision_rule_vars[i][index].value,
                               skip_validation=True)

    return results
示例#19
0
文件: plugins.py 项目: xfLee/pyomo
    def _dualize(self, block, unfixed=[]):
        """
        Generate the dual of a block
        """
        #
        # Collect linear terms from the block
        #
        A, b_coef, c_rhs, c_sense, d_sense, vnames, cnames, v_domain = collect_linear_terms(
            block, unfixed)
        ##print(A)
        ##print(vnames)
        ##print(cnames)
        ##print(list(A.keys()))
        ##print("---")
        ##print(A.keys())
        ##print(c_sense)
        ##print(c_rhs)
        #
        # Construct the block
        #
        if isinstance(block, Model):
            dual = ConcreteModel()
        else:
            dual = Block()
        dual.construct()
        _vars = {}

        def getvar(name, ndx=None):
            v = _vars.get((name, ndx), None)
            if v is None:
                v = Var()
                if ndx is None:
                    v_name = name
                elif type(ndx) is tuple:
                    v_name = "%s[%s]" % (name, ','.join(map(str, ndx)))
                else:
                    v_name = "%s[%s]" % (name, str(ndx))
                setattr(dual, v_name, v)
                _vars[name, ndx] = v
            return v

        #
        # Construct the objective
        #
        if d_sense == minimize:
            dual.o = Objective(expr=sum(-b_coef[name, ndx] * getvar(name, ndx)
                                        for name, ndx in b_coef),
                               sense=d_sense)
        else:
            dual.o = Objective(expr=sum(b_coef[name, ndx] * getvar(name, ndx)
                                        for name, ndx in b_coef),
                               sense=d_sense)
        #
        # Construct the constraints
        #
        for cname in A:
            for ndx, terms in iteritems(A[cname]):
                expr = 0
                for term in terms:
                    expr += term.coef * getvar(term.var, term.ndx)
                if not (cname, ndx) in c_rhs:
                    c_rhs[cname, ndx] = 0.0
                if c_sense[cname, ndx] == 'e':
                    e = expr - c_rhs[cname, ndx] == 0
                elif c_sense[cname, ndx] == 'l':
                    e = expr - c_rhs[cname, ndx] <= 0
                else:
                    e = expr - c_rhs[cname, ndx] >= 0
                c = Constraint(expr=e)
                if ndx is None:
                    c_name = cname
                elif type(ndx) is tuple:
                    c_name = "%s[%s]" % (cname, ','.join(map(str, ndx)))
                else:
                    c_name = "%s[%s]" % (cname, str(ndx))
                setattr(dual, c_name, c)
            #
            for (name, ndx), domain in iteritems(v_domain):
                v = getvar(name, ndx)
                flag = type(ndx) is tuple and (ndx[-1] == 'lb'
                                               or ndx[-1] == 'ub')
                if domain == 1:
                    v.domain = NonNegativeReals
                elif domain == -1:
                    v.domain = NonPositiveReals
                else:
                    # TODO: verify that this case is possible
                    v.domain = Reals

        return dual
示例#20
0
for x in e.states:
    con = getattr(e.d1, x + '_icc')
    with open("states_sens.txt", "a") as f:
        for key in con.keys():
            if not con[key].active:
                continue
            f.write(x + "\t" + str(key) + "\n")
        f.close()
    # con.set_suffix_value(e.d1.dcdp, 1)
    var = getattr(e.d1, x)
    for key in var.keys():
        if key[1] == e.ncp_t:
            if var[key].stale:
                continue
            con[key[2:]].set_suffix_value(e.d1.dcdp, ii)
            var[key].set_suffix_value(e.d1.var_order, ii)
            ii += 1
f = open("suf0.txt", "w")
e.d1.var_order.pprint(ostream=f)
f.close()
e.d1.dum_of = Objective(expr=1, sense=minimize)
e.d1.write_nl(name="whatevs0.nl")
kaug = SolverFactory("k_aug",
                     executable="/home/dav0/k2/KKT_matrix/src/kmatrix/k_aug")
kaug.options["compute_dsdp"] = ""
f = open("suf1.txt", "w")
e.d1.var_order.pprint(ostream=f)
f.close()
e.d1.write_nl(name="whatevs.nl")
kaug.solve(e.d1, tee=True)
# Turn off file determinism
示例#21
0
    def find_target_ss(self, ref_state=None, **kwargs):
        """Attempt to find a second steady state
        Args:
            ref_state (dict): Contains the reference state with value key "state", (j,): value
            kwargs (dict): Optional arguments
        Returns
            None"""

        if ref_state:
            self.ref_state = ref_state
        else:
            if not ref_state:
                self.journalist("W", self._iteration_count,
                                "find_target_ss", "No reference state was given, using default")
            if not self.ref_state:
                self.journalist("W", self._iteration_count,
                                "find_target_ss", "No default reference state was given, exit")
                sys.exit()

        weights_ref = dict.fromkeys(self.ref_state.keys())
        for i in self.ref_state.keys():
            v = getattr(self.SteadyRef, i[0])
            vkey = i[1]
            vss0 = value(v[(0, 1) + vkey])
            val = abs(self.ref_state[i] - vss0)
            if val < 1e-09:
                val = 1e+06
            else:
                val = 1/val
            weights_ref[i] = val

        weights = kwargs.pop("weights", weights_ref)

        self.journalist("I", self._iteration_count, "find_target_ss", "Attempting to find steady state")

        del self.SteadyRef2
        self.SteadyRef2 = self.d_mod(1, 1, steady=True)
        self.SteadyRef2.name = "SteadyRef2 (reference)"
        for u in self.u:
            cv = getattr(self.SteadyRef2, u)  #: Get the param
            c_val = [value(cv[i]) for i in cv.keys()]  #: Current value
            self.SteadyRef2.del_component(cv)  #: Delete the param
            self.SteadyRef2.add_component(u, Var(self.SteadyRef2.fe_t, initialize=lambda m, i: c_val[i-1]))
            self.SteadyRef2.equalize_u(direction="r_to_u")
            cc = getattr(self.SteadyRef2, u + "_c")  #: Get the constraint
            ce = getattr(self.SteadyRef2, u + "_e")  #: Get the expression
            cv = getattr(self.SteadyRef2, u)  #: Get the new variable
            for k in cv.keys():
                cv[k].setlb(self.u_bounds[u][0])
                cv[k].setub(self.u_bounds[u][1])
            cc.clear()
            cc.rule = lambda m, i: cv[i] == ce[i]
            cc.reconstruct()

        self.SteadyRef2.create_bounds()
        self.SteadyRef2.equalize_u(direction="r_to_u")

        for vs in self.SteadyRef.component_objects(Var, active=True):  #: Load_guess
            vt = getattr(self.SteadyRef2, vs.getname())
            for ks in vs.keys():
                vt[ks].set_value(value(vs[ks]))
        ofexp = 0
        for i in self.ref_state.keys():
            v = getattr(self.SteadyRef2, i[0])
            val = value((v[(0, 1) + vkey]))
            vkey = i[1]
            ofexp += weights[i] * (v[(0, 1) + vkey] - self.ref_state[i])**2
            # ofexp += -weights[i] * (v[(1, 1) + vkey])**2 #- self.ref_state[i])**2
        self.SteadyRef2.obfun_SteadyRef2 = Objective(expr=ofexp, sense=minimize)

        tst = self.solve_dyn(self.SteadyRef2, iter_max=10000, stop_if_nopt=True, halt_on_ampl_error=False, **kwargs)
        # self.SteadyRef2.write_nl(name="steady.nl")
        # self.SteadyRef2.write_nl()
        # self.SteadyRef2.snap_shot(filename="mom.py")
        # sys.exit()

        if tst != 0:
            self.SteadyRef2.display(filename="failed_SteadyRef2.txt")
            self.SteadyRef2.write(filename="failed_SteadyRef2.nl",
                           format=ProblemFormat.nl,
                           io_options={"symbolic_solver_labels": True})
            # sys.exit(-1)
        self.journalist("I", self._iteration_count, "find_target_ss", "Target: solve done")
        for i in self.ref_state.keys():
            v = getattr(self.SteadyRef2, i[0])
            vkey = i[1]
            val = value(v[(0, 1) + vkey])
            print("target {:}".format(i[0]), "key {:}".format(i[1]), "weight {:f}".format(weights[i]),
                  "value {:f}".format(val))
        for u in self.u:
            v = getattr(self.SteadyRef2, u)
            val = value(v[0])
            print("target {:}".format(u), " value {:f}".format(val))
        self.update_targets_nmpc()
示例#22
0
    def __init__(
        self,
        data,
        target,
        number_regions,
        lam,
        epsilon=0.01,
        f_star=None,
        selected_features=None,
    ):
        super().__init__(
            name="OplraRegression %d regions (f*=%s)" % (number_regions, f_star)
        )
        self.number_regions = number_regions

        # Data and parameters
        self.data = data
        self.target = target
        self.lam = lam
        self.U1 = 1.5
        self.U2 = sum(self.target)
        self.epsilon = epsilon

        # Indices of the model
        self.s = Set(initialize=data.index.tolist())
        self.r = Set(initialize=range(self.number_regions))
        if self.number_regions == 1 or selected_features is None:
            self.f = Set(initialize=self.data.columns, ordered=True)
        else:
            self.f = Set(initialize=selected_features, ordered=True)

        # Variables common to both FEATURE_SELECTION and PIECEWISE models
        self.W = Var(self.r, self.f, initialize=0)

        self.absW = Var(self.r, self.f, domain=NonNegativeReals, initialize=0)
        self.B = Var(self.r, initialize=0)
        self.Pred = Var(self.r, self.s, initialize=0)
        self.D = Var(self.s, domain=NonNegativeReals, initialize=0)
        self.F = Var(self.r, self.s, domain=Binary, initialize=0)
        self.z = Var(domain=NonNegativeReals, initialize=0)
        self.mae = Var(domain=NonNegativeReals, initialize=0)
        self.reg = Var(domain=NonNegativeReals, initialize=0)

        if self.number_regions > 1 and f_star is None:
            raise ValueError("f_star is invalid.")

        self.fStar = f_star

        # Specific variables and constraints according to model (number of regions)
        if self.number_regions == 1:
            self.sf = Var(self.f, domain=Binary, initialize=0)
            # Old equations used for explicit feature selection
            # self.number_features    = Constraint(rule=OplraPyomoModel.number_features_rule)
            # self.upper_bound_coeff  = Constraint(self.r, self.f, rule=OplraPyomoModel.upper_bound_coeff_rule)
            # self.lower_bound_coeff  = Constraint(self.r, self.f, rule=OplraPyomoModel.lower_bound_coeff_rule)
        else:
            self.isSimpleLinear = False
            self.fStar = self.fStar
            self.X = Var(self.r, bounds=(0.0, 1.0), initialize=0)
            self.rr = Set(within=self.r)
            self.breakpoint_order = Constraint(
                self.r, rule=OplraPyomoModel.breakpoint_order_rule
            )
            self.region_divider1 = Constraint(
                self.r, self.s, rule=OplraPyomoModel.region_divider1_rule
            )
            self.region_divider2 = Constraint(
                self.r, self.s, rule=OplraPyomoModel.region_divider2_rule
            )

        # Common constraints
        self.sample_to_region = Constraint(
            self.s, rule=OplraPyomoModel.sample_to_region_rule
        )
        self.prediction = Constraint(
            self.r, self.s, rule=OplraPyomoModel.prediction_rule
        )
        self.abs_error1 = Constraint(
            self.r, self.s, rule=OplraPyomoModel.abs_error1_rule
        )
        self.abs_error2 = Constraint(
            self.r, self.s, rule=OplraPyomoModel.abs_error2_rule
        )
        self.abs_coeff1 = Constraint(
            self.r, self.f, rule=OplraPyomoModel.abs_coeff1_rule
        )
        self.abs_coeff2 = Constraint(
            self.r, self.f, rule=OplraPyomoModel.abs_coeff2_rule
        )
        self.mae_eqn = Constraint(rule=OplraPyomoModel.mae_rule)
        self.reg_eqn = Constraint(rule=OplraPyomoModel.regularisation_rule)
        self.z_eqn = Constraint(rule=OplraPyomoModel.z_rule)
        self.obj = Objective(rule=OplraPyomoModel.objective_rule, sense=minimize)
示例#23
0
 def _dualize(self, block, unfixed=[]):
     """
     Generate the dual of a block
     """
     #
     # Collect linear terms from the block
     #
     A, b_coef, c_rhs, c_sense, d_sense, vnames, cnames, v_domain = collect_linear_terms(
         block, unfixed)
     #
     # Construct the block
     #
     if isinstance(block, Model):
         dual = ConcreteModel()
     else:
         dual = Block()
     for v, is_indexed in vnames:
         if is_indexed:
             setattr(dual, v + '_Index', Set(dimen=None))
             setattr(dual, v, Var(getattr(dual, v + '_Index')))
         else:
             setattr(dual, v, Var())
     for cname, is_indexed in cnames:
         if is_indexed:
             setattr(dual, cname + '_Index', Set(dimen=None))
             setattr(dual, cname,
                     Constraint(getattr(dual, cname + '_Index')))
             setattr(dual, cname + '_lower_',
                     Var(getattr(dual, cname + '_Index')))
             setattr(dual, cname + '_upper_',
                     Var(getattr(dual, cname + '_Index')))
         else:
             setattr(dual, cname, Constraint())
             setattr(dual, cname + '_lower_', Var())
             setattr(dual, cname + '_upper_', Var())
     dual.construct()
     #
     # Add variables
     #
     # TODO: revisit this hack.  We shouldn't be calling
     # _getitem_when_not_present()
     #
     for name, ndx in b_coef:
         v = getattr(dual, name)
         if not ndx in v:
             v._getitem_when_not_present(ndx)
     #
     # Construct the objective
     #
     if d_sense == minimize:
         dual.o = Objective(expr=sum(-b_coef[name, ndx] *
                                     getattr(dual, name)[ndx]
                                     for name, ndx in b_coef),
                            sense=d_sense)
     else:
         dual.o = Objective(expr=sum(b_coef[name, ndx] *
                                     getattr(dual, name)[ndx]
                                     for name, ndx in b_coef),
                            sense=d_sense)
     #
     # Construct the constraints
     #
     for cname in A:
         c = getattr(dual, cname)
         c_index = getattr(dual, cname +
                           "_Index") if c.is_indexed() else None
         for ndx, terms in iteritems(A[cname]):
             if not c_index is None and not ndx in c_index:
                 c_index.add(ndx)
             expr = 0
             for term in terms:
                 v = getattr(dual, term.var)
                 if not term.ndx in v:
                     v.add(term.ndx)
                 expr += term.coef * v[term.ndx]
             if not (cname, ndx) in c_rhs:
                 c_rhs[cname, ndx] = 0.0
             if c_sense[cname, ndx] == 'e':
                 c.add(ndx, expr - c_rhs[cname, ndx] == 0)
             elif c_sense[cname, ndx] == 'l':
                 c.add(ndx, expr - c_rhs[cname, ndx] <= 0)
             else:
                 c.add(ndx, expr - c_rhs[cname, ndx] >= 0)
         for (name, ndx), domain in iteritems(v_domain):
             v = getattr(dual, name)
             flag = type(ndx) is tuple and (ndx[-1] == 'lb'
                                            or ndx[-1] == 'ub')
             if domain == 1:
                 if flag:
                     v[ndx].domain = NonNegativeReals
                 else:
                     v.domain = NonNegativeReals
             elif domain == -1:
                 if flag:
                     v[ndx].domain = NonPositiveReals
                 else:
                     v.domain = NonPositiveReals
             else:
                 if flag:
                     # TODO: verify that this case is possible
                     v[ndx].domain = Reals
                 else:
                     v.domain = Reals
     return dual
示例#24
0
    def __init__(self, **kwargs):
        # Values for the suffixes of input files
        self.int_file_mhe_suf = int()
        self.res_file_mhe_suf = str()

        self.int_file_nmpc_suf = int()
        self.res_file_nmpc_suf = str()

        self.res_file_suf = str(int(time.time()))

        self.d_mod = kwargs.pop('d_mod', None)

        self.nfe_t = kwargs.pop('nfe_t', 5)
        self.ncp_t = kwargs.pop('ncp_t', 3)

        self._t = kwargs.pop('_t', 100)
        self.states = kwargs.pop('states', [])
        self.u = kwargs.pop('u', [])  #: The inputs (controls)

        self.hi_t = self._t / self.nfe_t
        self.ss = self.d_mod(1, 1, steady=True)
        self.ss2 = object
        self.d1 = self.d_mod(1, self.ncp_t, _t=self.hi_t)
        self.d2 = object()
        self.ss.name = "ss"
        self.d1.name = "d1"

        self.ipopt = SolverFactory("ipopt")
        self.asl_ipopt = SolverFactory("asl:ipopt")
        self.k_aug = SolverFactory(
            "k_aug", executable="/home/dav0/k2/KKT_matrix/src/kmatrix/k_aug")
        self.k_aug_sens = SolverFactory(
            "k_aug", executable="/home/dav0/k2/KKT_matrix/src/kmatrix/k_aug")
        self.dot_driver = SolverFactory(
            "dot_driver",
            executable=
            "/home/dav0/k2/KKT_matrix/src/kmatrix/dot_driver/dot_driver")

        # self.k_aug.options["eig_rh"] = ""
        self.asl_ipopt.options["halt_on_ampl_error"] = "yes"

        # self.ipopt.options["print_user_options"] = "yes"
        # self.k_aug.options["deb_kkt"] = ""

        self.ss.ofun = Objective(expr=1, sense=minimize)
        self.dyn = object()
        self.l_state = []
        self.l_vals = []
        self._c_it = 0
        self.ccl = []
        self.iput = []
        self.sp = []

        self._kt_list = []
        self._dt_list = []
        self._ipt_list = []

        self._k_timing = ["0", "0", "0"]
        self._dot_timing = "0"
        self.ip_time = 0

        self._stall_iter = 0
        self._window_keep = self.nfe_t + 2

        self._u_plant = {}  #: key: (ui, time)
        for i in self.u:
            u = getattr(self.d1, i)
            for t in range(0, self._window_keep):
                self._u_plant[(i, t)] = value(u[1])
        self.curr_u = dict.fromkeys(self.u, 0.0)

        self.state_vars = {}
        self.curr_estate = {}  #: Current estimated state (for the olnmpc)
        self.curr_rstate = {}  #: Current real state (for the olnmpc)

        self.curr_state_offset = {}  #: Current offset of measurement
        self.curr_pstate = {}  #: Current offset of measurement
        self.curr_state_noise = {}  #: Current noise of the state

        self.curr_state_target = {}  #: Current target state
        self.curr_u_target = {}  #: Current control state

        self.xp_l = []
        self.xp_key = {}

        with open("ipopt.opt", "w") as f:
            f.close()
示例#25
0
    def __init__(self, **kwargs):
        NmpcGen.__init__(self, **kwargs)
        self.int_file_mhe_suf = int(time.time())-1

        # Need a list of relevant measurements y

        self.y = kwargs.pop('y', [])
        self.y_vars = kwargs.pop('y_vars', {})

        # Need a list or relevant noisy-states z

        self.x_noisy = kwargs.pop('x_noisy', [])
        self.x_vars = kwargs.pop('x_vars', {})
        self.deact_ics = kwargs.pop('del_ics', True)
        self.diag_Q_R = kwargs.pop('diag_QR', True)  #: By default use diagonal matrices for Q and R matrices
        self.u = kwargs.pop('u', [])
        self.IgnoreProcessNoise = kwargs.pop('IgnoreProcessNoise', False)


        print("-" * 120)
        print("I[[create_lsmhe]] lsmhe (full) model created.")
        print("-" * 120)
        nstates = sum(len(self.x_vars[x]) for x in self.x_noisy)

        self.journalizer("I", self._c_it, "MHE with \t", str(nstates) + "states")
        self.journalizer("I", self._c_it, "MHE with \t", str(nstates*self.nfe_t*self.ncp_t) + "noise vars")
        self.lsmhe = self.d_mod(self.nfe_t, self.ncp_t, _t=self._t)
        self.lsmhe.name = "LSMHE (Least-Squares MHE)"
        self.lsmhe.create_bounds()
        #: create x_pi constraint

        #: Create list of noisy-states vars
        self.xkN_l = []
        self.xkN_nexcl = []
        self.xkN_key = {}
        k = 0
        for x in self.x_noisy:
            n_s = getattr(self.lsmhe, x)  #: Noisy-state
            for jth in self.x_vars[x]:  #: the jth variable
                self.xkN_l.append(n_s[(1, 0) + jth])
                self.xkN_nexcl.append(1)  #: non-exclusion list for active bounds
                self.xkN_key[(x, jth)] = k
                k += 1

        self.lsmhe.xkNk_mhe = Set(initialize=[i for i in range(0, len(self.xkN_l))])  #: Create set of noisy_states
        self.lsmhe.x_0_mhe = Param(self.lsmhe.xkNk_mhe, initialize=0.0, mutable=True)  #: Prior-state
        self.lsmhe.wk_mhe = Param(self.lsmhe.fe_t, self.lsmhe.cp_ta, self.lsmhe.xkNk_mhe, initialize=0.0) \
            if self.IgnoreProcessNoise else Expression(self.lsmhe.fe_t, self.lsmhe.cp_ta, self.lsmhe.xkNk_mhe)  #: Model disturbance
        self.lsmhe.PikN_mhe = Param(self.lsmhe.xkNk_mhe, self.lsmhe.xkNk_mhe,
                                initialize=lambda m, i, ii: 1. if i == ii else 0.0, mutable=True)  #: Prior-Covariance
        self.lsmhe.Q_mhe = Param(range(1, self.nfe_t), self.lsmhe.xkNk_mhe, initialize=1, mutable=True) if self.diag_Q_R\
            else Param(range(1, self.nfe_t), self.lsmhe.xkNk_mhe, self.lsmhe.xkNk_mhe,
                             initialize=lambda m, t, i, ii: 1. if i == ii else 0.0, mutable=True)  #: Disturbance-weight
        j = 0
        for i in self.x_noisy:
            de_exp = getattr(self.lsmhe, "de_" + i)
            for k in self.x_vars[i]:
                for tfe in range(1, self.nfe_t+1):
                    for tcp in range(1, self.ncp_t + 1):
                        self.lsmhe.wk_mhe[tfe, tcp, j].set_value(de_exp[(tfe, tcp) + k]._body)
                        de_exp[(tfe, tcp) + k].deactivate()
                j += 1



        #: Create list of measurements vars
        self.yk_l = {}
        self.yk_key = {}
        k = 0
        self.yk_l[1] = []
        for y in self.y:
            m_v = getattr(self.lsmhe, y)  #: Measured "state"
            for jth in self.y_vars[y]:  #: the jth variable
                self.yk_l[1].append(m_v[(1, self.ncp_t) + jth])
                self.yk_key[(y, jth)] = k  #: The key needs to be created only once, that is why the loop was split
                k += 1

        for t in range(2, self.nfe_t + 1):
            self.yk_l[t] = []
            for y in self.y:
                m_v = getattr(self.lsmhe, y)  #: Measured "state"
                for jth in self.y_vars[y]:  #: the jth variable
                    self.yk_l[t].append(m_v[(t, self.ncp_t) + jth])

        self.lsmhe.ykk_mhe = Set(initialize=[i for i in range(0, len(self.yk_l[1]))])  #: Create set of measured_vars
        self.lsmhe.nuk_mhe = Var(self.lsmhe.fe_t, self.lsmhe.ykk_mhe, initialize=0.0)   #: Measurement noise
        self.lsmhe.yk0_mhe = Param(self.lsmhe.fe_t, self.lsmhe.ykk_mhe, initialize=1.0, mutable=True)
        self.lsmhe.hyk_c_mhe = Constraint(self.lsmhe.fe_t, self.lsmhe.ykk_mhe,
                                          rule=
                                          lambda mod, t, i:mod.yk0_mhe[t, i] - self.yk_l[t][i] - mod.nuk_mhe[t, i] == 0.0)
        self.lsmhe.hyk_c_mhe.deactivate()
        self.lsmhe.R_mhe = Param(self.lsmhe.fe_t, self.lsmhe.ykk_mhe, initialize=1.0, mutable=True) if self.diag_Q_R else \
            Param(self.lsmhe.fe_t, self.lsmhe.ykk_mhe, self.lsmhe.ykk_mhe,
                             initialize=lambda mod, t, i, ii: 1.0 if i == ii else 0.0, mutable=True)
        f = open("file_cv.txt", "w")
        f.close()

        #: Constraints for the input noise
        for u in self.u:
            # cv = getattr(self.lsmhe, u)  #: Get the param
            # c_val = [value(cv[i]) for i in cv.keys()]  #: Current value
            # self.lsmhe.del_component(cv)  #: Delete the param
            # self.lsmhe.add_component(u + "_mhe", Var(self.lsmhe.fe_t, initialize=lambda m, i: c_val[i-1]))
            self.lsmhe.add_component("w_" + u + "_mhe", Var(self.lsmhe.fe_t, initialize=0.0))  #: Noise for input
            self.lsmhe.add_component("w_" + u + "c_mhe", Constraint(self.lsmhe.fe_t))
            self.lsmhe.equalize_u(direction="r_to_u")
            # cc = getattr(self.lsmhe, u + "_c")  #: Get the constraint for input
            con_w = getattr(self.lsmhe, "w_" + u + "c_mhe")  #: Get the constraint-noisy
            var_w = getattr(self.lsmhe, "w_" + u + "_mhe")  #: Get the constraint-noisy
            ce = getattr(self.lsmhe, u + "_e")  #: Get the expression
            cp = getattr(self.lsmhe, u)  #: Get the param

            con_w.rule = lambda m, i: cp[i] == ce[i] + var_w[i]
            con_w.reconstruct()
            con_w.deactivate()

            # con_w.rule = lambda m, i: cp[i] == cv[i] + var_w[i]
            # con_w.reconstruct()
            # with open("file_cv.txt", "a") as f:
            #     cc.pprint(ostream=f)
            #     con_w.pprint(ostream=f)
                # f.close()

        self.lsmhe.U_mhe = Param(range(1, self.nfe_t + 1), self.u, initialize=1, mutable=True)

        #: Deactivate icc constraints
        if self.deact_ics:
            pass
            # for i in self.states:
            #     self.lsmhe.del_component(i + "_icc")
        #: Maybe only for a subset of the states
        else:
            for i in self.states:
                if i in self.x_noisy:
                    ic_con = getattr(self.lsmhe, i + "_icc")
                    for k in self.x_vars[i]:
                        ic_con[k].deactivate()

        #: Put the noise in the continuation equations (finite-element)
        j = 0
        self.lsmhe.noisy_cont = ConstraintList()
        for i in self.x_noisy:
            # cp_con = getattr(self.lsmhe, "cp_" + i)
            cp_exp = getattr(self.lsmhe, "noisy_" + i)
            # self.lsmhe.del_component(cp_con)
            for k in self.x_vars[i]:  #: This should keep the same order
                for t in range(1, self.nfe_t):
                    self.lsmhe.noisy_cont.add(cp_exp[t, k] == 0.0)
                    # self.lsmhe.noisy_cont.add(cp_exp[t, k] == 0.0)
                j += 1
            # cp_con.reconstruct()
        j = 0
        self.lsmhe.noisy_cont.deactivate()

        #: Expressions for the objective function (least-squares)
        self.lsmhe.Q_e_mhe = 0.0 if self.IgnoreProcessNoise else Expression(
            expr=0.5 * sum(
                sum(
                    sum(self.lsmhe.Q_mhe[1, k] * self.lsmhe.wk_mhe[i, j, k]**2 for k in self.lsmhe.xkNk_mhe) for j in range(1, self.ncp_t +1))
                for i in range(1, self.nfe_t+1))) if self.diag_Q_R else Expression(
            expr=sum(sum(self.lsmhe.wk_mhe[i, j] *
                         sum(self.lsmhe.Q_mhe[i, j, k] * self.lsmhe.wk_mhe[i, 1, k] for k in self.lsmhe.xkNk_mhe)
                         for j in self.lsmhe.xkNk_mhe) for i in range(1, self.nfe_t)))

        self.lsmhe.R_e_mhe = Expression(
            expr=0.5 * sum(
                sum(
                    self.lsmhe.R_mhe[i, k] * self.lsmhe.nuk_mhe[i, k]**2 for k in self.lsmhe.ykk_mhe)
                for i in self.lsmhe.fe_t)) if self.diag_Q_R else Expression(
            expr=sum(sum(self.lsmhe.nuk_mhe[i, j] *
                         sum(self.lsmhe.R_mhe[i, j, k] * self.lsmhe.nuk_mhe[i, k] for k in self.lsmhe.ykk_mhe)
                         for j in self.lsmhe.ykk_mhe) for i in self.lsmhe.fe_t))
        expr_u_obf = 0
        for i in self.lsmhe.fe_t:
            for u in self.u:
                var_w = getattr(self.lsmhe, "w_" + u + "_mhe")  #: Get the constraint-noisy
                expr_u_obf += self.lsmhe.U_mhe[i, u] * var_w[i] ** 2

        self.lsmhe.U_e_mhe = Expression(expr=0.5 * expr_u_obf)  # how about this
        # with open("file_cv.txt", "a") as f:
        #     self.lsmhe.U_e_mhe.pprint(ostream=f)
        #     f.close()

        self.lsmhe.Arrival_e_mhe = Expression(
            expr=0.5 * sum((self.xkN_l[j] - self.lsmhe.x_0_mhe[j]) *
                     sum(self.lsmhe.PikN_mhe[j, k] * (self.xkN_l[k] - self.lsmhe.x_0_mhe[k]) for k in self.lsmhe.xkNk_mhe)
                     for j in self.lsmhe.xkNk_mhe))

        self.lsmhe.Arrival_dummy_e_mhe = Expression(
            expr=100000.0 * sum((self.xkN_l[j] - self.lsmhe.x_0_mhe[j]) ** 2 for j in self.lsmhe.xkNk_mhe))

        self.lsmhe.obfun_dum_mhe_deb = Objective(sense=minimize,
                                             expr=self.lsmhe.Q_e_mhe)
        self.lsmhe.obfun_dum_mhe = Objective(sense=minimize,
                                             expr=self.lsmhe.R_e_mhe + self.lsmhe.Q_e_mhe + self.lsmhe.U_e_mhe) # no arrival
        self.lsmhe.obfun_dum_mhe.deactivate()

        self.lsmhe.obfun_mhe_first = Objective(sense=minimize,
                                         expr=self.lsmhe.Arrival_dummy_e_mhe + self.lsmhe.Q_e_mhe)
        self.lsmhe.obfun_mhe_first.deactivate()


        self.lsmhe.obfun_mhe = Objective(sense=minimize,
                                         expr=self.lsmhe.Arrival_dummy_e_mhe + self.lsmhe.R_e_mhe + self.lsmhe.Q_e_mhe + self.lsmhe.U_e_mhe)
        self.lsmhe.obfun_mhe.deactivate()

        # with open("file_cv.txt", "a") as f:
        #     self.lsmhe.obfun_mhe.pprint(ostream=f)
        #     f.close()

        self._PI = {}  #: Container of the KKT matrix
        self.xreal_W = {}
        self.curr_m_noise = {}   #: Current measurement noise
        self.curr_y_offset = {}  #: Current offset of measurement
        for y in self.y:
            for j in self.y_vars[y]:
                self.curr_m_noise[(y, j)] = 0.0
                self.curr_y_offset[(y, j)] = 0.0

        self.s_estimate = {}
        self.s_real = {}
        for x in self.x_noisy:
            self.s_estimate[x] = []
            self.s_real[x] = []

        self.y_estimate = {}
        self.y_real = {}
        self.y_noise_jrnl = {}
        self.yk0_jrnl = {}
        for y in self.y:
            self.y_estimate[y] = []
            self.y_real[y] = []
            self.y_noise_jrnl[y] = []
            self.yk0_jrnl[y] = []
示例#26
0
    def create_nmpc(self, **kwargs):
        kwargs.pop("newnfe", self.nfe_tnmpc)
        kwargs.pop("newncp", self.ncp_tnmpc)
        self.journalist('W', self._iteration_count, "Initializing NMPC",
                        "With {:d} fe and {:d} cp".format(self.nfe_tnmpc, self.ncp_tnmpc))
        _tnmpc = self.hi_t * self.nfe_tnmpc
        self.olnmpc = self.d_mod(self.nfe_tnmpc, self.ncp_tnmpc, _t=_tnmpc)
        self.olnmpc.name = "olnmpc (Open-Loop NMPC)"
        self.olnmpc.create_bounds()

        for u in self.u:
            cv = getattr(self.olnmpc, u)  #: Get the param
            c_val = [value(cv[i]) for i in cv.keys()]  #: Current value
            self.olnmpc.del_component(cv)  #: Delete the param
            self.olnmpc.add_component(u, Var(self.olnmpc.fe_t, initialize=lambda m, i: c_val[i-1]))
            self.olnmpc.equalize_u(direction="r_to_u")
            cc = getattr(self.olnmpc, u + "_c")  #: Get the constraint
            ce = getattr(self.olnmpc, u + "_e")  #: Get the expression
            cv = getattr(self.olnmpc, u)  #: Get the new variable
            for k in cv.keys():
                cv[k].setlb(self.u_bounds[u][0])
                cv[k].setub(self.u_bounds[u][1])
            cc.clear()
            cc.rule = lambda m, i: cv[i] == ce[i]
            cc.reconstruct()
        #: Dictionary of the states for a particular time point i
        self.xmpc_l = {}
        #: Dictionary of the position for a state in the dictionary
        self.xmpc_key = {}
        #:
        self.xmpc_l[0] = []
        #: First build the name dictionary
        k = 0
        for x in self.states:
            n_s = getattr(self.olnmpc, x)  #: State
            for j in self.state_vars[x]:
                self.xmpc_l[0].append(n_s[(0, self.ncp_tnmpc) + j])
                self.xmpc_key[(x, j)] = k
                k += 1
        #: Iterate over the rest
        for t in range(1, self.nfe_tnmpc):
            self.xmpc_l[t] = []
            for x in self.states:
                n_s = getattr(self.olnmpc, x)  #: State
                for j in self.state_vars[x]:
                    self.xmpc_l[t].append(n_s[(t, self.ncp_tnmpc) + j])
        #: A set with the length of flattened states
        self.olnmpc.xmpcS_nmpc = Set(initialize=[i for i in range(0, len(self.xmpc_l[0]))])
        #: Create set of noisy_states
        self.olnmpc.xmpc_ref_nmpc = Param(self.olnmpc.xmpcS_nmpc, initialize=0.0, mutable=True)  #: Ref-state
        self.olnmpc.Q_nmpc = Param(self.olnmpc.xmpcS_nmpc, initialize=1, mutable=True)  #: Control-weight
        # (diagonal Matrices)

        self.olnmpc.Q_w_nmpc = Param(self.olnmpc.fe_t, initialize=1e-04, mutable=True)
        self.olnmpc.R_w_nmpc = Param(self.olnmpc.fe_t, initialize=1e+02, mutable=True)
        #: Build the xT*Q*x part
        self.olnmpc.xQ_expr_nmpc = Expression(expr=sum(
            sum(self.olnmpc.Q_w_nmpc[fe] *
                self.olnmpc.Q_nmpc[k] * (self.xmpc_l[fe][k] - self.olnmpc.xmpc_ref_nmpc[k])**2
                for k in self.olnmpc.xmpcS_nmpc)
                for fe in range(0, self.nfe_tnmpc)))

        #: Build the control list
        self.umpc_l = {}
        for t in range(0, self.nfe_tnmpc):
            self.umpc_l[t] = []
            for u in self.u:
                uvar = getattr(self.olnmpc, u)
                self.umpc_l[t].append(uvar[t])
        #: Create set of u
        self.olnmpc.umpcS_nmpc = Set(initialize=[i for i in range(0, len(self.umpc_l[0]))])
        #: ref u
        self.olnmpc.umpc_ref_nmpc = Param(self.olnmpc.umpcS_nmpc, initialize=0.0, mutable=True)
        self.olnmpc.R_nmpc = Param(self.olnmpc.umpcS_nmpc, initialize=1, mutable=True)  #: Control-weight
        #: Build the uT * R * u expression
        self.olnmpc.xR_expr_nmpc = Expression(expr=sum(
            sum(self.olnmpc.R_w_nmpc[fe] *
                self.olnmpc.R_nmpc[k] * (self.umpc_l[fe][k] - self.olnmpc.umpc_ref_nmpc[k]) ** 2 for k in
                self.olnmpc.umpcS_nmpc)
            for fe in range(0, self.nfe_tnmpc)))
        self.olnmpc.objfun_nmpc = Objective(expr=self.olnmpc.xQ_expr_nmpc + self.olnmpc.xR_expr_nmpc)
示例#27
0
def set_testl(market_instances_list, airport_list, market_data,
              segment_travel_time, time_zone_dict, iti_dict, fleet_data,
              passeger_type_dict, attr_value, marketpt_attr_sum, solver):
    """
    很多输入变量都是字典,就是为了在模型中生成子集的时候有筛选功能 即 if dict【m】 in dict 
    :param airport_list: 
    :param market_data: 
    :param segment_travel_time: 
    :param iti_dict:itinerary number key ,info value :{0: {'market': "M('SEA', 'LAX')", 'non_stop': ('SEA', 'LAX'), ('SEA', 'LAX'): 1, 'legs': [('SEA', 'LAX')]}
    :param fleet_data: 
    :param passeger_type_dict: passenger_type as key , and it's proportions
    :param attr_value: 
    :param marketpt_attr_sum: 
    :param solver: 
    :return: time_table, q_variable for each itinerary, 
    """
    market_iti = {}  #market:itinerary list
    for m in market_instances_list:
        l = [
            i for i, v in iti_dict.items()
            if v['market'] == 'M' + str(m.od_pair)
        ]
        market_iti.update({m: l})
    model = ConcreteModel()
    market = list(market_data.keys())  #['M' + str(m.od_pair) for m in ]
    # market_segment={m:[(market_data[m][4],market_data[m][5])] for m in market_data.keys()}
    model.M = Set(initialize=market, doc='Player Market_obj')
    model.Mi = Set(list(market_iti.keys()),
                   initialize=market_iti,
                   doc='Player Market_obj')
    model.AP = Set(initialize=airport_list)
    model.Segment = Set(initialize=((i, j) for i in model.AP for j in model.AP
                                    if i != j))

    # create time spot [1-72] and it's time
    a = np.linspace(1, int((1440 - 360) / 15), int((1440 - 360) / 15))
    time_list = np.arange(360, 1440, 15)
    time_dict = dict(zip(a, time_list))
    # reverse_time_dict = {v: k for k, v in time_dict.items()}
    model.T = Set(
        initialize=a,
        ordered=True,
        doc='Time period from 300 min to 1440 ,step :15min,number:73')
    model.I = Set(initialize=iti_dict.keys(), doc='itinerary _index,size 4334')
    model.Im = Set(initialize=((m, i) for m in model.M for i in market_iti[m]),
                   doc='tuple(m,i),size 4334')  # 筛选出只在m的itinerary 的 号码
    model.PT = Set(initialize=passeger_type_dict.keys())
    model.F = Set(initialize=fleet_data.keys())
    d = {}  #create a dict as which OD and time get all itinerary_index in it
    for ap1, ap2 in model.Segment:
        for t in model.T:
            v = []
            for i, va in iti_dict.items():
                if (ap1, ap2) in va['legs'] and t == va[(ap1, ap2)]:
                    v.append(i)
            d[(ap1, ap2, t)] = v
    model.St = Set(
        list(d.keys()),
        initialize=d)  # index as (ap1,ap2,time) get [itinerary index list]

    def _filter3(model, i, m, ap1, ap2, t):

        return i in model.Mi[m].value and i in model.St[(ap1, ap2, t)].value

    # def Parameters
    demand_pt = {
    }  # get demand of pt in the market by total demand times its proportion
    print("passenger_type_proportion:", passeger_type_dict)
    for m, va in market_data.items():
        for ty, rato in passeger_type_dict.items():
            demand_pt.update({(m, ty):
                              va[0] * rato})  # market demand times proportions
    model.Dem = Param(model.M,
                      model.PT,
                      initialize=demand_pt,
                      doc='Market demand for each type of passenger')

    price_dict = {}
    for i in model.I:
        rato = np.linspace(1.3, 0.7, len(passeger_type_dict))
        for index, ty in enumerate(passeger_type_dict):
            if iti_dict[i]['non_stop']:
                price_dict.update({
                    (i, ty):
                    market_data[iti_dict[i]['market']][2] * rato[index]
                })  # market_data[m][2] is price
            else:
                price_dict.update({
                    (i, ty):
                    0.8 * market_data[iti_dict[i]['market']][2] * rato[index]
                })  # market_data[m][2] is price
    model.p = Param(model.I, model.PT, initialize=price_dict)
    model.Avail = Param(
        model.F,
        initialize={fleet: value[0]
                    for fleet, value in fleet_data.items()})
    model.Cap = Param(
        model.F,
        initialize={fleet: value[1]
                    for fleet, value in fleet_data.items()})
    model.distance = Param(model.Segment,
                           initialize={(value[-2], value[-1]): value[1]
                                       for value in market_data.values()})

    def ope_cost(model, ap1, ap2, f):
        if model.distance[ap1, ap2] <= 3106:
            return (1.6 * model.distance[ap1, ap2] + 722) * (model.Cap[f] +
                                                             104) * 0.019
        else:
            return (1.6 * model.distance[ap1, ap2] + 2200) * (model.Cap[f] +
                                                              211) * 0.0115

    model.Ope = Param(model.Segment, model.F, initialize=ope_cost, doc='cost')
    freq = {(market_data[m][4], market_data[m][5]): market_data[m][3]
            for m in market_data.keys()}

    model.Freq = Param(model.Segment, initialize=freq)
    model.A = Param(model.I, model.PT, initialize=attr_value)

    model.Am = Param(model.M, model.PT, initialize=marketpt_attr_sum)
    # Step 2: Define decision variables
    model.x = Var(model.Segment, model.F, model.T, within=Binary)
    model.y_1 = Var(model.F, model.AP, model.T, within=PositiveIntegers)
    model.y_2 = Var(model.F, model.AP, model.T, within=PositiveIntegers)
    model.q = Var(model.I, model.PT, within=NonNegativeReals)
    model.non_q = Var(model.M, model.PT, within=NonNegativeReals
                      )  # number of pax that choose others airine and no fly.

    # Step 3: Define Objective
    def obj_rule(model):
        return sum(model.q[i, pt] * model.p[i, pt] for i in model.I
                   for pt in model.PT) - sum(model.Ope[s, f] * model.x[s, f, t]
                                             for s in model.Segment
                                             for f in model.F for t in model.T)

    model.obj = Objective(rule=obj_rule, sense=maximize)

    def obj_cost(model):
        return sum(model.Ope[s, f] * model.x[s, f, t] for s in model.Segment
                   for f in model.F for t in model.T)

    model.obj_cost = Expression(rule=obj_cost)

    def obj_revenue(model):
        return sum(model.q[i, pt] * model.p[i, pt] for i in model.I
                   for pt in model.PT)

    model.obj_revenue = Expression(rule=obj_revenue)

    # add constraint
    # Aircraft count:
    def aircraft_con(model, f):
        return sum(model.y_1[f, ap, model.T[1]]
                   for ap in model.AP) <= model.Avail[f]

    model.count = Constraint(model.F, rule=aircraft_con)

    # flow balance cons
    def flow_balance_1(model, f, ap):
        return model.y_1[f, ap, model.T[1]] == model.y_2[f, ap, model.T[-1]]

    model.con_fb_1 = Constraint(model.F, model.AP, rule=flow_balance_1)

    def flow_balance_2(model, f, ap, t):
        # if t == model.T[-1]:
        #     return Constraint.Skip
        # else:
        return model.y_1[f, ap, t + 1] == model.y_2[f, ap, t]

    def filter2(model, t):
        return t != model.T[-1]

    model.Tm = Set(initialize=(i for i in model.T if i != model.T[-1]))
    #model.con_fb_2 = Constraint(model.F, model.AP, model.T, rule=flow_balance_2)
    model.con_fb_2 = Constraint(model.F,
                                model.AP,
                                model.Tm,
                                rule=flow_balance_2)
    # time_zone_dict={('ANC', 'PDX'): 60, ('SEA', 'PDX'): 0, ('SEA', 'ANC'): -60, ('ANC', 'LAX'): 60, ('PDX', 'SEA'): 0, ('LAX', 'PDX'): 0,
    #                 ('LAX', 'SEA'): 0, ('PDX', 'ANC'): -60, ('SEA', 'LAX'): 0, ('ANC', 'SEA'): 60, ('LAX', 'ANC'): -60, ('PDX', 'LAX'): 0}

    Travel_time = segment_travel_time

    def flow_balance_3(model, f, ap, t):
        def D(s, t, turnaround=30):
            arrival_time = time_dict[t]
            dep_time = arrival_time - (Travel_time[s] +
                                       turnaround) - time_zone_dict[s]
            if dep_time >= 360:
                t0 = ((dep_time - 360) // 15) + 1
            else:
                t0 = 72 - (abs(360 - dep_time) // 15)
            return t0

        return model.y_1[f, ap, t] + sum(
            model.x[s, f, D(s, t)]
            for s in model.Segment if s[1] == ap) == model.y_2[f, ap, t] + sum(
                model.x[s, f, t] for s in model.Segment if s[0] == ap)

    model.con_fb_3 = Constraint(model.F,
                                model.AP,
                                model.T,
                                rule=flow_balance_3)

    # Demand and capacity constrains:
    def attract_con(model, market, i, pt):
        return model.Am[market, pt] * (
            model.q[i, pt] / model.Dem[market, pt]) <= model.A[i, pt] * (
                model.non_q[market, pt] / model.Dem[market, pt])

    model.attractiveness = Constraint(model.Im, model.PT, rule=attract_con)

    def capacity_con(model, ap1, ap2, t):
        return sum(model.q[i, pt] for i in d[(ap1, ap2, t)]
                   for pt in model.PT) <= sum(
                       model.Cap[f] * model.x[ap1, ap2, f, t] for f in model.F)

    model.con_d1 = Constraint(model.Segment, model.T, rule=capacity_con)

    def demand_market_con(model, market, pt):
        return sum(model.q[i, pt] for i in model.I if iti_dict[i]['market'] == market) + model.non_q[market, pt] == \
               model.Dem[market, pt]

    model.con_d3 = Constraint(model.M, model.PT, rule=demand_market_con)

    # Itinerary selection constraints:
    model.AC = Set(initialize=model.I * model.M * model.Segment * model.T,
                   filter=_filter3)

    def iti_selection(model, i, m, ap1, ap2, t, pt):
        # if i in market_iti[m] and i in d[(ap1, ap2, t)]:
        return sum(model.x[ap1, ap2, f, t]
                   for f in model.F) >= model.q[i, pt] / model.Dem[m, pt]

    model.con_iti_selection = Constraint(model.AC,
                                         model.PT,
                                         rule=iti_selection)

    # Restrictions on fight leg variables:
    def flight_leg_con(model, ap1, ap2, t):
        return sum(model.x[ap1, ap2, f, t] for f in model.F) <= 1

    model.con_leg_1 = Constraint(model.Segment, model.T, rule=flight_leg_con)

    def freq_con(model, ap1, ap2):
        return sum(model.x[ap1, ap2, f, t] for t in model.T
                   for f in model.F) == model.Freq[ap1, ap2]

    model.con_let_2 = Constraint(model.Segment, rule=freq_con)
    print("____" * 5)
    # for con in model.component_map(Constraint).itervalues():
    #     con.pprint()

    SOLVER_NAME = solver
    TIME_LIMIT = 60 * 60 * 2
    results = SolverFactory(SOLVER_NAME)

    if SOLVER_NAME == 'cplex':
        results.options['timelimit'] = TIME_LIMIT
    elif SOLVER_NAME == 'glpk':
        results.options['tmlim'] = TIME_LIMIT
    elif SOLVER_NAME == 'gurobi':
        results.options['TimeLimit'] = TIME_LIMIT

    com = results.solve(model, tee=True)
    com.write()

    #absgap = com.solution(0).gap
    # get x results in matrix form
    df_x = pd.DataFrame(columns=list(model.Segment), index=model.T)
    for s in model.Segment:
        for t in model.T:
            for f in model.F:
                if model.x[s, f, t].value > 0:
                    df_x.loc[t, [s]] = f

    #df_x=df_x.reset_index()# return value  is a dataframe of new time table
    # 所有的决策变量都遍历一遍
    # for v in instance.component_objects(Var, active=True):
    #     print("Variable", v)
    #     varobject = getattr(instance, str(v))
    #     for index in varobject:
    #         print("   ", index, varobject[index].value)
    varobject = getattr(model, 'q')
    q_data = {(i, pt): varobject[(i, pt)].value
              for (i, pt), v in varobject.items() if varobject[(i, pt)] != 0}
    df_q = pd.DataFrame.from_dict(q_data,
                                  orient="index",
                                  columns=["variable value"])
    varobject2 = getattr(model, 'non_q')
    nonq_data = {(m, pt): varobject2[(m, pt)].value
                 for (m, pt), v in varobject2.items()
                 if varobject2[(m, pt)] != 0}

    # q = list(model.q.get_values().values())
    # print('q = ', q)
    profit = model.obj()
    print('\nProfit = ', profit)
    cost = value_s(model.obj_cost())
    #revenue=value_s(model.obj_revenue())
    print('cost is:' * 10, cost)
    #print('revenue is:' * 10, revenue)
    '''
    print('\nDecision Variables')
    #list_of_vars = [v.value for v in model.component_objects(ctype=Var, active=True, descend_into=True)]
    #var_names = [v.name for v in model.component_objects(ctype=Var, active=True, descend_into=True) if v.value!=0]

    # print("y=",y)
    model.obj.display()

    def pyomo_postprocess( options=None, instance=None, results=None ):
        model.x.display()

    pyomo_postprocess(None, model, results)
    for v in model.component_objects(Var, active=True):
        print("Variable component object", v)
        varobject = getattr(model, str(v))
        for index in varobject:
            if varobject[index].value != 0:
                print("   ", index, varobject[index].value)
    '''
    return df_x, q_data, profit, cost, nonq_data
示例#28
0
def ROSolver_iterative_solve(model_data, config):
    '''
    GRCS algorithm implementation
    :model_data: ROSolveData object with deterministic model information
    :config: ConfigBlock for the instance being solved
    '''

    # === The "violation" e.g. uncertain parameter values added to the master problem are nominal in iteration 0
    #     User can supply a nominal_uncertain_param_vals if they want to set nominal to a certain point,
    #     Otherwise, the default init value for the params is used as nominal_uncertain_param_vals
    violation = list(p for p in config.nominal_uncertain_param_vals)

    # === Do coefficient matching
    constraints = [
        c for c in model_data.working_model.component_data_objects(Constraint)
        if c.equality and c not in ComponentSet(
            model_data.working_model.util.decision_rule_eqns)
    ]
    model_data.working_model.util.h_x_q_constraints = ComponentSet()
    for c in constraints:
        coeff_matching_success, robust_infeasible = coefficient_matching(
            model=model_data.working_model,
            constraint=c,
            uncertain_params=model_data.working_model.util.uncertain_params,
            config=config)
        if not coeff_matching_success and not robust_infeasible:
            raise ValueError(
                "Equality constraint \"%s\" cannot be guaranteed to be robustly feasible, "
                "given the current partitioning between first-stage, second-stage and state variables. "
                "You might consider editing this constraint to reference some second-stage "
                "and/or state variable(s)." % c.name)
        elif not coeff_matching_success and robust_infeasible:
            config.progress_logger.info(
                "PyROS has determined that the model is robust infeasible. "
                "One reason for this is that equality constraint \"%s\" cannot be satisfied "
                "against all realizations of uncertainty, "
                "given the current partitioning between first-stage, second-stage and state variables. "
                "You might consider editing this constraint to reference some (additional) second-stage "
                "and/or state variable(s)." % c.name)
            return None, None
        else:
            pass

    # h(x,q) == 0 becomes h'(x) == 0
    for c in model_data.working_model.util.h_x_q_constraints:
        c.deactivate()

    # === Build the master problem and master problem data container object
    master_data = master_problem_methods.initial_construct_master(model_data)

    # === If using p_robustness, add ConstraintList for additional constraints
    if config.p_robustness:
        master_data.master_model.p_robust_constraints = ConstraintList()

    # === Add scenario_0
    master_data.master_model.scenarios[0, 0].transfer_attributes_from(
        master_data.original.clone())
    if len(master_data.master_model.scenarios[
            0, 0].util.uncertain_params) != len(violation):
        raise ValueError

    # === Set the nominal uncertain parameters to the violation values
    for i, v in enumerate(violation):
        master_data.master_model.scenarios[
            0, 0].util.uncertain_params[i].value = v

    # === Add objective function (assuming minimization of costs) with nominal second-stage costs
    if config.objective_focus is ObjectiveType.nominal:
        master_data.master_model.obj = Objective(
            expr=master_data.master_model.scenarios[0,
                                                    0].first_stage_objective +
            master_data.master_model.scenarios[0, 0].second_stage_objective)
    elif config.objective_focus is ObjectiveType.worst_case:
        # === Worst-case cost objective
        master_data.master_model.zeta = Var(initialize=value(
            master_data.master_model.scenarios[0, 0].first_stage_objective +
            master_data.master_model.scenarios[0, 0].second_stage_objective))
        master_data.master_model.obj = Objective(
            expr=master_data.master_model.zeta)
        master_data.master_model.scenarios[0, 0].epigraph_constr = Constraint(
            expr=master_data.master_model.scenarios[0,
                                                    0].first_stage_objective +
            master_data.master_model.scenarios[0, 0].second_stage_objective <=
            master_data.master_model.zeta)
        master_data.master_model.scenarios[
            0,
            0].util.first_stage_variables.append(master_data.master_model.zeta)

    # === Add deterministic constraints to ComponentSet on original so that these become part of separation model
    master_data.original.util.deterministic_constraints = \
        ComponentSet(c for c in master_data.original.component_data_objects(Constraint, descend_into=True))

    # === Make separation problem model once before entering the solve loop
    separation_model = separation_problem_methods.make_separation_problem(
        model_data=master_data, config=config)

    # === Create separation problem data container object and add information to catalog during solve
    separation_data = SeparationProblemData()
    separation_data.separation_model = separation_model
    separation_data.points_separated = [
    ]  # contains last point separated in the separation problem
    separation_data.points_added_to_master = [
        config.nominal_uncertain_param_vals
    ]  # explicitly robust against in master
    separation_data.constraint_violations = [
    ]  # list of constraint violations for each iteration
    separation_data.total_global_separation_solves = 0  # number of times global solve is used
    separation_data.timing = master_data.timing  # timing object

    # === Keep track of subsolver termination statuses from each iteration
    separation_data.separation_problem_subsolver_statuses = []

    # === Nominal information
    nominal_data = Block()
    nominal_data.nom_fsv_vals = []
    nominal_data.nom_ssv_vals = []
    nominal_data.nom_first_stage_cost = 0
    nominal_data.nom_second_stage_cost = 0
    nominal_data.nom_obj = 0

    # === Time information
    timing_data = Block()
    timing_data.total_master_solve_time = 0
    timing_data.total_separation_local_time = 0
    timing_data.total_separation_global_time = 0
    timing_data.total_dr_polish_time = 0

    dr_var_lists_original = []
    dr_var_lists_polished = []

    k = 0
    while config.max_iter == -1 or k < config.max_iter:
        master_data.iteration = k

        # === Add p-robust constraint if iteration > 0
        if k > 0 and config.p_robustness:
            master_problem_methods.add_p_robust_constraint(
                model_data=master_data, config=config)

        # === Solve Master Problem
        config.progress_logger.info("PyROS working on iteration %s..." % k)
        master_soln = master_problem_methods.solve_master(
            model_data=master_data, config=config)
        #config.progress_logger.info("Done solving Master Problem!")
        master_soln.master_problem_subsolver_statuses = []

        # === Keep track of total time and subsolver termination conditions
        timing_data.total_master_solve_time += get_time_from_solver(
            master_soln.results)
        timing_data.total_master_solve_time += get_time_from_solver(
            master_soln.feasibility_problem_results)

        master_soln.master_problem_subsolver_statuses.append(
            master_soln.results.solver.termination_condition)

        # === Check for robust infeasibility or error or time-out in master problem solve
        if master_soln.master_subsolver_results[
                1] is pyrosTerminationCondition.robust_infeasible:
            term_cond = pyrosTerminationCondition.robust_infeasible
            output_logger(config=config, robust_infeasible=True)
        elif master_soln.pyros_termination_condition is pyrosTerminationCondition.subsolver_error:
            term_cond = pyrosTerminationCondition.subsolver_error
        else:
            term_cond = None
        if term_cond == pyrosTerminationCondition.subsolver_error or \
                term_cond == pyrosTerminationCondition.robust_infeasible:
            update_grcs_solve_data(pyros_soln=model_data,
                                   k=k,
                                   term_cond=term_cond,
                                   nominal_data=nominal_data,
                                   timing_data=timing_data,
                                   separation_data=separation_data,
                                   master_soln=master_soln)
            return model_data, []
        # === Check if time limit reached
        elapsed = get_main_elapsed_time(model_data.timing)
        if config.time_limit:
            if elapsed >= config.time_limit:
                output_logger(config=config, time_out=True, elapsed=elapsed)
                update_grcs_solve_data(
                    pyros_soln=model_data,
                    k=k,
                    term_cond=pyrosTerminationCondition.time_out,
                    nominal_data=nominal_data,
                    timing_data=timing_data,
                    separation_data=separation_data,
                    master_soln=master_soln)
                return model_data, []

        # === Save nominal information
        if k == 0:
            for val in master_soln.fsv_vals:
                nominal_data.nom_fsv_vals.append(val)

            for val in master_soln.ssv_vals:
                nominal_data.nom_ssv_vals.append(val)

            nominal_data.nom_first_stage_cost = master_soln.first_stage_objective
            nominal_data.nom_second_stage_cost = master_soln.second_stage_objective
            nominal_data.nom_obj = value(master_data.master_model.obj)

        if (
                # === Decision rule polishing (do not polish on first iteration if no ssv or if decision_rule_order = 0)
            (config.decision_rule_order != 0
             and len(config.second_stage_variables) > 0 and k != 0)):
            # === Save initial values of DR vars to file
            for varslist in master_data.master_model.scenarios[
                    0, 0].util.decision_rule_vars:
                vals = []
                for dvar in varslist.values():
                    vals.append(dvar.value)
                dr_var_lists_original.append(vals)

            polishing_results = master_problem_methods.minimize_dr_vars(
                model_data=master_data, config=config)
            timing_data.total_dr_polish_time += get_time_from_solver(
                polishing_results)

            #=== Save after polish
            for varslist in master_data.master_model.scenarios[
                    0, 0].util.decision_rule_vars:
                vals = []
                for dvar in varslist.values():
                    vals.append(dvar.value)
                dr_var_lists_polished.append(vals)

        # === Set up for the separation problem
        separation_data.opt_fsv_vals = [
            v.value for v in master_soln.master_model.scenarios[
                0, 0].util.first_stage_variables
        ]
        separation_data.opt_ssv_vals = master_soln.ssv_vals

        # === Provide master model scenarios to separation problem for initialization options
        separation_data.master_scenarios = master_data.master_model.scenarios

        if config.objective_focus is ObjectiveType.worst_case:
            separation_model.util.zeta = value(master_soln.master_model.obj)

        # === Solve Separation Problem
        separation_data.iteration = k
        separation_data.master_nominal_scenario = master_data.master_model.scenarios[
            0, 0]

        separation_data.master_model = master_data.master_model

        separation_solns, violating_realizations, constr_violations, is_global, \
            local_sep_time, global_sep_time = \
                separation_problem_methods.solve_separation_problem(model_data=separation_data, config=config)

        for sep_soln_list in separation_solns:
            for s in sep_soln_list:
                separation_data.separation_problem_subsolver_statuses.append(
                    s.termination_condition)

        if is_global:
            separation_data.total_global_separation_solves += 1

        timing_data.total_separation_local_time += local_sep_time
        timing_data.total_separation_global_time += global_sep_time

        separation_data.constraint_violations.append(constr_violations)

        if not any(s.found_violation for solve_data_list in separation_solns
                   for s in solve_data_list):
            separation_data.points_separated = []
        else:
            separation_data.points_separated = violating_realizations

        # === Check if time limit reached
        elapsed = get_main_elapsed_time(model_data.timing)
        if config.time_limit:
            if elapsed >= config.time_limit:
                output_logger(config=config, time_out=True, elapsed=elapsed)
                termination_condition = pyrosTerminationCondition.time_out
                update_grcs_solve_data(pyros_soln=model_data,
                                       k=k,
                                       term_cond=termination_condition,
                                       nominal_data=nominal_data,
                                       timing_data=timing_data,
                                       separation_data=separation_data,
                                       master_soln=master_soln)
                return model_data, separation_solns

        # === Check if we exit due to solver returning unsatisfactory statuses (not in permitted_termination_conditions)
        local_solve_term_conditions = {
            TerminationCondition.optimal, TerminationCondition.locallyOptimal,
            TerminationCondition.globallyOptimal
        }
        global_solve_term_conditions = {
            TerminationCondition.optimal, TerminationCondition.globallyOptimal
        }
        if (is_global and any((s.termination_condition not in global_solve_term_conditions)
                                  for sep_soln_list in separation_solns for s in sep_soln_list)) or \
            (not is_global and any((s.termination_condition not in local_solve_term_conditions)
                                  for sep_soln_list in separation_solns for s in sep_soln_list)):
            termination_condition = pyrosTerminationCondition.subsolver_error
            update_grcs_solve_data(pyros_soln=model_data,
                                   k=k,
                                   term_cond=termination_condition,
                                   nominal_data=nominal_data,
                                   timing_data=timing_data,
                                   separation_data=separation_data,
                                   master_soln=master_soln)
            return model_data, separation_solns

        # === Check if we terminate due to robust optimality or feasibility
        if not any(s.found_violation for sep_soln_list in separation_solns
                   for s in sep_soln_list) and is_global:
            if config.solve_master_globally and config.objective_focus is ObjectiveType.worst_case:
                output_logger(config=config, robust_optimal=True)
                termination_condition = pyrosTerminationCondition.robust_optimal
            else:
                output_logger(config=config, robust_feasible=True)
                termination_condition = pyrosTerminationCondition.robust_feasible
            update_grcs_solve_data(pyros_soln=model_data,
                                   k=k,
                                   term_cond=termination_condition,
                                   nominal_data=nominal_data,
                                   timing_data=timing_data,
                                   separation_data=separation_data,
                                   master_soln=master_soln)
            return model_data, separation_solns

        # === Add block to master at violation
        master_problem_methods.add_scenario_to_master(master_data,
                                                      violating_realizations)
        separation_data.points_added_to_master.append(violating_realizations)

        k += 1

    output_logger(config=config, max_iter=True)
    update_grcs_solve_data(pyros_soln=model_data,
                           k=k,
                           term_cond=pyrosTerminationCondition.max_iter,
                           nominal_data=nominal_data,
                           timing_data=timing_data,
                           separation_data=separation_data,
                           master_soln=master_soln)

    # === In this case we still return the final solution objects for the last iteration
    return model_data, separation_solns
示例#29
0
    def GradientsTool(self):
        self.journalizer("E", self._c_it, "GradientsTool", "Begin")
        src = self.d1
        src.dum_objfun = Objective(expr=1, sense=minimize)
        self.d1.var_order = Suffix(direction=Suffix.EXPORT)
        self.d1.con_order = Suffix(direction=Suffix.EXPORT)

        src.pprint(filename="first.txt")
        #: Fix/Deactivate irrelevant stuff
        for var in src.component_objects(Var, active=True):
            if not var.is_indexed():
                var.fix()
            for index in var.keys():
                if type(index) != tuple:
                    var.fix()
                    continue
                try:
                    if index[1] == self.ncp_t:
                        continue
                    var[index].fix()
                except IndexError:
                    var.fix()
                    print("Variable not indexed by time",
                          var.name,
                          file=sys.stderr)
        for con in src.component_objects(Constraint, active=True):
            if not con.is_indexed():
                con.deactivate()
            for index in con.keys():
                if type(index) != tuple:
                    con.deactivate()
                    continue
                try:
                    if index[1] == self.ncp_t:
                        continue
                    con[index].deactivate()
                except IndexError:
                    con.deactivate()
                    print("Constraint not indexed by time",
                          con.name,
                          file=sys.stderr)

        for i in self.states:  #: deactivate collocation related equations
            # con = getattr(src, "cp_" + i)  #: continuation
            # con.deactivate()
            con = getattr(src, "dvar_t_" + i)  #: derivative vars
            con.deactivate()
            con = getattr(src, i + "_icc")  #: initial-conditions
            con.deactivate()
            var = getattr(src, "d" + i + "_dt")
            var.fix()
            var = getattr(src, i)
            var.fix()  #: left with the av
            con = getattr(src, "de_" + i)  #: initial-conditions
            con.deactivate()
        # colcount = 0
        # for i in src.component_data_objects(Var, active=True):
        #     if i.is_fixed():
        #         continue
        #     print(i)
        #     colcount += 1
        #     i.set_suffix_value(src.var_order, colcount)
        # print(colcount)

        self.d1.write_nl(name="dgy.nl")
        sfxdict = dict()
        self.parse_rc("dgy.row", sfxdict)
        colcount = 1
        for ob in sfxdict.keys():
            con = getattr(src, sfxdict[ob][0])
            con[sfxdict[ob][1]].set_suffix_value(src.con_order, colcount)
            colcount += 1

        sfxdict = dict()
        self.parse_rc("dgy.col", sfxdict)
        colcount = 1
        for ob in sfxdict.keys():
            var = getattr(src, sfxdict[ob][0])
            var[sfxdict[ob][1]].set_suffix_value(src.var_order, colcount)
            colcount += 1
        print("Colcount\t", str(colcount), file=sys.stderr)
        src.write_nl(name="dgy.nl")
        #: Now dgx
        for var in src.component_objects(Var):
            var.fix()  #: Fix everything
        for i in self.states:
            var = getattr(src, i)
            for index in var.keys():
                try:
                    if index[1] == self.ncp_t:
                        var[index].unfix()
                except IndexError:
                    print("Something whent wrong :(\t",
                          var.name,
                          file=sys.stderr)

        self.d1.write_nl(name="dgx.nl")

        sfxdict = dict()
        self.parse_rc("dgx.col", sfxdict)
        colcount = 1
        for ob in sfxdict.keys():
            var = getattr(src, sfxdict[ob][0])
            var[sfxdict[ob][1]].set_suffix_value(src.var_order, colcount)
            colcount += 1
        src.write_nl(name="dgx.nl")

        #: Now dfy
        for var in src.component_objects(Var):
            var.unfix()
        for var in src.component_objects(Var):
            if not var.is_indexed():
                var.fix()
            for index in var.keys():
                if type(index) != tuple:
                    var.fix()
                    continue
                try:
                    if index[1] == self.ncp_t:
                        continue
                    var[index].fix()
                except IndexError:
                    var.fix()
                    print("Variable not indexed by time",
                          var.name,
                          file=sys.stderr)

        for con in src.component_objects(Constraint):
            con.deactivate()  #: deactivate everything

        for i in self.states:  #: deactivate collocation related terms
            var = getattr(src, "d" + i + "_dt")
            var.fix()
            var = getattr(src, i)
            var.fix()  #: left with the av
            con = getattr(src, "de_" + i)
            for index in con.keys():
                if index[1] == self.ncp_t:
                    con[index].activate()
        self.d1.reconstruct()
        # self.d1.write_nl(name="dfy.nl")

        sfxdict = dict()
        self.parse_rc("dgx.col", sfxdict)
        colcount = 1
        for ob in sfxdict.keys():
            col = getattr(src, "de_" + sfxdict[ob][0])
            col[sfxdict[ob][1]].set_suffix_value(src.con_order, colcount)
            colcount += 1
        src.write_nl(name="dfy.nl")

        #: Now dfx
        for var in src.component_objects(Var):
            var.fix()  #: Fix everything

        for i in self.states:
            var = getattr(src, i)
            for index in var.keys():
                try:
                    if index[1] == self.ncp_t:
                        var[index].unfix()
                except IndexError:
                    print("Something whent wrong :(\t",
                          var.name,
                          file=sys.stderr)
            # var.pprint()
        self.d1.reconstruct()
        src.pprint(filename="second.txt")
        self.d1.write_nl(name="dfx.nl")