Esempio n. 1
0
def pysp2_callback(scenario_name, node_names=None, cb_data=None):
    """
    mpisppy signature for scenario creation.
    Then find a starting solution for the scenario if solver option is not None.
    Note that stage numbers are one-based.

    Args:
        scenario_name (str): put the scenario number on the end 
        node_names (int): not used
        cb_data: (dict) "etree", "solver", "epath", "tee", "acstream"

    Returns:
        scenario (pyo.ConcreteModel): the scenario instance

    Attaches:
        _enodes (ACtree nodes): a list of the ACtree tree nodes
        _egret_md (egret tuple with dict as [1]) egret model data

    """
    # pull the number off the end of the scenario name
    scen_num = sputils.extract_num(scenario_name)

    etree = cb_data["etree"]
    solver = cb_data["solver"]
    acstream = cb_data["acstream"]

    # seed each scenario every time to avoid troubles
    acstream.seed(etree.seed + scen_num)

    def lines_up_and_down(stage_md_dict, enode):
        # local routine to configure the lines in stage_md_dict for the scenario
        LinesDown = []
        for f in enode.FailedLines:
            LinesDown.append(f[0])
        for this_branch in stage_md_dict.elements("branch"):
            if this_branch[0] in enode.LinesUp:
                this_branch[1]["in_service"] = True
            elif this_branch[0] in LinesDown:
                this_branch[1]["in_service"] = False
            else:
                print("enode.LinesUp=", enode.LinesUp)
                print("enode.FailedLines=", enode.FailedLines)
                raise RuntimeError("Branch (line) {} neither up nor down in scenario {}".\
                               format(this_branch[0], scenario_name))

    # pull the number off the end of the scenario name
    scen_num = sputils.extract_num(scenario_name)
    #print ("debug scen_num=",scen_num)

    numstages = etree.NumStages
    enodes = etree.Nodes_for_Scenario(scen_num)
    full_scenario_model = pyo.ConcreteModel()
    full_scenario_model.stage_models = dict()

    # the exact acopf model is hard-wired here:
    acopf_model = eac.create_riv_acopf_model

    # look at egret/data/model_data.py for the format specification of md_dict
    first_stage_md_dict = _md_dict(cb_data)
    generator_set = first_stage_md_dict.attributes("generator")
    generator_names = generator_set["names"]

    # the following creates the first stage model
    full_scenario_model.stage_models[1], model_dict = acopf_model(
        first_stage_md_dict, include_feasibility_slack=True)
    full_scenario_model.stage_models[1].obj.deactivate()
    setattr(full_scenario_model, "stage_models_" + str(1),
            full_scenario_model.stage_models[1])

    for stage in range(2, numstages + 1):
        #print ("stage={}".format(stage))

        stage_md_dict = copy.deepcopy(first_stage_md_dict)
        #print ("debug: processing node {}".format(enodes[stage-1].Name))
        lines_up_and_down(stage_md_dict, enodes[stage - 1])

        full_scenario_model.stage_models[stage], model_dict = \
            acopf_model(stage_md_dict, include_feasibility_slack=True)
        full_scenario_model.stage_models[stage].obj.deactivate()
        setattr(full_scenario_model, "stage_models_" + str(stage),
                full_scenario_model.stage_models[stage])

    def aggregate_ramping_rule(m):
        """
        We are adding ramping to the obj instead of a constraint for now
        because we may not have ramp limit data.
        """
        retval = 0
        for stage in range(1, numstages):
            retval += sum((full_scenario_model.stage_models[stage+1].pg[this_gen]\
                    - full_scenario_model.stage_models[stage].pg[this_gen])**2\
                   for this_gen in generator_names)
        return retval

    full_scenario_model.ramping = pyo.Expression(rule=aggregate_ramping_rule)

    full_scenario_model.objective = pyo.Objective(expr=\
                            1000000.0 * full_scenario_model.ramping+\
                            sum(full_scenario_model.stage_models[stage].obj.expr\
                                    for stage in range(1,numstages+1)))

    inst = full_scenario_model
    # end code from PySP1

    node_list = list()

    parent_name = None
    for sm1, enode in enumerate(etree.Nodes_for_Scenario(scen_num)):
        stage = sm1 + 1
        if stage < etree.NumStages:
            node_list.append(
                scenario_tree.ScenarioNode(
                    name=enode.Name,
                    cond_prob=enode.CondProb,
                    stage=stage,
                    cost_expression=inst.stage_models[stage].obj,
                    scen_name_list=enode.ScenarioList,
                    nonant_list=[
                        inst.stage_models[stage].pg,
                        inst.stage_models[stage].qg
                    ],
                    scen_model=inst,
                    parent_name=parent_name))
            parent_name = enode.Name

    inst._PySPnode_list = node_list
    # Optionally assign probability to PySP_prob
    inst.PySP_prob = 1 / etree.numscens
    # solve it so subsequent code will have a good start
    if solver is not None:
        solver.solve(inst)

    # attachments
    inst._enodes = enodes
    inst._egret_md = first_stage_md_dict

    return inst
Esempio n. 2
0
#Fabrica 1    c11        c12
#Fabrica 2    c21        c22
#Fabrica 3    c31        c32

#Custo de transporte da fabrica i pro cliente j
cij = [[162, 247], [117, 193], [131, 185]]

capacidades = [1000, 1500, 1200]
demandas = [2300, 1400]

m = len(capacidades)
n = len(demandas)

##-------------------------DECLARACAO DO MODELO E SEUS PARAMETROS--------------------##
#Modelo
modelo = pyEnv.ConcreteModel()
#Indice para as fabricas
modelo.I = pyEnv.RangeSet(m)
#Indice para os clientes
modelo.J = pyEnv.RangeSet(n)

#Variaveis de decisao xij
modelo.x = pyEnv.Var(modelo.I, modelo.J, within=pyEnv.NonNegativeReals)

#Custo de transporte da fabrica i pro cliente j
modelo.c = pyEnv.Param(modelo.I,
                       modelo.J,
                       initialize=lambda modelo, i, j: cij[i - 1][j - 1])
#Capacidade de cada fabrica
modelo.b = pyEnv.Param(modelo.I,
                       initialize=lambda modelo, i: capacidades[i - 1])
Esempio n. 3
0
    def __init__(self,
                 x,
                 y,
                 bigM=100,
                 shrinkage=None,
                 factor=2,
                 nlambda=10,
                 ngamma=10):
        '''
        x (list lenth M):  arrays of predictor variables
        y (list length M): arrays of response variables
        bigM (float):      bigM parameter value
        '''
        self.shrink = shrinkage
        self.factor = factor
        self.nlambda = nlambda
        self.ngamma = ngamma

        M = len(x)
        T = [_x.shape[0] for _x in x]
        _, P = x[0].shape

        # pyomo optimisation model
        model = pyo.ConcreteModel()
        '''
        model properties
        '''
        # number of regression models to fit
        model.M = M
        # number of input predictors
        model.P = P
        # number of observations
        model.T = T

        # ordered set of predictor indices
        model.oset_P = pyo.Set(name="indices: predictors",
                               within=pyo.NonNegativeIntegers,
                               initialize=list(range(P)),
                               ordered=True)
        # ordered set of model indices
        model.oset_M = pyo.Set(name="indices: models",
                               within=pyo.NonNegativeIntegers,
                               initialize=range(M),
                               ordered=True)
        '''
        model parameters
        '''
        # big M
        model.param_bigM = 100
        # k: model sparsity
        model.param_k = pyo.Param(
            default=1,
            doc="maximum number of predictors to allow into models",
            within=pyo.PositiveIntegers,
            mutable=True)

        # lambda: simultaneous shrinkage parameter (ridge shrinkage)
        model.param_lambda = pyo.Param(
            initialize=0,
            doc="ridge-like simultaneous shrinkage parameter",
            within=pyo.NonNegativeReals,
            mutable=True)
        # gamma: l1 parameter
        model.param_gamma = pyo.Param(
            initialize=0,
            doc="lasso-like simultaneous shrinkage parameter",
            within=pyo.NonNegativeReals,
            mutable=True)
        '''
        model variables
        '''
        # beta: regression coefficients (continuous variables)
        model.beta = pyo.Var(model.oset_M, model.oset_P, domain=pyo.Reals)
        # z: selected variable indicator (binary variables)
        model.z = pyo.Var(model.oset_P, domain=pyo.Boolean)
        # betaaux
        model.beta_aux = pyo.Var(model.oset_P, domain=pyo.Reals)
        # betatilde
        model.beta_tilde = pyo.Var(model.oset_M,
                                   model.oset_P, [0, 1],
                                   domain=pyo.PositiveReals)
        '''
        model arrays
        '''
        model.Q = [x[m].T.dot(x[m]) for m in range(M)]
        model.R = [-2 * y[m].dot(x[m]) for m in range(M)]
        model.C = [y[m].T.dot(y[m]) for m in range(M)]

        # objective, simultaneous OLS
        model.OBJ = pyo.Objective(rule=Objective_mls, sense=pyo.minimize)

        # objective, l2 shrinkage
        model.OBJ_shrinkl2 = pyo.Objective(rule=Objective_mls_shrinkl2,
                                           sense=pyo.minimize)
        model.OBJ_shrinkl2.deactivate()
        # objective, l1 shrinkage
        model.OBJ_shrinkl1 = pyo.Objective(rule=Objective_mls_shrinkl1,
                                           sense=pyo.minimize)
        model.OBJ_shrinkl1.deactivate()
        '''
        model constraints
        '''
        # sparsity: total number of selected predictors (across M models)
        model.constr_sparsity = pyo.Constraint(
            expr=pyo.quicksum(model.z[p] for p in range(P)) <= model.param_k)

        # big M above
        model.constr_Mpos = pyo.Constraint(
            model.oset_M,
            model.oset_P,
            rule=lambda mod, m, p: mod.beta[m, p] <= mod.param_bigM * mod.z[p])

        # big M below
        model.constr_Mneg = pyo.Constraint(
            model.oset_M,
            model.oset_P,
            rule=lambda mod, m, p: -mod.param_bigM * model.z[p] <= mod.beta[m,
                                                                            p])

        # l1 shrink: additional constraints
        model.constr_betatildep = pyo.Constraint(
            model.oset_M,
            model.oset_P,
            rule=lambda mod, m, p: mod.beta[m, p] - mod.beta_aux[
                p] <= mod.beta_tilde[m, p, 0] - mod.beta_tilde[m, p, 1])
        model.constr_betatildep.deactivate()
        model.constr_betatilden = pyo.Constraint(
            model.oset_M,
            model.oset_P,
            rule=lambda mod, m, p: mod.beta[m, p] - mod.beta_aux[
                p] >= mod.beta_tilde[m, p, 0] - mod.beta_tilde[m, p, 1])
        model.constr_betatilden.deactivate()

        # asssign the pyomo model to the class
        self.model = model
Esempio n. 4
0
    def test_scaling_without_rename(self):
        m = pyo.ConcreteModel()
        m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
        m.v1 = pyo.Var(initialize=10)
        m.v2 = pyo.Var(initialize=20)
        m.v3 = pyo.Var(initialize=30)

        def c1_rule(m):
            return m.v1 == 1e6

        m.c1 = pyo.Constraint(rule=c1_rule)

        def c2_rule(m):
            return m.v2 == 1e-4

        m.c2 = pyo.Constraint(rule=c2_rule)

        m.scaling_factor[m.v1] = 1.0
        m.scaling_factor[m.v2] = 0.5
        m.scaling_factor[m.v3] = 0.25
        m.scaling_factor[m.c1] = 1e-5
        m.scaling_factor[m.c2] = 1e5

        values = {}
        values[id(m.v1)] = (m.v1.value, m.scaling_factor[m.v1])
        values[id(m.v2)] = (m.v2.value, m.scaling_factor[m.v2])
        values[id(m.v3)] = (m.v3.value, m.scaling_factor[m.v3])
        values[id(m.c1)] = (pyo.value(m.c1.body), m.scaling_factor[m.c1])
        values[id(m.c2)] = (pyo.value(m.c2.body), m.scaling_factor[m.c2])

        m.c2_ref = pyo.Reference(m.c2)
        m.v3_ref = pyo.Reference(m.v3)

        scale = pyo.TransformationFactory('core.scale_model')
        scale.apply_to(m, rename=False)

        self.assertTrue(hasattr(m, 'v1'))
        self.assertTrue(hasattr(m, 'v2'))
        self.assertTrue(hasattr(m, 'c1'))
        self.assertTrue(hasattr(m, 'c2'))

        orig_val, factor = values[id(m.v1)]
        self.assertAlmostEqual(
            m.v1.value,
            orig_val * factor,
        )

        orig_val, factor = values[id(m.v2)]
        self.assertAlmostEqual(
            m.v2.value,
            orig_val * factor,
        )

        orig_val, factor = values[id(m.c1)]
        self.assertAlmostEqual(
            pyo.value(m.c1.body),
            orig_val * factor,
        )

        orig_val, factor = values[id(m.c2)]
        self.assertAlmostEqual(
            pyo.value(m.c2.body),
            orig_val * factor,
        )

        orig_val, factor = values[id(m.v3)]
        self.assertAlmostEqual(
            m.v3_ref[None].value,
            orig_val * factor,
        )
        # Note that because the model was not renamed,
        # v3_ref is still intact.

        lhs = m.c2.expr.arg(0)
        monom_factor = lhs.arg(0)
        scale_factor = (m.scaling_factor[m.c2] / m.scaling_factor[m.v2])
        self.assertAlmostEqual(
            monom_factor,
            scale_factor,
        )
Esempio n. 5
0
# scont.py
import pyomo.environ as pyo
from pyomo.gdp import Disjunct, Disjunction

L = [1, 2, 3]
U = [2, 4, 6]
index = [0, 1, 2]

model = pyo.ConcreteModel()
model.x = pyo.Var(index, within=pyo.Reals, bounds=(0, 20))
model.x_nonzero = pyo.Var(index, bounds=(0, 1))


# Each disjunction is a semi-continuous variable
#    x[k] == 0 or L[k] <= x[k] <= U[k]
def d_0_rule(d, k):
    m = d.model()
    d.c = pyo.Constraint(expr=m.x[k] == 0)


model.d_0 = Disjunct(index, rule=d_0_rule)


def d_nonzero_rule(d, k):
    m = d.model()
    d.c = pyo.Constraint(expr=pyo.inequality(L[k], m.x[k], U[k]))
    d.count = pyo.Constraint(expr=m.x_nonzero[k] == 1)


model.d_nonzero = Disjunct(index, rule=d_nonzero_rule)
Esempio n. 6
0
    def test_pyomo_external_model_ndarray_scaling(self):
        m = pyo.ConcreteModel()
        m.Pin = pyo.Var(initialize=100, bounds=(0, None))
        m.c1 = pyo.Var(initialize=1.0, bounds=(0, None))
        m.c2 = pyo.Var(initialize=1.0, bounds=(0, None))
        m.F = pyo.Var(initialize=10, bounds=(0, None))

        m.P1 = pyo.Var()
        m.P2 = pyo.Var()

        m.F_con = pyo.Constraint(expr=m.F == 10)
        m.Pin_con = pyo.Constraint(expr=m.Pin == 100)

        # simple parameter estimation test
        m.obj = pyo.Objective(expr=(m.P1 - 90)**2 + (m.P2 - 40)**2)

        # set scaling parameters for the pyomo variables and constraints
        m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
        m.scaling_factor[m.obj] = 0.1  # scale the objective
        m.scaling_factor[m.Pin] = 2.0  # scale the variable
        m.scaling_factor[m.c1] = 3.0  # scale the variable
        m.scaling_factor[m.c2] = 4.0  # scale the variable
        m.scaling_factor[m.F] = 5.0  # scale the variable
        m.scaling_factor[m.P1] = 6.0  # scale the variable
        m.scaling_factor[m.P2] = 7.0  # scale the variable
        m.scaling_factor[m.F_con] = 8.0  # scale the pyomo constraint
        m.scaling_factor[m.Pin_con] = 9.0  # scale the pyomo constraint

        # test that this all works with ndarray input as well
        cyipopt_problem = \
            PyomoExternalCyIpoptProblem(pyomo_model=m,
                                        ex_input_output_model=PressureDropModel(),
                                        inputs=[m.Pin, m.c1, m.c2, m.F],
                                        outputs=[m.P1, m.P2],
                                        outputs_eqn_scaling=np.asarray([10.0, 11.0], dtype=np.float64)
                                        )

        # solve the problem
        options = {
            'hessian_approximation': 'limited-memory',
            'nlp_scaling_method': 'user-scaling',
            'output_file': '_cyipopt-pyomo-ext-scaling-ndarray.log',
            'file_print_level': 10,
            'max_iter': 0
        }
        solver = CyIpoptSolver(cyipopt_problem, options=options)
        x, info = solver.solve(tee=False)

        with open('_cyipopt-pyomo-ext-scaling-ndarray.log', 'r') as fd:
            solver_trace = fd.read()
        os.remove('_cyipopt-pyomo-ext-scaling-ndarray.log')

        self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
        self.assertIn('output_file = _cyipopt-pyomo-ext-scaling-ndarray.log',
                      solver_trace)
        self.assertIn('objective scaling factor = 0.1', solver_trace)
        self.assertIn('x scaling provided', solver_trace)
        self.assertIn('c scaling provided', solver_trace)
        self.assertIn('d scaling provided', solver_trace)
        self.assertIn('DenseVector "x scaling vector" with 7 elements:',
                      solver_trace)
        self.assertIn('x scaling vector[    1]= 6.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    2]= 7.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    3]= 2.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    4]= 3.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    5]= 4.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    6]= 5.0000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    7]= 1.0000000000000000e+00',
                      solver_trace)
        self.assertIn('DenseVector "c scaling vector" with 5 elements:',
                      solver_trace)
        self.assertIn('c scaling vector[    1]= 8.0000000000000000e+00',
                      solver_trace)
        self.assertIn('c scaling vector[    2]= 9.0000000000000000e+00',
                      solver_trace)
        self.assertIn('c scaling vector[    3]= 1.0000000000000000e+00',
                      solver_trace)
        self.assertIn('c scaling vector[    4]= 1.0000000000000000e+01',
                      solver_trace)
        self.assertIn('c scaling vector[    5]= 1.1000000000000000e+01',
                      solver_trace)
Esempio n. 7
0
def get_future_position(base, fleet, rank):
	# return non-fix group pilot ids whose future position is input
	return set(future_base_dic[base] and future_fleet_dic[fleet] and future_rank_dic[rank])


base_dic = get_base_dic()
rank_dic = get_rank_dic()
fleet_dic = get_fleet_dic()
def get_position(base, fleet, rank):
	# return fix group pilot ids whose position is input
	return set(base_dic[base] and fleet_dic[fleet] and rank_dic[rank])
	
##################################
#create the model
model = pe.ConcreteModel()
#get crew list
crews=list(set(crew_df['Crew_ID'].values))
#define demand set
a = set(1,2)
a = {1,2}
frbt_set=[]
for t in range(26):
    for fleet in ['A320','A330']:
        for base in ['B1','B2']:
            for rank in ['CPT','FO']:
                frbt_set.append((fleet,rank,base,t))
model.frbt_set=pe.Set(initialize=frbt_set)
##################################
#Option 1: 
Esempio n. 8
0
def Create_Model_Stg3(EDLP_Init, TPR_Init, single_comb):
    def EDLP_Initialize(Model, *Index):
        # return EDLP_Init[Index[0]]
        return 1

    # def TPR_Initialize(Model, *Index):
    #    return TPR_Init[Index[0]]
    class Temp:
        global PROMO_Initialize

        def PROMO_Initialize(Model, w, promo):
            # promo_init = Globals.historical_df.Promo_Events.tolist()
            # #flag_init = [(1 - x) for x in flag_init]
            # promo_init = np.array(promo_init).reshape(Globals.Tot_Prod, Globals.Tot_Week)
            # if promo_init[p,w]!=0:
            #     if promo==(promo_init[p,w]-1):
            #         return 1
            #     return 0
            # else:
            #     if promo==3:
            #         return 1
            #     return 0
            # if promo==0:
            # return 1
            return 0

    GLV.Model = pyo.ConcreteModel(name="Spend_Optim")
    GLV.Model.Weeks = pyo.Param(
        initialize=Globals.Tot_Week, domain=pyo.PositiveIntegers
    )
    GLV.Model.PPGs = pyo.Param(initialize=Globals.Tot_Prod, domain=pyo.PositiveIntegers)
    GLV.Model.Wk_index = pyo.RangeSet(0, GLV.Model.Weeks - 1)
    GLV.Model.PPG_index = pyo.RangeSet(0, GLV.Model.PPGs - 1)
    # Model.EDLP = pyo.Var(Model.PPG_index, Model.Wk_index, initialize=EDLP_Initialize, domain=pyo.PositiveIntegers,
    # bounds=(Globals.EDLP_LB, Globals.EDLP_UB))
    GLV.Model.EDLP = pyo.Param(
        GLV.Model.PPG_index,
        GLV.Model.Wk_index,
        initialize=EDLP_Initialize,
        domain=pyo.PositiveIntegers,
    )
    # GLV.Model.TPR = pyo.Var(GLV.Model.PPG_index, GLV.Model.Wk_index, initialize=Globals.TPR_LB, domain=pyo.PositiveIntegers,
    #                 bounds=(Globals.TPR_LB, Globals.TPR_UB))
    for prd in range(Globals.Tot_Prod):
        setattr(
            GLV.Model,
            f"Promos_PPG_{prd}",
            pyo.Param(
                initialize=len(Globals.TPR_Perc_Val[prd]), domain=pyo.PositiveIntegers
            ),
        )
        setattr(
            GLV.Model,
            f"Promo_index_{prd}",
            pyo.RangeSet(0, getattr(GLV.Model, f"Promos_PPG_{0}") - 1),
        )
        setattr(
            GLV.Model,
            f"TPR_FLAG_PPG_{prd}",
            pyo.Var(
                GLV.Model.Wk_index,
                getattr(GLV.Model, f"Promo_index_{prd}"),
                initialize=PROMO_Initialize,
                domain=pyo.Binary,
            ),
        )

    # GLV.Model.display()

    #     GLV.Model.TPR_FLAG = pyo.Var(GLV.Model.PPG_index,GLV.Model.Wk_index,GLV.Model.Promo_index,initialize=PROMO_Initialize,domain=pyo.Binary)
    GLV.Model.Obj = pyo.Objective(rule=Dollar_Sales_Fn, sense=pyo.maximize)
    #     GLV.Model.Tot_Spent_Bnd = pyo.Constraint(GLV.Model.PPG_index, rule=Total_Trade_Spent_Bnd_Fn)
    #     GLV.Model.EDLP_Bnd = pyo.Constraint(GLV.Model.PPG_index, rule=EDLP_Trade_Spent_Bnd_Fn)
    GLV.Model.TPR_Bnd = pyo.Constraint(GLV.Model.PPG_index, rule=TPR_Trade_Spent_Bnd_Fn)
    GLV.Model.Overall = pyo.Constraint(rule=Overall_Total_Trade_Spent_Fn)
    GLV.Model.Promo_con = pyo.Constraint(
        GLV.Model.PPG_index, GLV.Model.Wk_index, rule=Promo_constraint
    )
    # Model.display()
    const_list = [
        "51_52",
        "Promo_limits",
        "Promo_Consecutive",
        "Deep_Promo_Repeat",
        "Deep_Promo_Collective",
        "Promos_Rep_PR",
        "Weeks_Baseline",
        "Promo_Retailer_NFL",
        "TWP_Promo",
        "RSV_Constraint",
        "Cross_Ret_Clash_Constraint",
        "Cat_Clean_Air_Constraint",
        "Two_Calendar_Constraint",
        "Deep_Activity_Promo_Constraint",
    ]
    name_file = ""
    # single_comb = [True,True,True,True,True,False,False,True,False,True]
    for i, s in enumerate(single_comb):
        if s:
            name_file += const_list[i] + "_"
    #     logger.info("#####------------ACK_PIN---------------###", name_file)
    #     logger.info(single_comb)

    window_size = 4

    Constraint_51_52(GLV.Model, single_comb[0])
    Promo_limits(GLV.Model, single_comb[1])
    Promo_Consective(GLV.Model, single_comb[2])
    Deep_Promo_Repeat(GLV.Model, single_comb[3], window_size=window_size)
    # Deep_Promo_Repeat(Model,single_comb[4],window_size=4)
    Deep_Promo_Collective(GLV.Model, single_comb[4])
    Promos_Rep_PR(GLV.Model, single_comb[5])
    Weeks_Baseline(GLV.Model, single_comb[6])
    Promo_Retailer_NFL(GLV.Model, single_comb[7])
    TWP_Promo(GLV.Model, single_comb[8])
    RSV_Dollar_Sales(GLV.Model, single_comb[9])
    Cross_Ret_Clash_Constraint(GLV.Model, single_comb[10])
    Same_Calendar_s3_Constraint(GLV.Model, single_comb[12])
    Deep_Activity_Promo_Const_Fn(GLV.Model, single_comb[13])

    # Model.display()
    return GLV.Model
def pysp_instance_creation_callback(scenario_name, node_names):

    model = aml.ConcreteModel()
    model.x = aml.Var()
    model.z = aml.Var()
    model.FirstStageCost = aml.Expression(expr=5 * (model.z**2 +
                                                    (model.x - 1.1)**2))
    model.SecondStageCost = aml.Expression(expr=0.0)
    model.ThirdStageCost = aml.Expression(expr=0.0)
    model.obj = aml.Objective(expr= model.FirstStageCost + \
                                    model.SecondStageCost + \
                                    model.ThirdStageCost)
    model.c = aml.ConstraintList()
    model.c.add(model.z == model.x)
    if scenario_name.startswith("u0"):
        # All scenarios under second-stage node "u0"
        model.xu0 = aml.Var()
        model.c.add(model.xu0 == model.x)
        model.SecondStageCost.expr = (model.xu0 - 1)**2

        model.y0 = aml.Var()
        model.c.add(expr=-10 <= model.y0 <= 10)
        if scenario_name == "u00":
            model.yu00 = aml.Var()
            model.c.add(model.yu00 == model.y0)
            model.ThirdStageCost.expr = (model.yu00 + 1)**2
        elif scenario_name == "u01":
            model.yu01 = aml.Var()
            model.c.add(model.yu01 == model.y0)
            model.ThirdStageCost.expr = (2 * model.yu01 - 3)**2 + 1
        else:
            assert False
    elif scenario_name.startswith("u1"):
        # All scenarios under second-stage node "u1"
        model.xu1 = aml.Var()
        model.c.add(model.xu1 == model.x)
        model.SecondStageCost.expr = (model.xu1 + 1)**2

        model.y1 = aml.Var()
        model.c.add(expr=-10 <= model.y1 <= 10)
        if scenario_name == "u10":
            model.yu10 = aml.Var()
            model.c.add(model.yu10 == model.y1)
            model.ThirdStageCost.expr = (0.5 * model.yu10 - 1)**2 - 1
        elif scenario_name == "u11":
            model.yu11 = aml.Var()
            model.c.add(model.yu11 == model.y1)
            model.ThirdStageCost.expr = (0.2 * model.yu11)**2
        else:
            assert False
    elif scenario_name.startswith("u2"):
        # All scenarios under second-stage node "u2"
        model.xu2 = aml.Var()
        model.c.add(model.xu2 == model.x)
        model.SecondStageCost.expr = (model.xu2 - 0.5)**2

        model.y2 = aml.Var()
        model.c.add(expr=-10 <= model.y2 <= 10)
        if scenario_name == "u20":
            model.yu20 = aml.Var()
            model.c.add(model.yu20 == model.y2)
            model.ThirdStageCost.expr = (0.1 * model.yu20 - 3)**2 + 2
        else:
            assert False
    else:
        assert False

    return model
Esempio n. 10
0
    def test_basics(self):
        m = pe.ConcreteModel()
        m.x = pe.Var(bounds=(-10, 10))
        m.y = pe.Var()
        m.obj = pe.Objective(expr=m.x**2 + m.y**2)
        m.c1 = pe.Constraint(expr=m.y >= 2 * m.x + 1)

        opt = pe.SolverFactory('xpress_persistent')
        opt.set_instance(m)

        self.assertEqual(opt.get_xpress_attribute('cols'), 2)
        self.assertEqual(opt.get_xpress_attribute('rows'), 1)

        res = opt.solve()
        self.assertAlmostEqual(m.x.value, -0.4, delta=1e-6)
        self.assertAlmostEqual(m.y.value, 0.2, delta=1e-6)
        opt.load_duals()
        self.assertAlmostEqual(m.dual[m.c1], -0.4, delta=1e-6)
        del m.dual

        m.c2 = pe.Constraint(expr=m.y >= -m.x + 1)
        opt.add_constraint(m.c2)
        self.assertEqual(opt.get_xpress_attribute('cols'), 2)
        self.assertEqual(opt.get_xpress_attribute('rows'), 2)

        res = opt.solve(save_results=False, load_solutions=False)
        self.assertAlmostEqual(m.x.value, -0.4, delta=1e-6)
        self.assertAlmostEqual(m.y.value, 0.2, delta=1e-6)
        opt.load_vars()
        self.assertAlmostEqual(m.x.value, 0, delta=1e-6)
        self.assertAlmostEqual(m.y.value, 1, delta=2e-6)

        opt.remove_constraint(m.c2)
        m.del_component(m.c2)
        self.assertEqual(opt.get_xpress_attribute('cols'), 2)
        self.assertEqual(opt.get_xpress_attribute('rows'), 1)

        self.assertEqual(opt.get_xpress_control('feastol'), 1e-6)
        res = opt.solve(options={'feastol': '1e-7'})
        self.assertEqual(opt.get_xpress_control('feastol'), 1e-7)
        self.assertAlmostEqual(m.x.value, -0.4, delta=1e-6)
        self.assertAlmostEqual(m.y.value, 0.2, delta=1e-6)

        m.x.setlb(-5)
        m.x.setub(5)
        opt.update_var(m.x)
        # a nice wrapper for xpress isn't implemented,
        # so we'll do this directly
        x_idx = opt._solver_model.getIndex(
            opt._pyomo_var_to_solver_var_map[m.x])
        lb = []
        opt._solver_model.getlb(lb, x_idx, x_idx)
        ub = []
        opt._solver_model.getub(ub, x_idx, x_idx)
        self.assertEqual(lb[0], -5)
        self.assertEqual(ub[0], 5)

        m.x.fix(0)
        opt.update_var(m.x)
        lb = []
        opt._solver_model.getlb(lb, x_idx, x_idx)
        ub = []
        opt._solver_model.getub(ub, x_idx, x_idx)
        self.assertEqual(lb[0], 0)
        self.assertEqual(ub[0], 0)

        m.x.unfix()
        opt.update_var(m.x)
        lb = []
        opt._solver_model.getlb(lb, x_idx, x_idx)
        ub = []
        opt._solver_model.getub(ub, x_idx, x_idx)
        self.assertEqual(lb[0], -5)
        self.assertEqual(ub[0], 5)

        m.c2 = pe.Constraint(expr=m.y >= m.x**2)
        opt.add_constraint(m.c2)
        self.assertEqual(opt.get_xpress_attribute('cols'), 2)
        self.assertEqual(opt.get_xpress_attribute('rows'), 2)

        opt.remove_constraint(m.c2)
        m.del_component(m.c2)
        self.assertEqual(opt.get_xpress_attribute('cols'), 2)
        self.assertEqual(opt.get_xpress_attribute('rows'), 1)

        m.z = pe.Var()
        opt.add_var(m.z)
        self.assertEqual(opt.get_xpress_attribute('cols'), 3)
        opt.remove_var(m.z)
        del m.z
        self.assertEqual(opt.get_xpress_attribute('cols'), 2)
Esempio n. 11
0
import pyomo.environ as py

m = py.ConcreteModel()

m.x11 = py.Var(within = py.NonNegativeIntegers)
m.x12 = py.Var(within = py.NonNegativeIntegers)
m.x13 = py.Var(within = py.NonNegativeIntegers)

m.x21 = py.Var(within = py.NonNegativeIntegers)
m.x22 = py.Var(within = py.NonNegativeIntegers)
m.x23 = py.Var(within = py.NonNegativeIntegers)

m.x31 = py.Var(within = py.NonNegativeIntegers)
m.x32 = py.Var(within = py.NonNegativeIntegers)
m.x33 = py.Var(within = py.NonNegativeIntegers)

m.x41 = py.Var(within = py.NonNegativeIntegers)
m.x42 = py.Var(within = py.NonNegativeIntegers)
m.x43 = py.Var(within = py.NonNegativeIntegers)

m.x51 = py.Var(within = py.NonNegativeIntegers)
m.x52 = py.Var(within = py.NonNegativeIntegers)
m.x53 = py.Var(within = py.NonNegativeIntegers)


M = 100000000

def obj_rule(m):
    return (31*m.x11 + 45*m.x12 + 38*m.x13 + 
            29*m.x21 + 41*m.x22 + 35*m.x23 + 
            32*m.x31 + 46*m.x32 + 40*m.x33 + 
Esempio n. 12
0
# @model:
import pyomo.environ as pyo

m = pyo.ConcreteModel()
m.x = pyo.Var()
m.y = pyo.Var()
m.obj = pyo.Objective(expr=m.x**2 + m.y**2)
m.c = pyo.Constraint(expr=m.y >= -2 * m.x + 5)
# @:model

# @creation:
opt = pyo.SolverFactory('gurobi_persistent')
# @:creation

# @set_instance:
opt.set_instance(m)
# @:set_instance

# @solve:
results = opt.solve()
# @:solve

print('Objective after solve 1: ', pyo.value(m.obj))

# @add_constraint:
m.c2 = pyo.Constraint(expr=m.y >= m.x)
opt.add_constraint(m.c2)
# @:add_constraint

# @solve2:
results = opt.solve()
Esempio n. 13
0
 def __init__(self):
     self.model = pe.ConcreteModel()
     self.solver = pe.SolverFactory("couenne")
     self.top = 0
Esempio n. 14
0
def create_copperplate_dispatch_approx_model(model_data,
                                             include_feasibility_slack=False):
    md = model_data.clone_in_service()
    tx_utils.scale_ModelData_to_pu(md, inplace=True)

    gens = dict(md.elements(element_type='generator'))
    buses = dict(md.elements(element_type='bus'))
    branches = dict(md.elements(element_type='branch'))
    loads = dict(md.elements(element_type='load'))
    shunts = dict(md.elements(element_type='shunt'))

    gen_attrs = md.attributes(element_type='generator')
    bus_attrs = md.attributes(element_type='bus')

    inlet_branches_by_bus, outlet_branches_by_bus = \
        tx_utils.inlet_outlet_branches_by_bus(branches, buses)
    gens_by_bus = tx_utils.gens_by_bus(buses, gens)

    model = pe.ConcreteModel()

    ### declare (and fix) the loads at the buses
    bus_p_loads, _ = tx_utils.dict_of_bus_loads(buses, loads)

    libbus.declare_var_pl(model, bus_attrs['names'], initialize=bus_p_loads)
    model.pl.fix()

    ### declare the fixed shunts at the buses
    _, bus_gs_fixed_shunts = tx_utils.dict_of_bus_fixed_shunts(buses, shunts)

    ### declare the generator real power
    pg_init = {
        k: (gen_attrs['p_min'][k] + gen_attrs['p_max'][k]) / 2.0
        for k in gen_attrs['pg']
    }
    libgen.declare_var_pg(model,
                          gen_attrs['names'],
                          initialize=pg_init,
                          bounds=zip_items(gen_attrs['p_min'],
                                           gen_attrs['p_max']))

    ### include the feasibility slack for the system balance
    p_rhs_kwargs = {}
    if include_feasibility_slack:
        p_rhs_kwargs, penalty_expr = _include_system_feasibility_slack(
            model, gen_attrs, bus_p_loads)

    ### declare the p balance
    libbus.declare_eq_p_balance_ed(model=model,
                                   index_set=bus_attrs['names'],
                                   bus_p_loads=bus_p_loads,
                                   gens_by_bus=gens_by_bus,
                                   bus_gs_fixed_shunts=bus_gs_fixed_shunts,
                                   **p_rhs_kwargs)

    ### declare the generator cost objective
    libgen.declare_expression_pgqg_operating_cost(model=model,
                                                  index_set=gen_attrs['names'],
                                                  p_costs=gen_attrs['p_cost'])

    obj_expr = sum(model.pg_operating_cost[gen_name]
                   for gen_name in model.pg_operating_cost)
    if include_feasibility_slack:
        obj_expr += penalty_expr

    model.obj = pe.Objective(expr=obj_expr)

    return model, md
Esempio n. 15
0
def test_project_to_F_obj_func(quadratic_NW):
    # TEST DESCRIPTION: Since project_to_F essentially adds an objective
    #function to the user defined feasible_set_C pyomo model and then solves the model
    #with gurobi, the main element to check is this objective function.:
    #We examined the objective function that project_to_F generates for the second unit test toy
    #problem’s initial zt by plugging in test values we generated in a separate MATLAB
    #script (generating_data.m) and comparing the objective function values between
    #the MATLAB answers and the project_to_F objective function values.
    
    #### Part 1: Defining the set C/F #####
    
    feasible_c_region = pyo.ConcreteModel()

    feasible_c_region.varindex = pyo.RangeSet(1,3)
    feasible_c_region.c = pyo.Var(feasible_c_region.varindex)
    
    # Defining Constraints #
    # We need all constraints to be in the form of rules (including
    # if we have non-negativity constraints)    
    def greater_than_zero(model,i):
        return 0 <= model.c[i] 
    
    feasible_c_region.greater_than_zero_constraint = pyo.Constraint(feasible_c_region.varindex,\
                                                         rule=greater_than_zero) 
    
    def less_than_one(model,i):
        return model.c[i] <= 1
    
    feasible_c_region.less_than_one_constraint = pyo.Constraint(feasible_c_region.varindex,\
                                                                rule=less_than_one)
    
    quadratic_NW.feasible_set_C = feasible_c_region.clone()
    
    #########################################################
    ## Part 2: Initialize the Model ##
    
    quadratic_NW.initialize_IO_method("BMPS_online_GD",alg_specific_params={'diam_flag':0})
    #the first y_t_BMPS will be the c that we passed into the initialization
    #{1:-8,2:-3,3:-3}
    quadratic_NW.next_iteration(part_for_BMPS=1) #the first y_t_BMPS is the c data that gets fed into
                                            #the class when we create an instance of it  
    
    ## Extracting the project_to_F model to check the objective function ##
    model_F = quadratic_NW.project_to_F_model.clone()
    
    
    ## Part 3: Test the Model ##
    ## Input 1 ##
    model_F.c[1] = 7
    model_F.c[2] = 6
    model_F.c[3] = -14
    
    obj_value_F = round(pyo.value(model_F.obj_func(model_F)),1)
    
    assert obj_value_F == 427.0
    
    ## Input 2 ##
    model_F.c[1] = -16
    model_F.c[2] = 0
    model_F.c[3] = 19
    
    obj_value_F = round(pyo.value(model_F.obj_func(model_F)),1)
    
    assert obj_value_F == 557.0
    
    ## Input 3 ##
    model_F.c[1] = -7
    model_F.c[2] = 3
    model_F.c[3] = -11
    
    obj_value_F = round(pyo.value(model_F.obj_func(model_F)),1)
    
    assert obj_value_F == 101.0
Esempio n. 16
0
    def find_component(self, n, coeffs_centered):
        def norm(model):
            out = 0
            for i in range(self.ndata):
                x_i = np.copy(coeffs_centered[i, :])
                pt_i = np.copy(self.coeff_mat[i, :])
                center = np.copy(self.bary)
                PT = []
                for s in range(self.nbasis):
                    vector = model.lamb[i] * model.w[s]
                    PT.append(center[s] + vector)

                for h in range(model.nvar):
                    for s in range(model.nvar):
                        out += (PT[h] - pt_i[h]) * \
                            self.metric_aug[h, s]*(PT[s] - pt_i[s])

            return out

        model = pyo.ConcreteModel()
        model.nvar = self.nbasis
        model.npoints = self.ndata

        model.w = pyo.Var(np.arange(model.nvar),
                          domain=pyo.Reals,
                          initialize=lambda m, i: self.initialization[i, n])
        model.lamb = pyo.Var(np.arange(model.npoints),
                             domain=pyo.Reals,
                             initialize=1)

        model.obj = pyo.Objective(rule=norm, sense=pyo.minimize)
        model.costr = pyo.ConstraintList()

        # costraint ||w||_E=1
        aux = 0
        for i in range(model.nvar):
            aux += self.metric_aug[i, i] * model.w[i]**2
            for j in range(i):
                aux += 2 * model.w[i] * model.w[j] * self.metric_aug[i, j]

        model.costr.add(aux == 1)

        # monothonicity contstraint
        for i in range(self.ndata):
            x_i = np.copy(coeffs_centered[i, :])
            center = np.copy(self.bary)
            for s in range(n):
                eig = np.copy(self.eig_vecs[:, s])
                center += eig * self.coords[i, s]

            for j in range(self.nbasis - 1):
                costr = sum([
                    self.constraints_mat[j, k] *
                    (model.lamb[i] * model.w[k] + center[k])
                    for k in range(self.nbasis)
                ])
                model.costr.add(costr <= 0)

        # orthogonality constraints wrt previous components
        if n > 0:
            for s in range(n):
                eig = np.copy(self.eig_vecs[:, s])
                angle = 0
                for h in range(model.nvar):
                    for k in range(model.nvar):
                        angle += model.w[h] * eig[k] * self.metric_aug[h, k]
                model.costr.add(angle == 0)

        solver = pyo.SolverFactory('ipopt')

        S = solver.solve(model)
        cost = model.obj()

        # needed to get argmin
        # TODO maybe find more intellingent way
        w_eval = np.ones((model.nvar, ))
        for key, val in model.w.extract_values().items():
            w_eval[key] = val

        lamb_eval = np.ones((model.npoints, ))
        for key, val in model.lamb.extract_values().items():
            lamb_eval[key] = val

        return w_eval, lamb_eval
Esempio n. 17
0
def test_gradient_step(chan_lee_terekhov_linear_inequalities):
    #TEST DESCRIPTION: This test uses data we generated in a MATLAB script to
    #make sure that gradient_step does the correct calculations. We generate data for
    #eta_t, c_t, x_t, xbat_t, feed the data into gradient_step, and then check 
    #the results against the MATLAB results.

    
    
    ### Setting things up ###
    chan_lee_terekhov_linear_inequalities.feasible_set_C = pyo.ConcreteModel()
    chan_lee_terekhov_linear_inequalities.initialize_IO_method("BMPS_online_GD",alg_specific_params={'diam_flag':0}) #this will set up the method 

    ### Passing in Data (to the attributes) ###
    ## Test 1 ##
    chan_lee_terekhov_linear_inequalities.c_t_BMPS = {1:3,2:-34}
    chan_lee_terekhov_linear_inequalities.x_t_BMPS = np.array([[10],[-24]])
    chan_lee_terekhov_linear_inequalities.xbar_t_BMPS = np.array([[16],[19]])
    eta = 0.2294
    z_t = chan_lee_terekhov_linear_inequalities.gradient_step(eta_t=eta,x_t=chan_lee_terekhov_linear_inequalities.x_t_BMPS)
    
    assert np.all(np.around(z_t,decimals=4) == np.array([[4.3764],[-24.1358]]))
    
    ## Test 2 ##
    chan_lee_terekhov_linear_inequalities.c_t_BMPS = {1:-5,2:-42}
    chan_lee_terekhov_linear_inequalities.x_t_BMPS = np.array([[-27],[42]])
    chan_lee_terekhov_linear_inequalities.xbar_t_BMPS = np.array([[-35],[33]])
    eta = 0.2000
    z_t = chan_lee_terekhov_linear_inequalities.gradient_step(eta_t=eta,x_t=chan_lee_terekhov_linear_inequalities.x_t_BMPS)
    
    assert np.all(np.around(z_t,decimals=4) == np.array([[-6.6000],[-43.8000]]))
    
    ## Test 3 ##
    chan_lee_terekhov_linear_inequalities.c_t_BMPS = {1:32,2:37}
    chan_lee_terekhov_linear_inequalities.x_t_BMPS = np.array([[-42],[-10]])
    chan_lee_terekhov_linear_inequalities.xbar_t_BMPS = np.array([[-24],[30]])
    eta = 0.1890
    z_t = chan_lee_terekhov_linear_inequalities.gradient_step(eta_t=eta,x_t=chan_lee_terekhov_linear_inequalities.x_t_BMPS)
    
    assert np.all(np.around(z_t,decimals=4) == np.array([[35.4020],[44.5600]]))
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
Esempio n. 18
0
def optimize(data, config):
    # model
    model = pyomo.ConcreteModel()

    # parameters
    shippingcost = {x['seller']: x['shippingcost'] for x in data}
    distance = {x['seller']: x['distance'] for x in data}
    ordercount = {x['seller']: x['ordercount'] for x in data}

    # define sets
    I = list(set(x['product'] for x in data))
    J = list(set(x['seller'] for x in data))
    IJ = [(x['product'], x['seller']) for x in data]

    # decision vaiables
    model.x = pyomo.Var(IJ, domain=pyomo.Integers, bounds=(0, 1), doc='trans')
    model.y = pyomo.Var(J,
                        domain=pyomo.Integers,
                        bounds=(0, 1),
                        doc='sellertrans')

    # constraints
    model.cons = pyomo.ConstraintList(doc='constraints')
    # transport to all demand
    for i in I:
        model.cons.add(sum([model.x[ij] for ij in model.x if ij[0] == i]) == 1)
    # seller transportation constraints
    maxtrans = len(IJ)
    for j in J:
        model.cons.add(
            sum([model.x[ij]
                 for ij in model.x if ij[1] == j]) <= model.y[j] * maxtrans)

    # objective function
    shippingcost_penalty = 0 if sum(shippingcost.values()) == 0 \
        else 1000000000 * (sum(model.y[j] * shippingcost[j] for j in J) / sum(shippingcost.values()))
    sellertotal_penalty = 0 if len(J) == 0 \
        else 1000000 * (sum(model.y[j] for j in J) / len(J))
    distance_penalty = 0 if sum(distance.values()) == 0 \
        else 1000 * (sum(model.y[j] * distance[j] for j in J) / sum(distance.values()))
    ordercount_penalty = 0 if sum(ordercount.values()) == 0 \
        else 1 * (sum(model.y[j] * ordercount[j] for j in J) / sum(ordercount.values()))
    model.obj = pyomo.Objective(expr=shippingcost_penalty +
                                sellertotal_penalty + distance_penalty +
                                ordercount_penalty,
                                sense=pyomo.minimize)

    # solve
    if config['app']['solver_path'] == "None":
        s = SolverFactory(config['app']['solver'])
    else:
        s = SolverFactory(config['app']['solver'],
                          executable=config['app']['solver_path'])
    status = s.solve(model)

    # gen output
    x = []
    for ij in model.x:
        if model.x[ij].value > 0:
            x.append({
                "product": ij[0],
                "seller": ij[1],
                "shippingcost": shippingcost[ij[1]],
            })
    y = []
    for j in model.y:
        if model.y[j].value > 0:
            y.append({
                "seller": j,
            })

    output = {
        "status_solver": str(status['Solver'][0]['Status']),
        "status_termination":
        str(status['Solver'][0]['Termination condition']),
        "total_shippingcost": sum([shippingcost[j['seller']] for j in y]),
        "total_sellers": len(y),
        "total_distance": sum([distance[j['seller']] for j in y]),
        "total_ordercount": sum([ordercount[j['seller']] for j in y]),
        "result": x
    }
    return output
Esempio n. 19
0
def build_im_mip_model(env, bigm=10000, online=False):
    '''
    Optimize base stock level (z variable) on a simulated sample path using an MILP. The existing
    sample path (historical demands) is used when running online.
    
    Notes: 
        -z is constant in time (static base-stock policy)
        -Using the hull reformulation instead of big-M could speed things up. Using tighter 
            big-M could also be helpful.
        -All parameters to the simulation environment must have been defined 
            previously when making the environment.
    
    env = [InvManagementEnv] current simulation environment. 
    bigm = [Float] big-M value for BM reformulation
    online = [Boolean] should the optimization be run online?
    '''

    # assert env.spec.id == 'InvManagement-v0', \
    # '{} received. Heuristic designed for InvManagement-v0.'.format(env.spec.id)
    #do not reset environment

    #big m values
    M = bigm
    BigM1 = M
    BigM2 = M
    BigM3 = -M
    BigM4 = -M
    BigM5 = -M
    BigM6 = -M

    #create model
    mip = pe.ConcreteModel()

    #define sets
    if online:
        mip.n = pe.RangeSet(0, env.period - 1)  #periods
        mip.n1 = pe.RangeSet(
            0, env.period
        )  #periods (includes an additional period for final inventories)
    else:
        mip.n = pe.RangeSet(0, env.num_periods - 1)
        mip.n1 = pe.RangeSet(0, env.num_periods)
    mip.m = pe.RangeSet(0, env.num_stages - 1)  #stages
    mip.m0 = pe.RangeSet(
        0, env.num_stages -
        2)  #stages (excludes last stage which has no inventory)

    #define parameters
    mip.unit_price = pe.Param(mip.m,
                              initialize={i: env.unit_price[i]
                                          for i in mip.m
                                          })  #sales price for each stage
    mip.unit_cost = pe.Param(mip.m,
                             initialize={i: env.unit_cost[i]
                                         for i in mip.m
                                         })  #purchasing cost for each stage
    mip.demand_cost = pe.Param(mip.m,
                               initialize={
                                   i: env.demand_cost[i]
                                   for i in mip.m
                               })  #cost for unfulfilled demand at each stage
    mip.holding_cost = pe.Param(mip.m,
                                initialize={
                                    i: env.holding_cost[i]
                                    for i in mip.m
                                })  #inventory holding cost at each stage
    mip.supply_capacity = pe.Param(mip.m0,
                                   initialize={
                                       i: env.supply_capacity[i]
                                       for i in mip.m0
                                   })  #production capacity at each stage
    mip.lead_time = pe.Param(mip.m0,
                             initialize={i: env.lead_time[i]
                                         for i in mip.m0
                                         })  #lead times in between stages
    mip.discount = env.discount  #time-valued discount
    backlog = env.backlog  #backlog or lost sales
    if online:  #only use up to the current period
        mip.num_periods = env.period
        D = env.D[:env.period]
    else:  #use full simulation if offline
        mip.num_periods = env.num_periods
        D = env.demand_dist.rvs(size=env.num_periods, **env.dist_param)
    mip.D = pe.Param(mip.n, initialize={i: D[i]
                                        for i in mip.n})  #store demands
    prob = env.demand_dist.pmf(
        D, **env.dist_param)  #probability of each demand based on distribution
    mip.prob = pe.Param(mip.n,
                        initialize={i: prob[i]
                                    for i in mip.n
                                    })  #store probability at each period

    #define variables
    mip.I = pe.Var(
        mip.n1, mip.m0,
        domain=pe.NonNegativeReals)  #on hand inventory at each stage
    mip.T = pe.Var(
        mip.n1, mip.m0,
        domain=pe.NonNegativeReals)  #pipeline inventory in between each stage
    mip.R = pe.Var(
        mip.n, mip.m0,
        domain=pe.NonNegativeReals)  #reorder quantities for each stage
    mip.R1 = pe.Var(
        mip.n, mip.m0,
        domain=pe.NonNegativeReals)  #unconstrained reorder quantity
    mip.S = pe.Var(mip.n, mip.m,
                   domain=pe.NonNegativeReals)  #sales at each stage
    if backlog:
        mip.B = pe.Var(mip.n, mip.m,
                       domain=pe.NonNegativeReals)  #backlogs at each stage
    else:
        mip.LS = pe.Var(mip.n, mip.m,
                        domain=pe.NonNegativeReals)  #lost sales at each stage
    mip.P = pe.Var(mip.n, domain=pe.Reals)  #profit at each stage
    mip.y = pe.Var(
        mip.n, mip.m0, domain=pe.Binary
    )  #auxiliary variable (y = 0: inventory level is above the base stock level (no reorder))
    mip.y1 = pe.Var(
        mip.n, mip.m0, domain=pe.Binary
    )  #auxiliary variable (y1 = 1: unconstrained reorder quantity accepted)
    mip.y2 = pe.Var(
        mip.n, mip.m0, domain=pe.Binary
    )  #auxiliary variable (y2 = 1: reorder quantity is capacity constrained)
    if env.num_stages > 2:
        mip.y3 = pe.Var(
            mip.n, mip.m0, domain=pe.Binary
        )  #auxiliary variable (y3 = 1: reorder quantity is inventory constrained)
    mip.y4 = pe.Var(mip.n, mip.m, domain=pe.Binary
                    )  #auxiliary variable (y4 = 1: demand + backlog satisfied)
    mip.x = pe.Var(mip.m0,
                   domain=pe.NonNegativeReals)  #inventory level at each stage
    mip.z = pe.Var(mip.m0,
                   domain=pe.PositiveIntegers)  #base stock level at each stage

    #initialize
    for m in mip.m0:
        mip.T[0, m].fix(0)

    #define constraints
    mip.inv_bal = pe.ConstraintList()
    mip.sales1 = pe.ConstraintList()
    mip.sales2 = pe.ConstraintList()
    mip.sales3 = pe.ConstraintList()
    mip.sales4 = pe.ConstraintList()
    mip.sales5 = pe.ConstraintList()
    mip.reorder1 = pe.ConstraintList()
    mip.reorder2 = pe.ConstraintList()
    mip.reorder3 = pe.ConstraintList()
    mip.reorder4 = pe.ConstraintList()
    mip.reorder5 = pe.ConstraintList()
    mip.reorder6 = pe.ConstraintList()
    mip.reorder7 = pe.ConstraintList()
    mip.reorder8 = pe.ConstraintList()
    mip.reorder9 = pe.ConstraintList()
    mip.reorder10 = pe.ConstraintList()
    mip.pip_bal = pe.ConstraintList()
    mip.unfulfilled = pe.ConstraintList()
    mip.profit = pe.ConstraintList()
    mip.basestock = pe.ConstraintList()
    mip.init_inv = pe.ConstraintList()

    #build constraints
    for m in mip.m0:
        #relate base stock levels to inventory levels: base stock level = total inventory up to that echelon
        mip.basestock.add(mip.z[m] == sum(mip.x[i] for i in range(m + 1)))
        #initialize inventory levels to being full (this would be ideal)
        mip.init_inv.add(mip.I[0, m] == mip.x[m])

    for n in mip.n:
        #calculate profit: apply time value discount to sales revenue - purchasing costs - unfulfilled demand cost - holding cost
        if backlog:
            mip.profit.add(
                mip.P[n] == mip.discount**n *
                (sum(mip.unit_price[m] * mip.S[n, m] for m in mip.m) -
                 (sum(mip.unit_cost[m] * mip.R[n, m]
                      for m in mip.m0) + mip.unit_cost[mip.m[-1]] *
                  mip.S[n, mip.m[-1]]) - sum(mip.demand_cost[m] * mip.B[n, m]
                                             for m in mip.m) -
                 sum(mip.holding_cost[m] * mip.I[n + 1, m] for m in mip.m0)))
        else:
            mip.profit.add(
                mip.P[n] == mip.discount**n *
                (sum(mip.unit_price[m] * mip.S[n, m] for m in mip.m) -
                 (sum(mip.unit_cost[m] * mip.R[n, m]
                      for m in mip.m0) + mip.unit_cost[mip.m[-1]] *
                  mip.S[n, mip.m[-1]]) - sum(mip.demand_cost[m] * mip.LS[n, m]
                                             for m in mip.m) -
                 sum(mip.holding_cost[m] * mip.I[n + 1, m] for m in mip.m0)))

        for m in mip.m0:
            #on-hand inventory balance: next period inventory = prev period inventory + arrival from above stage - sales
            if n - mip.lead_time[m] >= 0:
                mip.inv_bal.add(mip.I[n + 1, m] == mip.I[n, m] +
                                mip.R[n - mip.lead_time[m], m] - mip.S[n, m])
            else:
                mip.inv_bal.add(mip.I[n + 1, m] == mip.I[n, m] - mip.S[n, m])
            #pipeline inventory balance: next period inventory = prev period inventory - delivered material + new reorder
            if n - mip.lead_time[m] >= 0:
                mip.pip_bal.add(mip.T[n + 1, m] == mip.T[n, m] -
                                mip.R[n - mip.lead_time[m], m] + mip.R[n, m])
            else:
                mip.pip_bal.add(mip.T[n + 1, m] == mip.T[n, m] + mip.R[n, m])
            #reorder quantity constraints: R1 = max(0, z - sum(I + T - B) + B[m+1])
            # reorder based on base_stock level = z - sum(I + T - B)
            # Note: R1 = max(A,B) <-> A <= R1 <= A + M*(1-y) ;  B <= R1 <= B + M*y
            # y = 1 means that the reorder level is positive
            # y = 0 means that no reorder necessary (already above base stock level)
            # Disjunction: [y -> R1 = z - sum(I + T - B)] OR [not y -> R1 = 0]
            if (backlog) & (n - 1 >= 0):
                mip.reorder1.add(
                    mip.R1[n, m] <= mip.z[m] -
                    sum(mip.I[n, i] + mip.T[n, i] - mip.B[n - 1, i]
                        for i in range(m + 1)) + mip.B[n - 1, m + 1] + BigM1 *
                    (1 - mip.y[n, m]))
                mip.reorder2.add(
                    mip.R1[n, m] >= mip.z[m] -
                    sum(mip.I[n, i] + mip.T[n, i] - mip.B[n - 1, i]
                        for i in range(m + 1)) + mip.B[n - 1, m + 1])
            else:
                mip.reorder1.add(mip.R1[n, m] <= mip.z[m] -
                                 sum(mip.I[n, i] + mip.T[n, i]
                                     for i in range(m + 1)) + BigM1 *
                                 (1 - mip.y[n, m]))
                mip.reorder2.add(
                    mip.R1[n, m] >= mip.z[m] - sum(mip.I[n, i] + mip.T[n, i]
                                                   for i in range(m + 1)))
            mip.reorder3.add(mip.R1[n, m] <= BigM2 * mip.y[n, m])
            #reorder quantity constraints: R = min(c, I[m+1], R1)
            #last constraint ensures that only one of the 3 options is chosen
            # Note: R = min(A,B,C) <-> A + M*(1-y1) <= R <= A  ;  B + M*(1-y2) <= R <= B  ;  C + M*(1-y3) <= R <= C  ;  y1+y2+y3==1
            mip.reorder4.add(mip.R[n, m] <= mip.R1[n, m])
            mip.reorder5.add(mip.R[n, m] >= mip.R1[n, m] + BigM3 *
                             (1 - mip.y1[n, m]))
            mip.reorder6.add(mip.R[n, m] <= mip.supply_capacity[m])
            mip.reorder7.add(
                mip.R[n, m] >= mip.supply_capacity[m] * mip.y2[n, m])
            if (m < mip.m0[-1]) & (env.num_stages > 2):
                #if number of stages = 2, then there is no inventory constraint since the last level has unlimited inventory
                #also, last stage has unlimited inventory
                mip.reorder8.add(mip.R[n, m] <= mip.I[n, m + 1])
                mip.reorder9.add(mip.R[n, m] >= mip.I[n, m + 1] + BigM4 *
                                 (1 - mip.y3[n, m]))
                mip.reorder10.add(mip.y1[n, m] + mip.y2[n, m] +
                                  mip.y3[n, m] == 1)
            else:
                mip.reorder10.add(mip.y1[n, m] + mip.y2[n, m] == 1)

        for m in mip.m:
            if m == 0:
                #sales constraints: S = min(I + R[n-L], D + B[n-1]) at stage 0
                if n - mip.lead_time[m] >= 0:
                    mip.sales1.add(mip.S[n, m] <= mip.I[n, m] +
                                   mip.R[n - mip.lead_time[m], m])
                    mip.sales2.add(mip.S[n, m] >= mip.I[n, m] +
                                   mip.R[n - mip.lead_time[m], m] + BigM5 *
                                   (1 - mip.y4[n, m]))
                else:
                    mip.sales1.add(mip.S[n, m] <= mip.I[n, m])
                    mip.sales2.add(mip.S[n, m] >= mip.I[n, m] + BigM5 *
                                   (1 - mip.y4[n, m]))

                if (backlog) & (n - 1 >= 0):
                    mip.sales3.add(mip.S[n, m] <= mip.D[n] + mip.B[n - 1, m])
                    mip.sales4.add(mip.S[n, m] >= mip.D[n] + mip.B[n - 1, m] +
                                   BigM6 * mip.y4[n, m])
                else:
                    mip.sales3.add(mip.S[n, m] <= mip.D[n])
                    mip.sales4.add(
                        mip.S[n, m] >= mip.D[n] + BigM6 * mip.y4[n, m])
            else:
                #sales constraints: S = R[n,m-1] at higher level stages
                mip.sales5.add(mip.S[n, m] == mip.R[n, m - 1])

            if m == 0:
                #unfulfilled orders at stage 0: U = D + B[n-1] - S
                if backlog:
                    if n - 1 >= 0:
                        mip.unfulfilled.add(mip.B[n, m] == mip.D[n] +
                                            mip.B[n - 1, m] - mip.S[n, m])
                    else:
                        mip.unfulfilled.add(mip.B[n,
                                                  m] == mip.D[n] - mip.S[n, m])
                else:
                    mip.unfulfilled.add(mip.LS[n, m] == mip.D[n] - mip.S[n, m])
            else:
                #unfulfilled orders at stage higher level stages: U = R[n,m-1] + B[n-1,m] - S[n,m]
                if backlog:
                    if n - 1 >= 0:
                        mip.unfulfilled.add(mip.B[n, m] == mip.R[n, m - 1] +
                                            mip.B[n - 1, m] - mip.S[n, m])
                    else:
                        mip.unfulfilled.add(mip.B[n, m] == mip.R[n, m - 1] -
                                            mip.S[n, m])
                else:
                    mip.unfulfilled.add(mip.LS[n, m] == mip.R[n, m - 1] -
                                        mip.S[n, m])

    #objective function: maximize expected profit
    mip.obj = pe.Objective(expr=1 / mip.num_periods *
                           sum(mip.prob[n] * mip.P[n] for n in mip.n),
                           sense=pe.maximize)

    return mip
Esempio n. 20
0
    def sample_model(self, input_changes=None, fixed_outputs=None):
        import pyomo.environ as pyo
        from pyomo.opt import SolverFactory

        # Step 0: Create an instance of the model
        model = pyo.ConcreteModel()

        # Step 1: Define index sets
        time = range(8760)

        # Input Changes
        Names = ["CostPV", "CostBat", "CostBuy", "Demand"]
        Scaling = [1, 1, 1, 1, 1, 1, 1, 1, 1]
        if input_changes is not None:
            for i in range(Names.__len__()):
                try:
                    Scaling[i] = input_changes[Names[i]]
                except:
                    Scaling[i] = 1

        # Output Fixes
        Names = ["PVFixed", "BatteryFixed", "SelfProdRatioFixed", "TOTEXFixed", "CAPEXFixed"]
        Fixing = [-1, -1, -1, -1, -1, -1, -1, -1]
        if fixed_outputs is not None:
            for i in range(Names.__len__()):
                try:
                    Fixing[i] = fixed_outputs[Names[i]]
                except:
                    Fixing[i] = -1

        # Step 1.5: Parameters
        lifetime = self.Settings["lifetime"]  # years
        cost_PV = Scaling[0] * self.Settings["cost_PV"] / lifetime  # *((time[-1]+1)/8760) # € / (lifetime * kW)
        cost_Battery = Scaling[1] * self.Settings[
            "cost_Battery"] / lifetime  # *((time[-1]+1)/8760)  # € / (lifetime * kWh)
        cost_buy_ele = Scaling[2] * self.Settings["cost_buy"]  # €/kWh
        dem_tot = Scaling[3] * self.Settings["dem_tot"]  # kWh
        battery_in_eff = 1  # efficiency 100%

        import csv

        availability_pv = []  # create empty arrays
        DemandVal = []

        with open('TS_PVAvail.csv', 'r') as file:
            # next(file)
            reader = csv.reader(file, delimiter='\n')
            for row in reader:
                availability_pv.append(float(row[0]))

        with open('TS_Demand.csv', 'r') as file:
            # next(file)
            reader = csv.reader(file, delimiter='\n')
            for row in reader:
                DemandVal.append(float(row[0]))

        availability_pv = dict(enumerate(availability_pv))
        DemandVal = dict(enumerate(DemandVal))


        # Step 2: Define the decision

        # Electricity Sector
        model.EnergyPV = pyo.Var(time, within=pyo.NonNegativeReals)
        model.Demand = pyo.Var(time, within=pyo.NonNegativeReals)
        model.EnergyBattery = pyo.Var(time, within=pyo.NonNegativeReals)
        model.EnergyBattery_IN = pyo.Var(time, within=pyo.NonNegativeReals)
        model.EnergyBattery_OUT = pyo.Var(time, within=pyo.NonNegativeReals)
        model.EnergyBuy = pyo.Var(time, within=pyo.NonNegativeReals)
        model.CapacityPV = pyo.Var(within=pyo.NonNegativeReals)
        model.CapacityBattery = pyo.Var(within=pyo.NonNegativeReals)
        model.CostBuy = pyo.Var(within=pyo.Reals)
        model.CostPV = pyo.Var(within=pyo.Reals)
        model.CostBat = pyo.Var(within=pyo.Reals)

        # Step 3: Define Objective
        model.cost = pyo.Objective(expr=cost_PV * model.CapacityPV + cost_buy_ele * sum(
            model.EnergyBuy[i] for i in time) + cost_Battery * model.CapacityBattery, sense=pyo.minimize)

        # Step 4: Constraints
        model.limEQ = pyo.ConstraintList()

        for i in time:
            model.limEQ.add(model.EnergyPV[i] <= model.CapacityPV * availability_pv[i]) # PV Upper Limit

        for i in time:
            model.limEQ.add(model.EnergyBattery[i] <= model.CapacityBattery)  # Battery Upper Limit

        model.InitialBattery = pyo.Constraint(
            expr=model.EnergyBattery[0] == model.EnergyBattery[time[-1]] - model.EnergyBattery_OUT[0] +
                 model.EnergyBattery_IN[0])  # Battery level t=0 == t=T

        model.DemandEQ = pyo.ConstraintList()

        for i in time:
            model.DemandEQ.add(expr=model.Demand[i] == dem_tot * DemandVal[i])  # Electricity Demand

        model.batteryEQ = pyo.ConstraintList()

        for i in time[1:]:
            model.batteryEQ.add(
                expr=model.EnergyBattery[i] == model.EnergyBattery[i - 1] - model.EnergyBattery_OUT[i] +
                     model.EnergyBattery_IN[i])  # Battery Equation

        model.EnergyEQ = pyo.ConstraintList()
        for i in time:
            model.EnergyEQ.add(
                expr=model.Demand[i] == model.EnergyBuy[i] + model.EnergyBattery_OUT[i] - model.EnergyBattery_IN[
                    i] + model.EnergyPV[i])  # Energy Equation

        # Some equations that store input settings in a Variable
        model.ValueCostBuy = pyo.Constraint(expr=model.CostBuy == cost_buy_ele)
        model.ValueCostPV = pyo.Constraint(expr=model.CostPV == cost_PV)
        model.ValueCostBat = pyo.Constraint(expr=model.CostBat == cost_Battery)

        # Equations to fix outputs
        if Fixing[0] != -1:  # fixed PV Cap
            model.fixedPV = pyo.Constraint(expr=model.CapacityPV == Fixing[0])

        if Fixing[1] != -1:  # fixed Battery cap
            model.fixedBattery = pyo.Constraint(expr=model.CapacityBattery == Fixing[1])

        if Fixing[2] != -1:  # fixed Self Generation
            model.SelfProduction = pyo.Constraint(expr=sum(model.EnergyPV[i] for i in time) / dem_tot == Fixing[2])

        if Fixing[3] != -1:  # fixed TOTEX
            model.TOTEX = pyo.Constraint(expr=cost_PV * model.CapacityPV + cost_buy_ele * sum(
                model.EnergyBuy[i] for i in time) + cost_Battery * model.CapacityBattery == Fixing[3])

        if Fixing[4] != -1:  # fixed CAPEX
            model.CAPEX = pyo.Constraint(
                expr=cost_PV * model.CapacityPV + cost_Battery * model.CapacityBattery == Fixing[4])

        # Change lines below to use other solver
        solver_options = open("solverSettings.txt", "r").read().split("\n")
        for i in solver_options:
            if i.find('#') == 0 or i.__len__() == 0:
                val = 0  # comment or empty line: do nothing
            elif i.find('solver') == 0:
                val = i.split('=')
                val = val[1].strip()
                # set solver
                solver = SolverFactory(val)
            else:
                val = i.split('=')
                opt = val[0].strip()
                val = val[1].strip()
                try:
                    val2 = float(val)
                except ValueError:
                    val2 = val

                solver.options[opt] = val2

        results = solver.solve(model, tee=True, keepfiles=True)
        results.write()
        # Print full model to console. Only enable for debugging purpose
        # model.pprint()
        return model, results.solver.termination_condition
Esempio n. 21
0
    def test_linear_scaling(self):
        model = pyo.ConcreteModel()
        model.x = pyo.Var([1, 2, 3], bounds=(-10, 10), initialize=5.0)
        model.z = pyo.Var(bounds=(10, 20))
        model.obj = pyo.Objective(expr=model.z + model.x[1])

        # test scaling of duals as well
        model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
        model.rc = pyo.Suffix(direction=pyo.Suffix.IMPORT)

        def con_rule(m, i):
            if i == 1:
                return m.x[1] + 2 * m.x[2] + 1 * m.x[3] == 4.0
            if i == 2:
                return m.x[1] + 2 * m.x[2] + 2 * m.x[3] == 5.0
            if i == 3:
                return m.x[1] + 3.0 * m.x[2] + 1 * m.x[3] == 5.0

        model.con = pyo.Constraint([1, 2, 3], rule=con_rule)
        model.zcon = pyo.Constraint(expr=model.z >= model.x[2])

        x_scale = 0.5
        obj_scale = 2.0
        z_scale = -10.0
        con_scale1 = 0.5
        con_scale2 = 2.0
        con_scale3 = -5.0
        zcon_scale = -3.0

        unscaled_model = model.clone()
        unscaled_model.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
        unscaled_model.scaling_factor[unscaled_model.obj] = obj_scale
        unscaled_model.scaling_factor[unscaled_model.x] = x_scale
        unscaled_model.scaling_factor[unscaled_model.z] = z_scale
        unscaled_model.scaling_factor[unscaled_model.con[1]] = con_scale1
        unscaled_model.scaling_factor[unscaled_model.con[2]] = con_scale2
        unscaled_model.scaling_factor[unscaled_model.con[3]] = con_scale3
        unscaled_model.scaling_factor[unscaled_model.zcon] = zcon_scale

        scaled_model = pyo.TransformationFactory(
            'core.scale_model').create_using(unscaled_model)

        # print('*** unscaled ***')
        # unscaled_model.pprint()
        # print('*** scaled ***')
        # scaled_model.pprint()

        glpk_solver = pyo.SolverFactory('glpk')
        if isinstance(glpk_solver, UnknownSolver) or \
           (not glpk_solver.available()):
            raise unittest.SkipTest("glpk solver not available")

        glpk_solver.solve(unscaled_model)
        glpk_solver.solve(scaled_model)

        # check vars
        self.assertAlmostEqual(pyo.value(unscaled_model.x[1]),
                               pyo.value(scaled_model.scaled_x[1]) / x_scale,
                               4)
        self.assertAlmostEqual(pyo.value(unscaled_model.x[2]),
                               pyo.value(scaled_model.scaled_x[2]) / x_scale,
                               4)
        self.assertAlmostEqual(pyo.value(unscaled_model.x[3]),
                               pyo.value(scaled_model.scaled_x[3]) / x_scale,
                               4)
        self.assertAlmostEqual(pyo.value(unscaled_model.z),
                               pyo.value(scaled_model.scaled_z) / z_scale, 4)
        # check var lb
        self.assertAlmostEqual(
            pyo.value(unscaled_model.x[1].lb),
            pyo.value(scaled_model.scaled_x[1].lb) / x_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.x[2].lb),
            pyo.value(scaled_model.scaled_x[2].lb) / x_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.x[3].lb),
            pyo.value(scaled_model.scaled_x[3].lb) / x_scale, 4)
        # note: z_scale is negative, therefore, the inequality directions swap
        self.assertAlmostEqual(pyo.value(unscaled_model.z.lb),
                               pyo.value(scaled_model.scaled_z.ub) / z_scale,
                               4)
        # check var ub
        self.assertAlmostEqual(
            pyo.value(unscaled_model.x[1].ub),
            pyo.value(scaled_model.scaled_x[1].ub) / x_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.x[2].ub),
            pyo.value(scaled_model.scaled_x[2].ub) / x_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.x[3].ub),
            pyo.value(scaled_model.scaled_x[3].ub) / x_scale, 4)
        # note: z_scale is negative, therefore, the inequality directions swap
        self.assertAlmostEqual(pyo.value(unscaled_model.z.ub),
                               pyo.value(scaled_model.scaled_z.lb) / z_scale,
                               4)
        # check var multipliers (rc)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.rc[unscaled_model.x[1]]),
            pyo.value(scaled_model.rc[scaled_model.scaled_x[1]]) * x_scale /
            obj_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.rc[unscaled_model.x[2]]),
            pyo.value(scaled_model.rc[scaled_model.scaled_x[2]]) * x_scale /
            obj_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.rc[unscaled_model.x[3]]),
            pyo.value(scaled_model.rc[scaled_model.scaled_x[3]]) * x_scale /
            obj_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.rc[unscaled_model.z]),
            pyo.value(scaled_model.rc[scaled_model.scaled_z]) * z_scale /
            obj_scale, 4)
        # check constraint multipliers
        self.assertAlmostEqual(
            pyo.value(unscaled_model.dual[unscaled_model.con[1]]),
            pyo.value(scaled_model.dual[scaled_model.scaled_con[1]]) *
            con_scale1 / obj_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.dual[unscaled_model.con[2]]),
            pyo.value(scaled_model.dual[scaled_model.scaled_con[2]]) *
            con_scale2 / obj_scale, 4)
        self.assertAlmostEqual(
            pyo.value(unscaled_model.dual[unscaled_model.con[3]]),
            pyo.value(scaled_model.dual[scaled_model.scaled_con[3]]) *
            con_scale3 / obj_scale, 4)

        # put the solution from the scaled back into the original
        pyo.TransformationFactory('core.scale_model').propagate_solution(
            scaled_model, model)

        # compare var values and rc with the unscaled soln
        for vm in model.component_objects(ctype=pyo.Var, descend_into=True):
            cuid = pyo.ComponentUID(vm)
            vum = cuid.find_component_on(unscaled_model)
            self.assertEqual((vm in model.rc), (vum in unscaled_model.rc))
            if vm in model.rc:
                self.assertAlmostEqual(pyo.value(model.rc[vm]),
                                       pyo.value(unscaled_model.rc[vum]), 4)
            for k in vm:
                vmk = vm[k]
                vumk = vum[k]
                self.assertAlmostEqual(pyo.value(vmk), pyo.value(vumk), 4)
                self.assertEqual((vmk in model.rc),
                                 (vumk in unscaled_model.rc))
                if vmk in model.rc:
                    self.assertAlmostEqual(pyo.value(model.rc[vmk]),
                                           pyo.value(unscaled_model.rc[vumk]),
                                           4)

        # compare constraint duals and value
        for model_con in model.component_objects(ctype=pyo.Constraint,
                                                 descend_into=True):
            cuid = pyo.ComponentUID(model_con)
            unscaled_model_con = cuid.find_component_on(unscaled_model)
            self.assertEqual((model_con in model.rc),
                             (unscaled_model_con in unscaled_model.rc))
            if model_con in model.dual:
                self.assertAlmostEqual(
                    pyo.value(model.dual[model_con]),
                    pyo.value(unscaled_model.dual[unscaled_model_con]), 4)
            for k in model_con:
                mk = model_con[k]
                umk = unscaled_model_con[k]
                self.assertEqual((mk in model.dual),
                                 (umk in unscaled_model.dual))
                if mk in model.dual:
                    self.assertAlmostEqual(pyo.value(model.dual[mk]),
                                           pyo.value(unscaled_model.dual[umk]),
                                           4)
Esempio n. 22
0
def pysp_instance_creation_callback(scenario_name,
                                    use_integer=False,
                                    sense=pyo.minimize,
                                    crops_multiplier=1):
    # long function to create the entire model
    # scenario_name is a string (e.g. AboveAverageScenario0)
    #
    # Returns a concrete model for the specified scenario

    # scenarios come in groups of three
    scengroupnum = sputils.extract_num(scenario_name)
    scenario_base_name = scenario_name.rstrip("0123456789")

    model = pyo.ConcreteModel()

    def crops_init(m):
        retval = []
        for i in range(crops_multiplier):
            retval.append("WHEAT" + str(i))
            retval.append("CORN" + str(i))
            retval.append("SUGAR_BEETS" + str(i))
        return retval

    model.CROPS = pyo.Set(initialize=crops_init)

    #
    # Parameters
    #

    model.TOTAL_ACREAGE = 500.0 * crops_multiplier

    def _scale_up_data(indict):
        outdict = {}
        for i in range(crops_multiplier):
            for crop in ['WHEAT', 'CORN', 'SUGAR_BEETS']:
                outdict[crop + str(i)] = indict[crop]
        return outdict

    model.PriceQuota = _scale_up_data({
        'WHEAT': 100000.0,
        'CORN': 100000.0,
        'SUGAR_BEETS': 6000.0
    })

    model.SubQuotaSellingPrice = _scale_up_data({
        'WHEAT': 170.0,
        'CORN': 150.0,
        'SUGAR_BEETS': 36.0
    })

    model.SuperQuotaSellingPrice = _scale_up_data({
        'WHEAT': 0.0,
        'CORN': 0.0,
        'SUGAR_BEETS': 10.0
    })

    model.CattleFeedRequirement = _scale_up_data({
        'WHEAT': 200.0,
        'CORN': 240.0,
        'SUGAR_BEETS': 0.0
    })

    model.PurchasePrice = _scale_up_data({
        'WHEAT': 238.0,
        'CORN': 210.0,
        'SUGAR_BEETS': 100000.0
    })

    model.PlantingCostPerAcre = _scale_up_data({
        'WHEAT': 150.0,
        'CORN': 230.0,
        'SUGAR_BEETS': 260.0
    })

    #
    # Stochastic Data
    #
    Yield = {}
    Yield['BelowAverageScenario'] = \
        {'WHEAT':2.0,'CORN':2.4,'SUGAR_BEETS':16.0}
    Yield['AverageScenario'] = \
        {'WHEAT':2.5,'CORN':3.0,'SUGAR_BEETS':20.0}
    Yield['AboveAverageScenario'] = \
        {'WHEAT':3.0,'CORN':3.6,'SUGAR_BEETS':24.0}

    def Yield_init(m, cropname):
        # yield as in "crop yield"
        crop_base_name = cropname.rstrip("0123456789")
        if scengroupnum != 0:
            return Yield[scenario_base_name][
                crop_base_name] + farmerstream.rand()
        else:
            return Yield[scenario_base_name][crop_base_name]

    model.Yield = pyo.Param(model.CROPS,
                            within=pyo.NonNegativeReals,
                            initialize=Yield_init,
                            mutable=True)

    #
    # Variables
    #

    if (use_integer):
        model.DevotedAcreage = pyo.Var(model.CROPS,
                                       within=pyo.NonNegativeIntegers,
                                       bounds=(0.0, model.TOTAL_ACREAGE))
    else:
        model.DevotedAcreage = pyo.Var(model.CROPS,
                                       bounds=(0.0, model.TOTAL_ACREAGE))

    model.QuantitySubQuotaSold = pyo.Var(model.CROPS, bounds=(0.0, None))
    model.QuantitySuperQuotaSold = pyo.Var(model.CROPS, bounds=(0.0, None))
    model.QuantityPurchased = pyo.Var(model.CROPS, bounds=(0.0, None))

    #
    # Constraints
    #

    def ConstrainTotalAcreage_rule(model):
        return pyo.sum_product(model.DevotedAcreage) <= model.TOTAL_ACREAGE

    model.ConstrainTotalAcreage = pyo.Constraint(
        rule=ConstrainTotalAcreage_rule)

    def EnforceCattleFeedRequirement_rule(model, i):
        return model.CattleFeedRequirement[i] <= (
            model.Yield[i] * model.DevotedAcreage[i]
        ) + model.QuantityPurchased[i] - model.QuantitySubQuotaSold[
            i] - model.QuantitySuperQuotaSold[i]

    model.EnforceCattleFeedRequirement = pyo.Constraint(
        model.CROPS, rule=EnforceCattleFeedRequirement_rule)

    def LimitAmountSold_rule(model, i):
        return model.QuantitySubQuotaSold[i] + model.QuantitySuperQuotaSold[
            i] - (model.Yield[i] * model.DevotedAcreage[i]) <= 0.0

    model.LimitAmountSold = pyo.Constraint(model.CROPS,
                                           rule=LimitAmountSold_rule)

    def EnforceQuotas_rule(model, i):
        return (0.0, model.QuantitySubQuotaSold[i], model.PriceQuota[i])

    model.EnforceQuotas = pyo.Constraint(model.CROPS, rule=EnforceQuotas_rule)

    # Stage-specific cost computations;

    def ComputeFirstStageCost_rule(model):
        return pyo.sum_product(model.PlantingCostPerAcre, model.DevotedAcreage)

    model.FirstStageCost = pyo.Expression(rule=ComputeFirstStageCost_rule)

    def ComputeSecondStageCost_rule(model):
        expr = pyo.sum_product(model.PurchasePrice, model.QuantityPurchased)
        expr -= pyo.sum_product(model.SubQuotaSellingPrice,
                                model.QuantitySubQuotaSold)
        expr -= pyo.sum_product(model.SuperQuotaSellingPrice,
                                model.QuantitySuperQuotaSold)
        return expr

    model.SecondStageCost = pyo.Expression(rule=ComputeSecondStageCost_rule)

    def total_cost_rule(model):
        if (sense == pyo.minimize):
            return model.FirstStageCost + model.SecondStageCost
        return -model.FirstStageCost - model.SecondStageCost

    model.Total_Cost_Objective = pyo.Objective(rule=total_cost_rule,
                                               sense=sense)

    return model
Esempio n. 23
0
    def test_pow_neg(self):
        m = pe.ConcreteModel()
        m.x = pe.Var(bounds=(-1,1))
        m.y = pe.Var()
        m.z = pe.Var()
        m.w = pe.Var()
        m.p = pe.Param(initialize=-2)
        m.c = pe.Constraint(expr=m.x**m.p + m.y + m.z == 0)
        m.c2 = pe.Constraint(expr=m.w - 3*m.x**m.p == 0)

        rel = coramin.relaxations.relax(m)

        # This model should be relaxed to
        #
        # aux2 + y + z = 0
        # w - 3 * aux2 = 0
        # aux1 = x**2
        # aux1*aux2 = aux3
        # aux3 = 1
        #

        self.assertTrue(hasattr(rel, 'aux_cons'))
        self.assertTrue(hasattr(rel, 'aux_vars'))
        self.assertEqual(len(rel.aux_cons), 2)
        self.assertEqual(len(rel.aux_vars), 3)

        self.assertAlmostEqual(rel.aux_vars[1].lb, 0)
        self.assertAlmostEqual(rel.aux_vars[1].ub, 1)

        self.assertTrue(rel.aux_vars[3].is_fixed())
        self.assertEqual(rel.aux_vars[3].value, 1)

        self.assertEqual(rel.aux_cons[1].lower, 0)
        self.assertEqual(rel.aux_cons[1].upper, 0)
        ders = reverse_sd(rel.aux_cons[1].body)
        self.assertEqual(ders[rel.z], 1)
        self.assertEqual(ders[rel.aux_vars[2]], 1)
        self.assertEqual(ders[rel.y], 1)
        self.assertEqual(len(list(identify_variables(rel.aux_cons[1].body))), 3)

        self.assertEqual(rel.aux_cons[2].lower, 0)
        self.assertEqual(rel.aux_cons[2].upper, 0)
        ders = reverse_sd(rel.aux_cons[2].body)
        self.assertEqual(ders[rel.w], 1)
        self.assertEqual(ders[rel.aux_vars[2]], -3)
        self.assertEqual(len(list(identify_variables(rel.aux_cons[2].body))), 2)

        self.assertTrue(hasattr(rel, 'relaxations'))
        self.assertTrue(hasattr(rel.relaxations, 'rel0'))
        self.assertTrue(isinstance(rel.relaxations.rel0, coramin.relaxations.PWXSquaredRelaxation))
        self.assertIn(rel.x, ComponentSet(rel.relaxations.rel0.get_rhs_vars()))
        self.assertEqual(id(rel.aux_vars[1]), id(rel.relaxations.rel0.get_aux_var()))
        self.assertTrue(rel.relaxations.rel0.is_rhs_convex())
        self.assertFalse(rel.relaxations.rel0.is_rhs_concave())

        self.assertTrue(hasattr(rel.relaxations, 'rel1'))
        self.assertTrue(isinstance(rel.relaxations.rel1, coramin.relaxations.PWMcCormickRelaxation))
        self.assertIn(rel.aux_vars[1], ComponentSet(rel.relaxations.rel1.get_rhs_vars()))
        self.assertIn(rel.aux_vars[2], ComponentSet(rel.relaxations.rel1.get_rhs_vars()))
        self.assertEqual(id(rel.aux_vars[3]), id(rel.relaxations.rel1.get_aux_var()))

        self.assertFalse(hasattr(rel.relaxations, 'rel2'))
Esempio n. 24
0
def create_model(spt):
    norm_spt = spt / np.max(spt)

    m = po.ConcreteModel()

    """ Sets """
    m.i = po.Set(initialize=["A", "B", "C"])
    m.j = po.Set(initialize=[1, 2])

    """ Time Components """
    m.t = pod.ContinuousSet(bounds=(0, 1), initialize=norm_spt)
    m.tau = po.Var(bounds=(0, None))

    """ Concentrations """
    m.c = po.Var(m.t, m.i, bounds=(0, None))
    m.dcdt = pod.DerivativeVar(m.c, wrt=m.t)

    """ Experimental Variables """
    m.f_in = po.Var(bounds=(0, 10))
    m.T = po.Var(bounds=(273.15, 323.15))

    """ Reaction Parameters """
    s = {
        ("A", 1): -1,
        ("B", 1):  1,
        ("C", 1):  0,

        ("A", 2):  0,
        ("B", 2): -1,
        ("C", 2):  1,
    }
    m.s = po.Param(m.i, m.j, initialize=s)
    c_in = {
        "A": 1,
        "B": 0,
        "C": 0,
    }
    m.c_in = po.Param(m.i, initialize=c_in)

    """ Model Parameters """
    m.k = po.Var(m.j, bounds=(0, None))
    m.theta0 = po.Var(m.j)
    m.theta1 = po.Var(m.j)

    """ Reaction Rates """
    m.r = po.Var(m.t, m.j)

    """ Model Equations """
    def _bal(m, t, i):
        return m.dcdt[t, i] / m.tau == m.f_in * m.c_in[i] + sum(m.s[i, j] * m.r[t, j] for j in m.j)
    m.bal = po.Constraint(m.t, m.i, rule=_bal)

    def _r_def(m, t, j):
        if j == 1:
            return m.r[t, j] == po.exp(m.theta0[j] + m.theta1[j] * (m.T - 273.15) / m.T) * m.c[t, "A"]
        elif j == 2:
            return m.r[t, j] == po.exp(m.theta0[j] + m.theta1[j] * (m.T - 273.15) / m.T) * m.c[t, "B"]
        else:
            raise SyntaxError("Unrecognized reaction index, please check the model.")
    m.r_def = po.Constraint(m.t, m.j, rule=_r_def)

    return m
Esempio n. 25
0
def scenario_creator(
    scenario_name,
    solar_filname=None,
    use_LP=False,
    lam=None,
):
    """
    Args:
        scenario_name (str):
            Name of the scenario to create.
        solar_filename (str):
            File containing the solar data.
        use_LP (bool, optional):
            If True, uses LP. Default is False.
        lam (float):
            Value of the dual variable for the chance constraint.
    """
    if 'solar_filename' is None:
        raise ValueError("kwarg `solar_filename` is required")
    if 'lam' is None:
        raise RuntimeError("kwarg `lam` is required")

    data = getData(solar_filename)
    num_scenarios = data['solar'].shape[0]
    scenario_index = extract_scenario_index(scenario_name)
    if (scenario_index < 0) or (scenario_index >= num_scenarios):
        raise RuntimeError('Provided scenario index is invalid (must lie in '
                           '{0,1,...' + str(num_scenarios - 1) +
                           '} inclusive)')
    model = pyo.ConcreteModel()

    T = range(data['T'])
    Tm1 = range(data['T'] - 1)

    model.y = pyo.Var(T, within=pyo.NonNegativeReals)
    model.p = pyo.Var(T, bounds=(0, data['cMax']))
    model.q = pyo.Var(T, bounds=(0, data['dMax']))
    model.x = pyo.Var(T, bounds=(data['eMin'], data['eMax']))
    if (use_LP):
        model.z = pyo.Var([0], within=pyo.UnitInterval)
    else:
        model.z = pyo.Var([0], within=pyo.Binary)
    ''' "Flow balance" constraints '''
    def flow_balance_constraint_rule(model, t):
        return model.x[t+1]==model.x[t] + \
            data['eff'] * model.p[t] - (1/data['eff']) * model.q[t]

    model.flow_constr = pyo.Constraint(Tm1, rule=flow_balance_constraint_rule)
    ''' Big-M constraints '''

    def big_M_constraint_rule(model, t):
        return model.y[t] - model.q[t] + model.p[t] \
            <= data['solar'][scenario_index,t] + \
            data['M'][scenario_index,t] * model.z[0] # Why indexed??

    model.big_m_constr = pyo.Constraint(T, rule=big_M_constraint_rule)
    ''' Objective function (must be minimization or PH crashes) '''
    model.obj = pyo.Objective(expr=-pyo.dot_product(data['rev'], model.y) +
                              data['char'] * pyo.quicksum(model.p) +
                              data['disc'] * pyo.quicksum(model.q) +
                              lam * model.z[0],
                              sense=pyo.minimize)

    fscr = lambda model: pyo.dot_product(data['rev'], model.y)
    model.first_stage_cost = pyo.Expression(rule=fscr)

    model._PySPnode_list = [
        stree.ScenarioNode(name='ROOT',
                           cond_prob=1.,
                           stage=1,
                           cost_expression=model.first_stage_cost,
                           scen_name_list=None,
                           nonant_list=[model.y],
                           scen_model=model)
    ]

    return model
Esempio n. 26
0
 def test_no_objective(self):
     m = pyo.ConcreteModel()
     m.x = pyo.Var()
     m.c = pyo.Constraint(expr=2.0 * m.x >= 5)
     with self.assertRaises(NotImplementedError):
         nlp = PyomoNLP(m)
Esempio n. 27
0
 def create_master():
     m = pe.ConcreteModel()
     m.y = pe.Var(bounds=(1, None))
     m.eta = pe.Var(bounds=(-10, None))
     m.obj = pe.Objective(expr=m.y**2 + m.eta)
     return m
Esempio n. 28
0
    def pyomosim(data):
        # Define rate parameters
        kco = 35
        kst = 1.5
        sparam = 1.0
        flow = 1.0
        vol = 1.0
        gc = .008314
        # Define kinetic rate parameters
        k = params[0]
        E = params[1]
        # define UB for concentration
        #nound_ub = 20
        # pyomo solver options
        opt = pyo.SolverFactory('baron')
        cracmodel = pyo.ConcreteModel()
        ca0, cb0, cc0, cd0, cf0, cg0, ch0, ci0, cj0, T = [
            float(v) for v in data
        ]

        bound_ub = 100.0
        # Define cracmodel variables
        # A = Eb , B = St , C = Bz , D = Et, E = Tl, F = Me, G = Water, H = H2 I = CO2, J = N2
        cracmodel.a = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=ca0)
        cracmodel.b = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=cb0)
        cracmodel.c = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=cc0)
        cracmodel.d = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=cd0)
        cracmodel.f = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=cf0)
        cracmodel.g = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=cg0)
        cracmodel.h = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=ch0)
        cracmodel.i = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=ci0)
        cracmodel.j = pyo.Var(domain=pyo.NonNegativeReals,
                              bounds=(0, bound_ub),
                              initialize=cj0)
        cracmodel.r1 = pyo.Var(domain=pyo.Reals)
        cracmodel.r2 = pyo.Var(domain=pyo.Reals)
        cracmodel.r4 = pyo.Var(domain=pyo.Reals)
        cracmodel.r5 = pyo.Var(domain=pyo.Reals)

        def keq(T):
            return pyo.exp(0.1 + (300 / T))
#            return pyo.exp(-1.0*(122700-126.3*T-0.002194*T**2)/(gc*T)) * sparam
# define reaction rate variable

        def fr1(cracmodel):
            # A <> B + H
            return cracmodel.r1 == k[0] * pyo.exp(-(E[0] / (gc)) * (
                (1 / T) -
                (1 / Tr))) * (cracmodel.a -
                              (cracmodel.b * cracmodel.h) / keq(T)) * (1.0 / (
                                  (1 + kst * cracmodel.b) *
                                  (1 + kco * cracmodel.i)))

        def fr2(cracmodel):
            # A > C + D
            return cracmodel.r2 == k[1] * pyo.exp(-(E[1] / (gc)) * (
                (1 / T) - (1 / Tr))) * cracmodel.a * (1.0 /
                                                      (1 + kco * cracmodel.i))

        def fr4(cracmodel):
            # D + 2H > 2F
            return cracmodel.r4 == k[2] * pyo.exp(-(E[2] / (gc)) * (
                (1 / T) - (1 / Tr))) * cracmodel.d * cracmodel.h

        def fr5(cracmodel):
            # F+G > I + 4H
            return cracmodel.r5 == k[3] * pyo.exp(-(E[3] / (gc)) * (
                (1 / T) - (1 / Tr))) * cracmodel.f * cracmodel.g

        cracmodel.er1 = pyo.Constraint(rule=fr1)
        cracmodel.er2 = pyo.Constraint(rule=fr2)
        cracmodel.er4 = pyo.Constraint(rule=fr4)
        cracmodel.er5 = pyo.Constraint(rule=fr5)
        cracmodel.sets = pyo.RangeSet(9)
        cracmodel.dum = pyo.Var(cracmodel.sets, domain=pyo.Reals)

        def fra(cracmodel):  # A - 1,2,3
            return cracmodel.dum[
                1] == ca0 - cracmodel.a - cracmodel.r1 - cracmodel.r2

        def frb(cracmodel):  # B - 1
            return cracmodel.dum[2] == cb0 - cracmodel.b + cracmodel.r1

        def frc(cracmodel):  # C - 2
            return cracmodel.dum[3] == cc0 - cracmodel.c + cracmodel.r2

        def frd(cracmodel):  # D - 2,4
            return cracmodel.dum[
                4] == cd0 - cracmodel.d + cracmodel.r2 - cracmodel.r4

        def frf(cracmodel):  # F - 3,4,5
            return cracmodel.dum[
                5] == cf0 - cracmodel.f + 2 * cracmodel.r4 - cracmodel.r5

        def frg(cracmodel):  # G - 5
            return cracmodel.dum[6] == cg0 - cracmodel.g - 2 * cracmodel.r5

        def frh(cracmodel):  # H - 1,3,4,5
            return cracmodel.dum[
                7] == ch0 - cracmodel.h + cracmodel.r1 - 2 * cracmodel.r4 + 4 * cracmodel.r5

        def fri(cracmodel):  # I - 5
            return cracmodel.dum[8] == ci0 - cracmodel.i + cracmodel.r5

        def frj(cracmodel):  # J - N2 is inert
            return cracmodel.dum[9] == cj0 - cracmodel.j

        cracmodel.era = pyo.Constraint(rule=fra)
        cracmodel.erb = pyo.Constraint(rule=frb)
        cracmodel.erc = pyo.Constraint(rule=frc)
        cracmodel.erd = pyo.Constraint(rule=frd)
        cracmodel.erf = pyo.Constraint(rule=frf)
        cracmodel.erg = pyo.Constraint(rule=frg)
        cracmodel.erh = pyo.Constraint(rule=frh)
        cracmodel.eri = pyo.Constraint(rule=fri)
        cracmodel.erj = pyo.Constraint(rule=frj)

        # minimize square of dummy variables to find steady-state concentrations
        def objf(cracmodel):
            return sum(cracmodel.dum[s]**2 for s in cracmodel.sets)

        cracmodel.OBJ = pyo.Objective(rule=objf)
        results = opt.solve(cracmodel)
        cracmodel.solutions.store_to(results)
        klist = ['a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j']
        # Add noise of the specifiec SNR, noise has variance eps ~ N(0,noise*conc)
        vn = [
            results.Solution.Variable[key]['Value'] + np.random.normal(
                0, noise * results.Solution.Variable[key]['Value'])
            for key in klist
        ]
        return vn
def test_power_plant_costing():
    # Create a Concrete Model as the top level object
    m = pyo.ConcreteModel()

    # Add a flowsheet object to the model
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.get_costing(year='2018')

    ###########################################################################
    #  Create costing constraints                                             #
    ###########################################################################

    # subcritical PC
    coal_accounts = ['1.1', '1.2', '1.3']
    m.fs.subcritical_PC = pyo.Block()
    m.fs.subcritical_PC.coal_feed_rate = pyo.Var(initialize=7613.37)  # tpd
    m.fs.subcritical_PC.coal_feed_rate.fix()
    get_PP_costing(m.fs.subcritical_PC, coal_accounts,
                   m.fs.subcritical_PC.coal_feed_rate, 'tpd', 1)

    # two-stage, slurry-feed IGCC
    feedwater_accounts = ['3.1', '3.3', '3.5']
    m.fs.IGCC_1 = pyo.Block()
    m.fs.IGCC_1.feedwater_flow_rate = pyo.Var(initialize=1576062.15)  # lb/hr
    m.fs.IGCC_1.feedwater_flow_rate.fix()
    get_PP_costing(m.fs.IGCC_1, feedwater_accounts,
                   m.fs.IGCC_1.feedwater_flow_rate, 'lb/hr', 3)

    # single-stage, slurry-feed, IGCC
    syngas_accounts = ['6.1', '6.2', '6.3']
    m.fs.IGCC_2 = pyo.Block()
    m.fs.IGCC_2.syngas_flow_rate = pyo.Var(initialize=182335.921)  # lb/hr
    m.fs.IGCC_2.syngas_flow_rate.fix()
    get_PP_costing(m.fs.IGCC_2, syngas_accounts, m.fs.IGCC_2.syngas_flow_rate,
                   'lb/hr', 4)

    # single-stage, dry-feed, IGCC
    HRSG_accounts = ['7.1', '7.2']
    m.fs.IGCC_3 = pyo.Block()
    m.fs.IGCC_3.HRSG_duty = pyo.Var(initialize=1777.86)  # MMBtu/hr
    m.fs.IGCC_3.HRSG_duty.fix()
    get_PP_costing(m.fs.IGCC_3, HRSG_accounts, m.fs.IGCC_3.HRSG_duty,
                   'MMBtu/hr', 5)

    # NGCC
    steam_turbine_accounts = ['8.1', '8.2', '8.5']
    m.fs.NGCC = pyo.Block()
    m.fs.NGCC.turbine_power = pyo.Var(initialize=212500)  # kW
    m.fs.NGCC.turbine_power.fix()
    get_PP_costing(m.fs.NGCC, steam_turbine_accounts, m.fs.NGCC.turbine_power,
                   'kW', 6)

    # AUSC PC
    AUSC_accounts = ['4.9', '8.4']
    m.fs.AUSC = pyo.Block()
    m.fs.AUSC.feedwater_flow = pyo.Var(initialize=3298815.58)  # lb/hr
    m.fs.AUSC.feedwater_flow.fix()
    get_PP_costing(m.fs.AUSC, AUSC_accounts, m.fs.AUSC.feedwater_flow, 'lb/hr',
                   7)

    # add total cost
    build_flowsheet_cost_constraint(m)

    # add initialize
    costing_initialization(m.fs)

    # try solving
    solver = pyo.SolverFactory('ipopt')
    results = solver.solve(m, tee=True)

    assert results.solver.termination_condition == \
        pyo.TerminationCondition.optimal
    #  all numbers come from the NETL excel file
    # "201.001.001_BBR4 COE Spreadsheet_Rev0U_20190919_njk.xlsm"
    assert pytest.approx(pyo.value(
        m.fs.subcritical_PC.costing.total_plant_cost['1.1']),
                         abs=1e-1) == 2379 / 1e3
    assert pytest.approx(pyo.value(
        m.fs.subcritical_PC.costing.total_plant_cost['1.2']),
                         abs=1e-1) == 6588 / 1e3
    assert pytest.approx(pyo.value(
        m.fs.subcritical_PC.costing.total_plant_cost['1.3']),
                         abs=1e-1) == 61409 / 1e3

    assert pytest.approx(pyo.value(
        m.fs.IGCC_1.costing.total_plant_cost['3.1']),
                         abs=1e-1) == 10807 / 1e3
    assert pytest.approx(pyo.value(
        m.fs.IGCC_1.costing.total_plant_cost['3.3']),
                         abs=1e-1) == 2564 / 1e3
    assert pytest.approx(pyo.value(
        m.fs.IGCC_1.costing.total_plant_cost['3.5']),
                         abs=1e-1) == 923 / 1e3

    assert pytest.approx(pyo.value(
        m.fs.IGCC_2.costing.total_plant_cost['6.1']),
                         abs=1e-1) == 117850 / 1e3
    assert pytest.approx(pyo.value(
        m.fs.IGCC_2.costing.total_plant_cost['6.2']),
                         abs=1e-1) == 3207 / 1e3
    assert pytest.approx(pyo.value(
        m.fs.IGCC_2.costing.total_plant_cost['6.3']),
                         abs=1e-1) == 3770 / 1e3

    assert pytest.approx(pyo.value(
        m.fs.IGCC_3.costing.total_plant_cost['7.1']),
                         abs=1e-1) == 53530 / 1e3
    assert pytest.approx(pyo.value(
        m.fs.IGCC_3.costing.total_plant_cost['7.2']),
                         abs=1e-1) == 19113 / 1e3

    assert pytest.approx(pyo.value(m.fs.NGCC.costing.total_plant_cost['8.1']),
                         abs=1e-1) == 49468 / 1e3
    assert pytest.approx(pyo.value(m.fs.NGCC.costing.total_plant_cost['8.2']),
                         abs=1e-1) == 565 / 1e3
    assert pytest.approx(pyo.value(m.fs.NGCC.costing.total_plant_cost['8.5']),
                         abs=1e-1) == 4094 / 1e3

    assert pytest.approx(pyo.value(m.fs.AUSC.costing.bare_erected_cost['4.9']),
                         abs=1e-1) == 295509 / 1e3
    assert pytest.approx(pyo.value(m.fs.AUSC.costing.bare_erected_cost['8.4']),
                         abs=1e-1) == 57265 / 1e3

    return m
Esempio n. 30
0
    def declareOptimizationProblem(self, timeSeriesAggregation=False):
        """
        Declare the optimization problem belonging to the specified energy system for which a pyomo concrete model
        instance is built and filled with
        * basic time sets,
        * sets, variables and constraints contributed by the component modeling classes,
        * basic, component overreaching constraints, and
        * an objective function.

        **Default arguments:**

        :param timeSeriesAggregation: states if the optimization of the energy system model should be done with
            (a) the full time series (False) or
            (b) clustered time series data (True).
            |br| * the default value is False
        :type timeSeriesAggregation: boolean

        Last edited: November 10, 2018
        |br| @author: Lara Welder
        """
        # Get starting time of the optimization to, later on, obtain the total run time of the optimize function call
        timeStart = time.time()

        # Check correctness of inputs
        utils.checkDeclareOptimizationProblemInput(
            timeSeriesAggregation, self.isTimeSeriesDataClustered)

        ################################################################################################################
        #                           Initialize mathematical model (ConcreteModel) instance                             #
        ################################################################################################################

        # Initialize a pyomo ConcreteModel which will be used to store the mathematical formulation of the model.
        # The ConcreteModel instance is stored in the EnergySystemModel instance, which makes it available for
        # post-processing or debugging. A pyomo Suffix with the name dual is declared to make dual values associated
        # to the model's constraints available after optimization.
        self.pyM = pyomo.ConcreteModel()
        pyM = self.pyM
        pyM.dual = pyomo.Suffix(direction=pyomo.Suffix.IMPORT)

        # Set time sets for the model instance
        self.declareTimeSets(pyM, timeSeriesAggregation)

        ################################################################################################################
        #                         Declare component specific sets, variables and constraints                           #
        ################################################################################################################

        for key, mdl in self.componentModelingDict.items():
            _t = time.time()
            utils.output(
                'Declaring sets, variables and constraints for ' + key,
                self.verbose, 0)
            utils.output('\tdeclaring sets... ', self.verbose,
                         0), mdl.declareSets(self, pyM)
            utils.output('\tdeclaring variables... ', self.verbose,
                         0), mdl.declareVariables(self, pyM)
            utils.output('\tdeclaring constraints... ', self.verbose,
                         0), mdl.declareComponentConstraints(self, pyM)
            utils.output('\t\t(%.4f' % (time.time() - _t) + ' sec)\n',
                         self.verbose, 0)

        ################################################################################################################
        #                              Declare cross-componential sets and constraints                                 #
        ################################################################################################################

        # Declare constraints for enforcing shared capacities
        _t = time.time()
        self.declareSharedPotentialConstraints(pyM)
        utils.output('\t\t(%.4f' % (time.time() - _t) + ' sec)\n',
                     self.verbose, 0)

        # Declare commodity balance constraints (one balance constraint for each commodity, location and time step)
        _t = time.time()
        self.declareCommodityBalanceConstraints(pyM)
        utils.output('\t\t(%.4f' % (time.time() - _t) + ' sec)\n',
                     self.verbose, 0)

        ################################################################################################################
        #                                         Declare objective function                                           #
        ################################################################################################################

        # Declare objective function by obtaining the contributions to the objective function from all modeling classes
        _t = time.time()
        self.declareObjective(pyM)
        utils.output('\t\t(%.4f' % (time.time() - _t) + ' sec)\n',
                     self.verbose, 0)

        # Store the build time of the optimize function call in the EnergySystemModel instance
        self.solverSpecs['buildtime'] = time.time() - timeStart