diff --git a/examples/dae/Heat_Conduction.py b/examples/dae/Heat_Conduction.py index c928ee2e899..11f35fddd13 100644 --- a/examples/dae/Heat_Conduction.py +++ b/examples/dae/Heat_Conduction.py @@ -15,37 +15,49 @@ from pyomo.dae import * m = ConcreteModel() -m.time = ContinuousSet(bounds=(0,1)) -m.x = ContinuousSet(bounds=(0,10)) -m.y = ContinuousSet(bounds=(0,5)) -m.T = Var(m.x,m.y,m.time) -m.u = Var(m.x,m.y,m.time) +m.time = ContinuousSet(bounds=(0, 1)) +m.x = ContinuousSet(bounds=(0, 10)) +m.y = ContinuousSet(bounds=(0, 5)) +m.T = Var(m.x, m.y, m.time) +m.u = Var(m.x, m.y, m.time) m.T0 = Param(initialize=5) -m.TD = Param(m.x,m.y,initialize=25) +m.TD = Param(m.x, m.y, initialize=25) m.Ux0 = Param(initialize=10) m.Uy5 = Param(initialize=15) -m.dTdx = DerivativeVar(m.T,wrt=m.x) -m.d2Tdx2 = DerivativeVar(m.T,wrt=(m.x,m.x)) -m.dTdy = DerivativeVar(m.T,wrt=m.y) -m.d2Tdy2 = DerivativeVar(m.T,wrt=(m.y,m.y)) -m.dTdt = DerivativeVar(m.T,wrt=m.time) +m.dTdx = DerivativeVar(m.T, wrt=m.x) +m.d2Tdx2 = DerivativeVar(m.T, wrt=(m.x, m.x)) +m.dTdy = DerivativeVar(m.T, wrt=m.y) +m.d2Tdy2 = DerivativeVar(m.T, wrt=(m.y, m.y)) +m.dTdt = DerivativeVar(m.T, wrt=m.time) -def _heateq(m,i,j,k): - return m.d2Tdx2[i,j,k] + m.d2Tdy2[i,j,k] + m.u[i,j,k] == m.dTdt[i,j,k] -m.heateq = Constraint(m.x,m.y,m.time,rule=_heateq) -def _initT(m,i,j): - return m.T[i,j,0] == m.T0 -m.initT = Constraint(m.x,m.y,rule=_initT) +def _heateq(m, i, j, k): + return m.d2Tdx2[i, j, k] + m.d2Tdy2[i, j, k] + m.u[i, j, k] == m.dTdt[i, j, k] -def _xbound(m,j,k): - return m.dTdx[0,j,k] == m.Ux0 -m.xbound = Constraint(m.y,m.time,rule=_xbound) -def _ybound(m,i,k): - return m.dTdy[i,5,k] == m.Uy5 -m.ybound = Constraint(m.x,m.time,rule=_ybound) +m.heateq = Constraint(m.x, m.y, m.time, rule=_heateq) + + +def _initT(m, i, j): + return m.T[i, j, 0] == m.T0 + + +m.initT = Constraint(m.x, m.y, rule=_initT) + + +def _xbound(m, j, k): + return m.dTdx[0, j, k] == m.Ux0 + + +m.xbound = Constraint(m.y, m.time, rule=_xbound) + + +def _ybound(m, i, k): + return m.dTdy[i, 5, k] == m.Uy5 + + +m.ybound = Constraint(m.x, m.time, rule=_ybound) # def _intExp(m,i,j): # return m.T[i,j,1] - m.TD[i,j] diff --git a/examples/dae/Optimal_Control.py b/examples/dae/Optimal_Control.py index f3b1b8bed16..ed44d5eeb59 100644 --- a/examples/dae/Optimal_Control.py +++ b/examples/dae/Optimal_Control.py @@ -11,20 +11,20 @@ # Sample Problem 1 (Ex 1 from Dynopt Guide) # -# min X2(tf) -# s.t. X1_dot = u X1(0) = 1 -# X2_dot = X1^2 + u^2 X2(0) = 0 -# tf = 1 +# min X2(tf) +# s.t. X1_dot = u X1(0) = 1 +# X2_dot = X1^2 + u^2 X2(0) = 0 +# tf = 1 from pyomo.environ import * from pyomo.dae import * m = ConcreteModel() -m.t = ContinuousSet(bounds=(0,1)) +m.t = ContinuousSet(bounds=(0, 1)) -m.x1 = Var(m.t, bounds=(0,1)) -m.x2 = Var(m.t, bounds=(0,1)) +m.x1 = Var(m.t, bounds=(0, 1)) +m.x2 = Var(m.t, bounds=(0, 1)) m.u = Var(m.t, initialize=0) m.x1dot = DerivativeVar(m.x1) @@ -32,21 +32,29 @@ m.obj = Objective(expr=m.x2[1]) -def _x1dot(M,i): - if i == 0: - return Constraint.Skip - return M.x1dot[i] == M.u[i] + +def _x1dot(M, i): + if i == 0: + return Constraint.Skip + return M.x1dot[i] == M.u[i] + + m.x1dotcon = Constraint(m.t, rule=_x1dot) -def _x2dot(M,i): - if i == 0: - return Constraint.Skip - return M.x2dot[i] == M.x1[i]**2 + M.u[i]**2 + +def _x2dot(M, i): + if i == 0: + return Constraint.Skip + return M.x2dot[i] == M.x1[i] ** 2 + M.u[i] ** 2 + + m.x2dotcon = Constraint(m.t, rule=_x2dot) + def _init(M): - yield M.x1[0] == 1 - yield M.x2[0] == 0 - yield ConstraintList.End -m.init_conditions = ConstraintList(rule=_init) + yield M.x1[0] == 1 + yield M.x2[0] == 0 + yield ConstraintList.End + +m.init_conditions = ConstraintList(rule=_init) diff --git a/examples/dae/PDE_example.py b/examples/dae/PDE_example.py index 187e3ce52ed..6cb7eb4a7fe 100644 --- a/examples/dae/PDE_example.py +++ b/examples/dae/PDE_example.py @@ -16,33 +16,45 @@ m = ConcreteModel() m.pi = Param(initialize=3.1416) -m.t = ContinuousSet(bounds=(0,2)) -m.x = ContinuousSet(bounds=(0,1)) -m.u = Var(m.x,m.t) +m.t = ContinuousSet(bounds=(0, 2)) +m.x = ContinuousSet(bounds=(0, 1)) +m.u = Var(m.x, m.t) -m.dudx = DerivativeVar(m.u,wrt=m.x) -m.dudx2 = DerivativeVar(m.u,wrt=(m.x,m.x)) -m.dudt = DerivativeVar(m.u,wrt=m.t) +m.dudx = DerivativeVar(m.u, wrt=m.x) +m.dudx2 = DerivativeVar(m.u, wrt=(m.x, m.x)) +m.dudt = DerivativeVar(m.u, wrt=m.t) -def _pde(m,i,j): - if i == 0 or i == 1 or j == 0 : + +def _pde(m, i, j): + if i == 0 or i == 1 or j == 0: return Constraint.Skip - return m.pi**2*m.dudt[i,j] == m.dudx2[i,j] -m.pde = Constraint(m.x,m.t,rule=_pde) + return m.pi**2 * m.dudt[i, j] == m.dudx2[i, j] + + +m.pde = Constraint(m.x, m.t, rule=_pde) + -def _initcon(m,i): +def _initcon(m, i): if i == 0 or i == 1: return Constraint.Skip - return m.u[i,0] == sin(m.pi*i) -m.initcon = Constraint(m.x,rule=_initcon) + return m.u[i, 0] == sin(m.pi * i) + + +m.initcon = Constraint(m.x, rule=_initcon) + -def _lowerbound(m,j): - return m.u[0,j] == 0 -m.lowerbound = Constraint(m.t,rule=_lowerbound) +def _lowerbound(m, j): + return m.u[0, j] == 0 -def _upperbound(m,j): - return m.pi*exp(-j)+m.dudx[1,j] == 0 -m.upperbound = Constraint(m.t,rule=_upperbound) + +m.lowerbound = Constraint(m.t, rule=_lowerbound) + + +def _upperbound(m, j): + return m.pi * exp(-j) + m.dudx[1, j] == 0 + + +m.upperbound = Constraint(m.t, rule=_upperbound) m.obj = Objective(expr=1) @@ -54,27 +66,27 @@ def _upperbound(m,j): # Discretize using Finite Difference and Collocation discretizer = TransformationFactory('dae.finite_difference') discretizer2 = TransformationFactory('dae.collocation') -discretizer.apply_to(m,nfe=25,wrt=m.x,scheme='BACKWARD') -discretizer2.apply_to(m,nfe=20,ncp=3,wrt=m.t) +discretizer.apply_to(m, nfe=25, wrt=m.x, scheme='BACKWARD') +discretizer2.apply_to(m, nfe=20, ncp=3, wrt=m.t) # Discretize using Finite Difference Method # discretizer = TransformationFactory('dae.finite_difference') # discretizer.apply_to(m,nfe=25,wrt=m.x,scheme='BACKWARD') # discretizer.apply_to(m,nfe=20,wrt=m.t,scheme='BACKWARD') -solver=SolverFactory('ipopt') -results = solver.solve(m,tee=True) +solver = SolverFactory('ipopt') +results = solver.solve(m, tee=True) x = [] t = [] u = [] for i in sorted(m.x): - temp=[] + temp = [] tempx = [] for j in sorted(m.t): tempx.append(i) - temp.append(value(m.u[i,j])) + temp.append(value(m.u[i, j])) x.append(tempx) t.append(sorted(m.t)) u.append(temp) @@ -83,9 +95,10 @@ def _upperbound(m,j): import numpy import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.axes3d import Axes3D + fig = plt.figure() -ax = fig.add_subplot(1,1,1,projection='3d') +ax = fig.add_subplot(1, 1, 1, projection='3d') ax.set_xlabel('Distance x') ax.set_ylabel('Time t') -p = ax.plot_wireframe(x,t,u,rstride=1,cstride=1) +p = ax.plot_wireframe(x, t, u, rstride=1, cstride=1) fig.show() diff --git a/examples/dae/Parameter_Estimation.py b/examples/dae/Parameter_Estimation.py index 5cb4e756644..7ee2f112b94 100644 --- a/examples/dae/Parameter_Estimation.py +++ b/examples/dae/Parameter_Estimation.py @@ -12,52 +12,64 @@ # Sample Problem 2: Parameter Estimation # (Ex 5 from Dynopt Guide) # -# min sum((X1(ti)-X1_meas(ti))^2) -# s.t. X1_dot = X2 X1(0) = p1 -# X2_dot = 1-2*X2-X1 X2(0) = p2 -# -1.5 <= p1,p2 <= 1.5 -# tf = 6 +# min sum((X1(ti)-X1_meas(ti))^2) +# s.t. X1_dot = X2 X1(0) = p1 +# X2_dot = 1-2*X2-X1 X2(0) = p2 +# -1.5 <= p1,p2 <= 1.5 +# tf = 6 # from pyomo.environ import * from pyomo.dae import * model = AbstractModel() -model.t = ContinuousSet() -model.MEAS_t = Set(within=model.t) # Measurement times, must be subset of t +model.t = ContinuousSet() +model.MEAS_t = Set(within=model.t) # Measurement times, must be subset of t model.x1_meas = Param(model.MEAS_t) model.x1 = Var(model.t) model.x2 = Var(model.t) -model.p1 = Var(bounds=(-1.5,1.5)) -model.p2 = Var(bounds=(-1.5,1.5)) +model.p1 = Var(bounds=(-1.5, 1.5)) +model.p2 = Var(bounds=(-1.5, 1.5)) -model.x1dot = DerivativeVar(model.x1,wrt=model.t) +model.x1dot = DerivativeVar(model.x1, wrt=model.t) model.x2dot = DerivativeVar(model.x2) + def _init_conditions(model): - yield model.x1[0] == model.p1 - yield model.x2[0] == model.p2 + yield model.x1[0] == model.p1 + yield model.x2[0] == model.p2 + + model.init_conditions = ConstraintList(rule=_init_conditions) # Alternate way to declare initial conditions -#def _initx1(model): -# return model.x1[0] == model.p1 -#model.initx1 = Constraint(rule=_initx1) +# def _initx1(model): +# return model.x1[0] == model.p1 +# model.initx1 = Constraint(rule=_initx1) + +# def _initx2(model): +# return model.x2[0] == model.p2 +# model.initx2 = Constraint(rule=_initx2) + + +def _x1dot(model, i): + return model.x1dot[i] == model.x2[i] -#def _initx2(model): -# return model.x2[0] == model.p2 -#model.initx2 = Constraint(rule=_initx2) -def _x1dot(model,i): - return model.x1dot[i] == model.x2[i] model.x1dotcon = Constraint(model.t, rule=_x1dot) -def _x2dot(model,i): - return model.x2dot[i] == 1-2*model.x2[i]-model.x1[i] + +def _x2dot(model, i): + return model.x2dot[i] == 1 - 2 * model.x2[i] - model.x1[i] + + model.x2dotcon = Constraint(model.t, rule=_x2dot) + def _obj(model): - return sum((model.x1[i]-model.x1_meas[i])**2 for i in model.MEAS_t) + return sum((model.x1[i] - model.x1_meas[i]) ** 2 for i in model.MEAS_t) + + model.obj = Objective(rule=_obj) diff --git a/examples/dae/Path_Constraint.py b/examples/dae/Path_Constraint.py index f28994ce3c9..866b4b3b90a 100644 --- a/examples/dae/Path_Constraint.py +++ b/examples/dae/Path_Constraint.py @@ -25,7 +25,7 @@ m = ConcreteModel() m.tf = Param(initialize=1) -m.t = ContinuousSet(bounds=(0,m.tf)) +m.t = ContinuousSet(bounds=(0, m.tf)) m.u = Var(m.t, initialize=0) m.x1 = Var(m.t) @@ -38,32 +38,47 @@ m.obj = Objective(expr=m.x3[m.tf]) + def _x1dot(m, t): if t == 0: return Constraint.Skip return m.dx1[t] == m.x2[t] + + m.x1dotcon = Constraint(m.t, rule=_x1dot) + def _x2dot(m, t): if t == 0: return Constraint.Skip - return m.dx2[t] == -m.x2[t]+m.u[t] + return m.dx2[t] == -m.x2[t] + m.u[t] + + m.x2dotcon = Constraint(m.t, rule=_x2dot) + def _x3dot(m, t): if t == 0: return Constraint.Skip - return m.dx3[t] == m.x1[t]**2+m.x2[t]**2+0.005*m.u[t]**2 + return m.dx3[t] == m.x1[t] ** 2 + m.x2[t] ** 2 + 0.005 * m.u[t] ** 2 + + m.x3dotcon = Constraint(m.t, rule=_x3dot) + def _con(m, t): - return m.x2[t]-8*(t-0.5)**2+0.5 <= 0 + return m.x2[t] - 8 * (t - 0.5) ** 2 + 0.5 <= 0 + + m.con = Constraint(m.t, rule=_con) + def _init(m): yield m.x1[0] == 0 yield m.x2[0] == -1 yield m.x3[0] == 0 + + m.init_conditions = ConstraintList(rule=_init) diff --git a/examples/dae/ReactionKinetics.py b/examples/dae/ReactionKinetics.py index 8d1fb6055d0..ef760820c4b 100644 --- a/examples/dae/ReactionKinetics.py +++ b/examples/dae/ReactionKinetics.py @@ -27,15 +27,17 @@ colloc = TransformationFactory('dae.collocation') solver = SolverFactory('ipopt') + class Reaction(object): - """ A simple class to hold the stoichiometry of a single reaction + """A simple class to hold the stoichiometry of a single reaction Reaction data is stored in two dictionaries: reactants: a map of reactant species name -> stoichiometric coefficient products: a map of product species name -> stoichiometric coefficient """ + def __init__(self, name, reactants, products=None): - """ Define a reaction. The reaction can be specified either as + """Define a reaction. The reaction can be specified either as a text string: Reaction("2*A + B -> C + 3*D") @@ -66,13 +68,13 @@ def _parse(self, _in): _in = _in.split('+') for x in _in: coef, species = self._parseTerm(x) - ans[species] = ans.get(species,0) + coef + ans[species] = ans.get(species, 0) + coef return ans - + def _parseTerm(self, x): if isinstance(x, str): if '*' in x: - coef, species = x.split('*',1) + coef, species = x.split('*', 1) coef = float(coef) else: coef, species = 1, x @@ -81,36 +83,43 @@ def _parseTerm(self, x): coef = float(coef) return coef, species.strip() + class ReactionNetwork(object): - """ A simple object to hold sets of reactions. """ + """A simple object to hold sets of reactions.""" + def __init__(self): self.reactions = {} def add(self, rxn): - """ Add a single reaction to the reaction network. """ + """Add a single reaction to the reaction network.""" if rxn.name in self.reactions: - raise RuntimeError("Duplicate reaction %s:\n\told=%s\n\tnew=%s" % - rxn.name, self.reactions[rxn.name], rxn) + raise RuntimeError( + "Duplicate reaction %s:\n\told=%s\n\tnew=%s" % rxn.name, + self.reactions[rxn.name], + rxn, + ) self.reactions[rxn.name] = rxn def add_reversible(self, rxn): - """ Add a pair of reactions to the reaction network. + """Add a pair of reactions to the reaction network. This model implements reversible reactions through an explicit pair of forward and reverse reactions. """ self.add(rxn) - tmp = Reaction( name= rxn.name+'_r', - reactants= [(b,a) for a,b in rxn.products.items()], - products= [(b,a) for a,b in rxn.reactants.items()] ) + tmp = Reaction( + name=rxn.name + '_r', + reactants=[(b, a) for a, b in rxn.products.items()], + products=[(b, a) for a, b in rxn.reactants.items()], + ) self.add(tmp) def species(self): """Return the set of all species appearing int he Reaction Network""" ans = set() for rxn in self.reactions.values(): - ans.update( rxn.reactants ) - ans.update( rxn.products ) + ans.update(rxn.reactants) + ans.update(rxn.products) return sorted(ans) @@ -122,40 +131,40 @@ def create_kinetic_model(rxnNet, time): model.rxnNetwork = rxnNet - model.SPECIES = Set( initialize=rxnNet.species() ) - model.REACTIONS = Set( initialize=rxnNet.reactions.keys() ) + model.SPECIES = Set(initialize=rxnNet.species()) + model.REACTIONS = Set(initialize=rxnNet.reactions.keys()) try: maxTime = max(time) times = time except TypeError: maxTime = time times = [time] - model.TIME = ContinuousSet( bounds=(0,maxTime), initialize=times ) + model.TIME = ContinuousSet(bounds=(0, maxTime), initialize=times) - model.c = Var( model.TIME, model.SPECIES, bounds=(0,None) ) - model.dcdt = DerivativeVar( model.c, wrt=model.TIME ) + model.c = Var(model.TIME, model.SPECIES, bounds=(0, None)) + model.dcdt = DerivativeVar(model.c, wrt=model.TIME) - model.k = Var( model.REACTIONS, bounds=(0,None) ) - model.rate = Var( model.TIME, model.REACTIONS ) + model.k = Var(model.REACTIONS, bounds=(0, None)) + model.rate = Var(model.TIME, model.REACTIONS) def reaction_rate(m, t, r): rhs = m.k[r] for s, coef in m.rxnNetwork.reactions[r].reactants.items(): - rhs *= m.c[t,s]**coef - return m.rate[t,r] == rhs - model.reaction_rate = Constraint( model.TIME, model.REACTIONS, - rule=reaction_rate ) + rhs *= m.c[t, s] ** coef + return m.rate[t, r] == rhs + + model.reaction_rate = Constraint(model.TIME, model.REACTIONS, rule=reaction_rate) def stoichiometry(m, t, s): rhs = 0 for r in m.REACTIONS: if s in m.rxnNetwork.reactions[r].reactants: - rhs -= m.rate[t,r] * m.rxnNetwork.reactions[r].reactants[s] + rhs -= m.rate[t, r] * m.rxnNetwork.reactions[r].reactants[s] if s in m.rxnNetwork.reactions[r].products: - rhs += m.rate[t,r] * m.rxnNetwork.reactions[r].products[s] - return m.dcdt[t,s] == rhs - model.stoichiometry = Constraint( model.TIME, model.SPECIES, - rule=stoichiometry ) + rhs += m.rate[t, r] * m.rxnNetwork.reactions[r].products[s] + return m.dcdt[t, s] == rhs + + model.stoichiometry = Constraint(model.TIME, model.SPECIES, rule=stoichiometry) return model @@ -172,20 +181,20 @@ def simple_simulation_model(): """Run a simple simulation model for 2*A -> B -> C.""" rxns = ReactionNetwork() - rxns.add( Reaction("AtoB", "2*A -> B") ) - rxns.add( Reaction("BtoC", "B -> C") ) + rxns.add(Reaction("AtoB", "2*A -> B")) + rxns.add(Reaction("BtoC", "B -> C")) - model = create_kinetic_model(rxns, 60*60) + model = create_kinetic_model(rxns, 60 * 60) - A1 = 1.32e19 # L / mol*s - A2 = 1.09e13 # 1/s + A1 = 1.32e19 # L / mol*s + A2 = 1.09e13 # 1/s Ea1 = 140000 # J/mol Ea2 = 100000 # J/mol - R = 8.314 # J / K*mol - T = 330 # K + R = 8.314 # J / K*mol + T = 330 # K - model.k['AtoB'].fix( A1 * exp( -Ea1 / (R*T) ) ) - model.k['BtoC'].fix( A2 * exp( -Ea2 / (R*T) ) ) + model.k['AtoB'].fix(A1 * exp(-Ea1 / (R * T))) + model.k['BtoC'].fix(A2 * exp(-Ea2 / (R * T))) model.c[0, 'A'].fix(1) model.c[0, 'B'].fix(0) @@ -198,12 +207,16 @@ def simple_simulation_model(): if plt is not None: _tmp = sorted(model.c.items()) for _i, _x in enumerate('ABC'): - plt.plot([x[0][0] for x in _tmp if x[0][1] == _x], - [value(x[1]) for x in _tmp if x[0][1] == _x], - 'bgr'[_i]+'*', label=_x) + plt.plot( + [x[0][0] for x in _tmp if x[0][1] == _x], + [value(x[1]) for x in _tmp if x[0][1] == _x], + 'bgr'[_i] + '*', + label=_x, + ) plt.legend() plt.show() + # # This example is based on # @@ -217,21 +230,22 @@ def simple_optimization_model(): concentration of the intermediate, "B".""" rxns = ReactionNetwork() - rxns.add( Reaction("AtoB", "2*A -> B") ) - rxns.add( Reaction("BtoC", "B -> C") ) + rxns.add(Reaction("AtoB", "2*A -> B")) + rxns.add(Reaction("BtoC", "B -> C")) - model = create_kinetic_model(rxns, 60*60) + model = create_kinetic_model(rxns, 60 * 60) - A1 = 1.32e19 # L / mol*s - A2 = 1.09e13 # 1/s + A1 = 1.32e19 # L / mol*s + A2 = 1.09e13 # 1/s Ea1 = 140000 # J/mol Ea2 = 100000 # J/mol - R = 8.314 # J / K*mol - model.T = Var(bounds=(0,None), initialize=330) # K + R = 8.314 # J / K*mol + model.T = Var(bounds=(0, None), initialize=330) # K def compute_k(m): - yield m.k['AtoB'] == A1 * exp( -Ea1 / (R*m.T) ) - yield m.k['BtoC'] == A2 * exp( -Ea2 / (R*m.T) ) + yield m.k['AtoB'] == A1 * exp(-Ea1 / (R * m.T)) + yield m.k['BtoC'] == A2 * exp(-Ea2 / (R * m.T)) + model.compute_k = ConstraintList(rule=compute_k) # initial conditions @@ -241,24 +255,27 @@ def compute_k(m): fdiff.apply_to(model, nfe=100) - model.obj = Objective( sense=maximize, - expr=model.c[max(model.TIME), 'B']) + model.obj = Objective(sense=maximize, expr=model.c[max(model.TIME), 'B']) results = solver.solve(model, tee=True) if plt is not None: for _i, _x in enumerate('ABC'): - plt.plot([x.index()[0] for x in model.c[:,_x]], - [value(x) for x in model.c[:,_x]], - 'bgr'[_i]+'*', label=_x) + plt.plot( + [x.index()[0] for x in model.c[:, _x]], + [value(x) for x in model.c[:, _x]], + 'bgr'[_i] + '*', + label=_x, + ) plt.legend() plt.show() + def create_regression_model(b, t): rxns = ReactionNetwork() - rxns.add_reversible( Reaction( "k_1", "TG + MeOH -> DG + FAME" ) ) - rxns.add_reversible( Reaction( "k_2", "DG + MeOH -> MG + FAME" ) ) - rxns.add_reversible( Reaction( "k_3", "MG + MeOH -> Glycerol + FAME" ) ) + rxns.add_reversible(Reaction("k_1", "TG + MeOH -> DG + FAME")) + rxns.add_reversible(Reaction("k_2", "DG + MeOH -> MG + FAME")) + rxns.add_reversible(Reaction("k_3", "MG + MeOH -> Glycerol + FAME")) data = b.model().data[t] key = b.model().key @@ -266,17 +283,22 @@ def create_regression_model(b, t): model = create_kinetic_model(rxns, data.keys()) model.T = Param(initialize=t) - model.error = Var(bounds=(0,None)) + model.error = Var(bounds=(0, None)) model.compute_error = Constraint( - expr = model.error == sum( - (( model.c[t,key[i]] - x ) / max(data[_t][i] for _t in data) )**2 - for t in data for i,x in enumerate(data[t]) ) ) + expr=model.error + == sum( + ((model.c[t, key[i]] - x) / max(data[_t][i] for _t in data)) ** 2 + for t in data + for i, x in enumerate(data[t]) + ) + ) return model + def regression_model(): - """ Develop a simple parameter estimation model to identify either + """Develop a simple parameter estimation model to identify either rate coedfficients (if regress_Ea is False), or the activation energy (if regress_Ea is True).""" @@ -286,53 +308,56 @@ def regression_model(): # model = ConcreteModel() - model.key = key = ('MeOH','TG','DG','MG','FAME','Glycerol') + model.key = key = ('MeOH', 'TG', 'DG', 'MG', 'FAME', 'Glycerol') model.data = data = { 150: { - 0: (2.833,6.84E-02,0.00,0.00,0.00,0.00,), - 256: (2.807,4.75E-02,1.51E-02,3.71E-03,2.60E-02,8.18E-04,), - 613: (2.795,3.92E-02,1.98E-02,5.83E-03,3.83E-02,1.60E-03,), - 1228: (2.772,2.95E-02,2.83E-02,9.78E-03,6.07E-02,2.30E-03,), - 1433: (2.762,2.40E-02,3.13E-02,1.49E-02,7.08E-02,4.48E-03,), - 1633: (2.747,1.74E-02,2.02E-02,2.16E-02,8.57E-02,6.23E-03,), - 1933: (2.715,1.03E-02,9.10E-03,2.83E-02,1.18E-01,6.97E-03,), - 2623: (2.699,7.49E-03,7.87E-03,2.34E-02,1.34E-01,9.83E-03,), - 3028: (2.676,3.04E-03,6.56E-03,1.58E-02,1.57E-01,1.68E-02,), - 9000: (2.639,0.00,0.00,0.00,1.94E-01,6.06E-02,), }, + 0: (2.833, 6.84e-02, 0.00, 0.00, 0.00, 0.00), + 256: (2.807, 4.75e-02, 1.51e-02, 3.71e-03, 2.60e-02, 8.18e-04), + 613: (2.795, 3.92e-02, 1.98e-02, 5.83e-03, 3.83e-02, 1.60e-03), + 1228: (2.772, 2.95e-02, 2.83e-02, 9.78e-03, 6.07e-02, 2.30e-03), + 1433: (2.762, 2.40e-02, 3.13e-02, 1.49e-02, 7.08e-02, 4.48e-03), + 1633: (2.747, 1.74e-02, 2.02e-02, 2.16e-02, 8.57e-02, 6.23e-03), + 1933: (2.715, 1.03e-02, 9.10e-03, 2.83e-02, 1.18e-01, 6.97e-03), + 2623: (2.699, 7.49e-03, 7.87e-03, 2.34e-02, 1.34e-01, 9.83e-03), + 3028: (2.676, 3.04e-03, 6.56e-03, 1.58e-02, 1.57e-01, 1.68e-02), + 9000: (2.639, 0.00, 0.00, 0.00, 1.94e-01, 6.06e-02), + }, 210: { - 0: (2.835,6.78E-02,0.00,0.00,0.00,0.00,), - 130:(2.806,3.56E-02,1.96E-02,1.92E-02,3.35E-02,0.00,), - 160:(2.755,3.42E-02,1.49E-02,2.54E-02,4.17E-02,0.00,), - 190:(2.735,2.92E-02,1.38E-02,2.83E-02,5.67E-02,0.00,), - 220:(2.715,2.20E-02,1.40E-02,2.80E-02,7.97E-02,4.37E-03,), - 250:(2.698,1.70E-02,7.89E-03,3.12E-02,1.05E-01,1.24E-02,), - 280:(2.675,1.29E-02,5.45E-03,2.78E-02,1.28E-01,2.23E-02,), - 340:(2.659,7.02E-03,5.90E-03,1.56E-02,1.58E-01,3.99E-02,), - 400:(2.648,3.65E-03,5.13E-03,7.92E-03,1.75E-01,5.17E-02,), - 460:(2.641,2.66E-03,5.04E-03,4.64E-03,1.79E-01,5.61E-02,), - 520:(2.637,1.49E-03,3.57E-03,2.48E-03,1.86E-01,6.09E-02,), - 580:(2.633,3.35E-04,4.96E-04,1.84E-03,1.95E-01,6.58E-02,), - 640:(2.632,2.49E-04,2.40E-04,1.44E-03,1.98E-01,6.65E-02,), - 700:(2.630,2.31E-04,2.90E-05,1.28E-03,2.00E-01,6.69E-02,), - 760:(2.630,0.00,0.00,7.61E-04,2.02E-01,6.77E-02,), } - } - - model.experiment = Block( data.keys(), rule=create_regression_model ) - - model.obj = Objective( sense=minimize, - expr=sum(b.error for b in model.experiment[:]) ) - _experiments = list( model.experiment.values() ) + 0: (2.835, 6.78e-02, 0.00, 0.00, 0.00, 0.00), + 130: (2.806, 3.56e-02, 1.96e-02, 1.92e-02, 3.35e-02, 0.00), + 160: (2.755, 3.42e-02, 1.49e-02, 2.54e-02, 4.17e-02, 0.00), + 190: (2.735, 2.92e-02, 1.38e-02, 2.83e-02, 5.67e-02, 0.00), + 220: (2.715, 2.20e-02, 1.40e-02, 2.80e-02, 7.97e-02, 4.37e-03), + 250: (2.698, 1.70e-02, 7.89e-03, 3.12e-02, 1.05e-01, 1.24e-02), + 280: (2.675, 1.29e-02, 5.45e-03, 2.78e-02, 1.28e-01, 2.23e-02), + 340: (2.659, 7.02e-03, 5.90e-03, 1.56e-02, 1.58e-01, 3.99e-02), + 400: (2.648, 3.65e-03, 5.13e-03, 7.92e-03, 1.75e-01, 5.17e-02), + 460: (2.641, 2.66e-03, 5.04e-03, 4.64e-03, 1.79e-01, 5.61e-02), + 520: (2.637, 1.49e-03, 3.57e-03, 2.48e-03, 1.86e-01, 6.09e-02), + 580: (2.633, 3.35e-04, 4.96e-04, 1.84e-03, 1.95e-01, 6.58e-02), + 640: (2.632, 2.49e-04, 2.40e-04, 1.44e-03, 1.98e-01, 6.65e-02), + 700: (2.630, 2.31e-04, 2.90e-05, 1.28e-03, 2.00e-01, 6.69e-02), + 760: (2.630, 0.00, 0.00, 7.61e-04, 2.02e-01, 6.77e-02), + }, + } + + model.experiment = Block(data.keys(), rule=create_regression_model) + + model.obj = Objective( + sense=minimize, expr=sum(b.error for b in model.experiment[:]) + ) + _experiments = list(model.experiment.values()) # initializations from the paper for _e in _experiments: - _e.k['k_1'] = 7.58e-7 + _e.k['k_1'] = 7.58e-7 _e.k['k_1_r'] = 0 - _e.k['k_2'] = 2.20e-7 + _e.k['k_2'] = 2.20e-7 _e.k['k_2_r'] = 0 - _e.k['k_3'] = 2.15e-7 + _e.k['k_3'] = 2.15e-7 _e.k['k_3_r'] = 0 - #fdiff.apply_to(model, nfe=100) + # fdiff.apply_to(model, nfe=100) colloc.apply_to(model, nfe=100, ncp=3) # Note that the two experiments are not linked at this point, so @@ -345,17 +370,19 @@ def regression_model(): # independent regression as the starting point) regress_Ea = True if regress_Ea: - model.Kset = Set(initialize=['k_1','k_2','k_3',]) - model.Ea = Var(model.Kset, bounds=(0,None), initialize=0) - model.A = Var(model.Kset, bounds=(0,None), initialize=0) + model.Kset = Set(initialize=['k_1', 'k_2', 'k_3']) + model.Ea = Var(model.Kset, bounds=(0, None), initialize=0) + model.A = Var(model.Kset, bounds=(0, None), initialize=0) model.R = Param(initialize=8.314) for _e in _experiments: _e.k.fix() + def compute_k(e, _k): m = e.model() # k11' == k_mt + k_11 * (C_DG + C_MG) / C_TG_0 - #return e.k[_k] == m.A[_k] * exp( -m.Ea[_k] / ( m.R * e.T ) ) - return log(e.k[_k]) == log(m.A[_k]) - m.Ea[_k] / ( m.R * e.T ) + # return e.k[_k] == m.A[_k] * exp( -m.Ea[_k] / ( m.R * e.T ) ) + return log(e.k[_k]) == log(m.A[_k]) - m.Ea[_k] / (m.R * e.T) + _e.compute_k = Constraint(model.Kset, rule=compute_k) solver.solve(model, tee=True) @@ -372,23 +399,31 @@ def compute_k(e, _k): ax2 = plt.twinx() for _i, _x in enumerate(key): _ax = ax2 if _x == 'MeOH' else ax - _ax.plot( [ t for t in data[T].keys() ], - [ data[T][t][_i] for t in data[T].keys() ], - 'mkrgbc'[_i]+'x' ) + _ax.plot( + [t for t in data[T].keys()], + [data[T][t][_i] for t in data[T].keys()], + 'mkrgbc'[_i] + 'x', + ) for _i, _x in enumerate(key): _ax = ax2 if _x == 'MeOH' else ax - _ax.plot([ x.index()[0] for x in model.experiment[T].c[:,_x] ], - [ value(x) for x in model.experiment[T].c[:,_x] ], - 'mkrgbc'[_i]+'-') + _ax.plot( + [x.index()[0] for x in model.experiment[T].c[:, _x]], + [value(x) for x in model.experiment[T].c[:, _x]], + 'mkrgbc'[_i] + '-', + ) plt.show() - + + if __name__ == "__main__": import sys + if len(sys.argv) != 2 or sys.argv[1] not in '123': - print("""ERROR: expected a model to run: + print( + """ERROR: expected a model to run: 1 - simple simulation model 2 - simple (final value) optimization model - 3 - kinetic parameter regression model""") + 3 - kinetic parameter regression model""" + ) sys.exit(1) if '1' in sys.argv[1]: diff --git a/examples/dae/car_example.py b/examples/dae/car_example.py index 82143669a46..a157159cf6c 100644 --- a/examples/dae/car_example.py +++ b/examples/dae/car_example.py @@ -16,15 +16,15 @@ m = ConcreteModel() -m.R = Param(initialize=0.001) # Friction factor -m.L = Param(initialize=100.0) # Final position +m.R = Param(initialize=0.001) # Friction factor +m.L = Param(initialize=100.0) # Final position -m.tau = ContinuousSet(bounds=(0,1)) # Unscaled time -m.time = Var(m.tau) # Scaled time +m.tau = ContinuousSet(bounds=(0, 1)) # Unscaled time +m.time = Var(m.tau) # Scaled time m.tf = Var() -m.x = Var(m.tau,bounds=(0,m.L+50)) -m.v = Var(m.tau,bounds=(0,None)) -m.a = Var(m.tau, bounds=(-3.0,1.0),initialize=0) +m.x = Var(m.tau, bounds=(0, m.L + 50)) +m.v = Var(m.tau, bounds=(0, None)) +m.a = Var(m.tau, bounds=(-3.0, 1.0), initialize=0) m.dtime = DerivativeVar(m.time) m.dx = DerivativeVar(m.x) @@ -32,65 +32,77 @@ m.obj = Objective(expr=m.tf) -def _ode1(m,i): - if i == 0 : + +def _ode1(m, i): + if i == 0: return Constraint.Skip return m.dx[i] == m.tf * m.v[i] + + m.ode1 = Constraint(m.tau, rule=_ode1) -def _ode2(m,i): - if i == 0 : + +def _ode2(m, i): + if i == 0: return Constraint.Skip - return m.dv[i] == m.tf*(m.a[i] - m.R*m.v[i]**2) + return m.dv[i] == m.tf * (m.a[i] - m.R * m.v[i] ** 2) + + m.ode2 = Constraint(m.tau, rule=_ode2) -def _ode3(m,i): + +def _ode3(m, i): if i == 0: return Constraint.Skip return m.dtime[i] == m.tf + + m.ode3 = Constraint(m.tau, rule=_ode3) + def _init(m): yield m.x[0] == 0 yield m.x[1] == m.L yield m.v[0] == 0 yield m.v[1] == 0 yield m.time[0] == 0 + + m.initcon = ConstraintList(rule=_init) discretizer = TransformationFactory('dae.finite_difference') -discretizer.apply_to(m,nfe=15,scheme='BACKWARD') +discretizer.apply_to(m, nfe=15, scheme='BACKWARD') solver = SolverFactory('ipopt') -solver.solve(m,tee=True) +solver.solve(m, tee=True) -print("final time = %6.2f" %(value(m.tf))) +print("final time = %6.2f" % (value(m.tf))) x = [] v = [] a = [] -time=[] +time = [] for i in m.tau: time.append(value(m.time[i])) x.append(value(m.x[i])) v.append(value(m.v[i])) a.append(value(m.a[i])) - + import matplotlib.pyplot as plt plt.subplot(131) -plt.plot(time,x,label='x') +plt.plot(time, x, label='x') plt.title('location') plt.xlabel('time') plt.subplot(132) -plt.plot(time,v,label='v') +plt.plot(time, v, label='v') plt.xlabel('time') plt.title('velocity') plt.subplot(133) -plt.plot(time,a,label='a') +plt.plot(time, a, label='a') plt.xlabel('time') plt.title('acceleration') diff --git a/examples/dae/disease_DAE.py b/examples/dae/disease_DAE.py index 143b8bfabc2..eb290919469 100644 --- a/examples/dae/disease_DAE.py +++ b/examples/dae/disease_DAE.py @@ -9,42 +9,44 @@ years = 20 beta_py = 26 fepr = 1 -fepy = beta_py*fepr +fepy = beta_py * fepr fe = fepy * years -step = 365.0/fepy +step = 365.0 / fepy model = AbstractModel() # Define unindexed parameters -model.P_GAMMA = Param(default=1.0/14.0) +model.P_GAMMA = Param(default=1.0 / 14.0) model.P_NUM_BETA = Param(default=beta_py) model.P_FEPY = Param(default=fepy) model.P_FE = Param(default=fe) model.P_STEP = Param(default=step) -model.P_TRI = Param(default=beta_py*years) +model.P_TRI = Param(default=beta_py * years) model.P_FEPR = Param(default=fepr) model.I_OBJ_WT = Param(default=0.995) model.PHI_OBJ_WT = Param(default=0.005) # Define sets -model.S_BETA = RangeSet(1,model.P_NUM_BETA) -model.S_FE = RangeSet(1,model.P_FE) +model.S_BETA = RangeSet(1, model.P_NUM_BETA) +model.S_FE = RangeSet(1, model.P_FE) def _TIME_init(model): - return (model.P_STEP*i for i in model.S_FE) -model.TIME = ContinuousSet(initialize=_TIME_init, bounds=(0,None)) + return (model.P_STEP * i for i in model.S_FE) -model.S_TRI = RangeSet(1,model.P_TRI) + +model.TIME = ContinuousSet(initialize=_TIME_init, bounds=(0, None)) + +model.S_TRI = RangeSet(1, model.P_TRI) # Define indexed parameters beta_ndx = {} if (beta_py > 26) or (fepr > 1): - for i in range(1,fe+1): - beta_ndx[i] = (((i+1)/fepr)-1)%beta_py+1 + for i in range(1, fe + 1): + beta_ndx[i] = (((i + 1) / fepr) - 1) % beta_py + 1 else: - for i in range(1,fe+1): - beta_ndx[i] = ((i-1)%beta_py)+1 + for i in range(1, fe + 1): + beta_ndx[i] = ((i - 1) % beta_py) + 1 model.P_BETA_NDX = Param(model.S_FE, initialize=beta_ndx, default=1.0) model.P_POP = Param(default=1.0e6) @@ -52,7 +54,7 @@ def _TIME_init(model): model.P_REP_CASES = Param(model.S_TRI, default=10.0) model.P_BIRTHS = Param(model.S_FE, default=100.0) model.P_DATA_WTS = Param(model.S_TRI, default=1.0) -model.P_ALL_CASES = Param(model.S_TRI, default = 10.0) +model.P_ALL_CASES = Param(model.S_TRI, default=10.0) # Define initialization parameters and rules model.init_S_bar = Param(default=1.0e5) @@ -72,104 +74,146 @@ def _TIME_init(model): model.init_Idot = Param(model.S_FE, default=1.0) model.init_phidot = Param(model.S_FE, default=1.0) -model.init_beta_patt = Param(model.S_BETA, default = 0.0) -model.init_beta_int = Param(default = 1.0) +model.init_beta_patt = Param(model.S_BETA, default=0.0) +model.init_beta_int = Param(default=1.0) + + def _init_S_bar(model): return model.init_S_bar + + def _init_beta_bar(model): return model.init_beta_bar + + def _init_I_init(model): return model.init_I_init + + def _init_S_init(model): return model.init_S_init -def _init_beta(model,i): + + +def _init_beta(model, i): return model.init_beta[i] -def _init_beta_pos(model,i): + + +def _init_beta_pos(model, i): return model.init_beta_pos[i] -def _init_beta_neg(model,i): + + +def _init_beta_neg(model, i): return model.init_beta_neg[i] -def _init_eps_I(model,i): + + +def _init_eps_I(model, i): return model.init_eps_I[i] -def _init_eps_phi(model,i): + + +def _init_eps_phi(model, i): return model.init_eps_phi[i] -def _init_S(model,i): - if i==0: + +def _init_S(model, i): + if i == 0: return model.init_S_init fe = model.TIME.get_upper_element_boundary(i) j = model.TIME._fe.index(fe) return model.init_S[j] -def _init_I(model,i): - if i==0: + + +def _init_I(model, i): + if i == 0: return model.init_I_init fe = model.TIME.get_upper_element_boundary(i) j = model.TIME._fe.index(fe) return model.init_I[j] -def _init_phi(model,i): - if i==0: + + +def _init_phi(model, i): + if i == 0: return 0 fe = model.TIME.get_upper_element_boundary(i) j = model.TIME._fe.index(fe) return model.init_phi[j] -def _init_Sdot(model,i): - if i==0: + + +def _init_Sdot(model, i): + if i == 0: return 1 fe = model.TIME.get_upper_element_boundary(i) j = model.TIME._fe.index(fe) - return model.P_STEP*model.init_Sdot[j] -def _init_Idot(model,i): - if i==0: + return model.P_STEP * model.init_Sdot[j] + + +def _init_Idot(model, i): + if i == 0: return 1 fe = model.TIME.get_upper_element_boundary(i) j = model.TIME._fe.index(fe) - return model.P_STEP*model.init_Idot[j] -def _init_phidot(model,i): - if i==0: + return model.P_STEP * model.init_Idot[j] + + +def _init_phidot(model, i): + if i == 0: return 1 fe = model.TIME.get_upper_element_boundary(i) j = model.TIME._fe.index(fe) - return model.P_STEP*model.init_phidot[j] + return model.P_STEP * model.init_phidot[j] -def _init_beta_patt(model,i): + +def _init_beta_patt(model, i): return model.init_beta_patt[i] + + def _init_beta_int(model): return model.init_beta_int -def _people_bounds(model,i): + +def _people_bounds(model, i): return (0.0, model.P_POP) + + def _init_people_bounds(model): return (0.0, model.P_POP) + # Define unindexed variables -model.S_bar = Var(initialize=_init_S_bar, bounds=(0,None)) -model.beta_bar = Var(initialize=_init_beta_bar, bounds=(0.05,5)) +model.S_bar = Var(initialize=_init_S_bar, bounds=(0, None)) +model.beta_bar = Var(initialize=_init_beta_bar, bounds=(0.05, 5)) model.I_init = Var(initialize=_init_I_init, bounds=_init_people_bounds) model.S_init = Var(initialize=_init_S_init, bounds=_init_people_bounds) model.phi_init = Param(default=0.0) # Define indexed variables -model.beta = Var(model.S_BETA, initialize=_init_beta, bounds=(0.01,5)) +model.beta = Var(model.S_BETA, initialize=_init_beta, bounds=(0.01, 5)) -model.beta_pos = Var(model.S_BETA, initialize=_init_beta_pos, bounds=(0,None)) -model.beta_neg = Var(model.S_BETA, initialize=_init_beta_neg, bounds=(0,None)) -model.beta_patt = Var(model.S_BETA, initialize=_init_beta_patt, bounds=(-5,5)) -model.beta_int = Var(initialize = _init_beta_int, bounds=(0.01,5.0)) -model.beta_c = Var(initialize = 1.0) -model.alpha = Var(initialize = 0.05, bounds=(-1.0,1.0)) +model.beta_pos = Var(model.S_BETA, initialize=_init_beta_pos, bounds=(0, None)) +model.beta_neg = Var(model.S_BETA, initialize=_init_beta_neg, bounds=(0, None)) +model.beta_patt = Var(model.S_BETA, initialize=_init_beta_patt, bounds=(-5, 5)) +model.beta_int = Var(initialize=_init_beta_int, bounds=(0.01, 5.0)) +model.beta_c = Var(initialize=1.0) +model.alpha = Var(initialize=0.05, bounds=(-1.0, 1.0)) model.eps_I = Var(model.S_FE, initialize=_init_eps_I) model.eps_phi = Var(model.S_TRI, initialize=_init_eps_phi) model.S = Var(model.TIME, initialize=_init_S, bounds=_people_bounds) model.I = Var(model.TIME, initialize=_init_I, bounds=_people_bounds) -model.phi = Var(model.TIME, initialize=_init_phi, bounds=(0,None)) +model.phi = Var(model.TIME, initialize=_init_phi, bounds=(0, None)) model.Sdot = DerivativeVar(model.S, initialize=_init_Sdot) model.Idot = DerivativeVar(model.I, initialize=_init_Idot) -model.phidot = DerivativeVar(model.phi, initialize=_init_phidot, bounds=(-10,None)) +model.phidot = DerivativeVar(model.phi, initialize=_init_phidot, bounds=(-10, None)) + def _obj_rule(model): - return (model.I_OBJ_WT*sum(model.eps_I[i]**2 for i in model.S_FE) + \ - model.PHI_OBJ_WT*sum(model.P_DATA_WTS[i]*model.eps_phi[i]**2 for i in model.S_TRI)) + return model.I_OBJ_WT * sum( + model.eps_I[i] ** 2 for i in model.S_FE + ) + model.PHI_OBJ_WT * sum( + model.P_DATA_WTS[i] * model.eps_phi[i] ** 2 for i in model.S_TRI + ) + + model.obj = Objective(rule=_obj_rule) ######################## @@ -179,57 +223,101 @@ def _init_conditions(model): yield model.I[0] == model.I_init yield model.S[0] == model.S_init yield model.phi[0] == model.phi_init + + model.init_conditions = ConstraintList(rule=_init_conditions) -def _reported_cases(model,i): + +def _reported_cases(model, i): if i == 1: if model.P_DATA_WTS[i] > 0.1: - return model.P_REP_CASES[i]== model.P_REP_FRAC[i]*( model.phi[model.TIME._fe[i*model.P_FEPR]] - model.phi_init ) + model.eps_phi[i] + return ( + model.P_REP_CASES[i] + == model.P_REP_FRAC[i] + * (model.phi[model.TIME._fe[i * model.P_FEPR]] - model.phi_init) + + model.eps_phi[i] + ) else: return Constraint.Skip else: if model.P_DATA_WTS[i] > 0.1: - return model.P_REP_CASES[i]== model.P_REP_FRAC[i]*( model.phi[model.TIME._fe[i*model.P_FEPR]] - model.phi[model.TIME._fe[(i-1)*model.P_FEPR]] ) + model.eps_phi[i] + return ( + model.P_REP_CASES[i] + == model.P_REP_FRAC[i] + * ( + model.phi[model.TIME._fe[i * model.P_FEPR]] + - model.phi[model.TIME._fe[(i - 1) * model.P_FEPR]] + ) + + model.eps_phi[i] + ) else: return Constraint.Skip + + model.con_reported_cases = Constraint(model.S_TRI, rule=_reported_cases) + def _beta_bar(model): - return (model.beta_bar, sum(model.beta[i] for i in model.S_BETA)/len(model.S_BETA)) + return ( + model.beta_bar, + sum(model.beta[i] for i in model.S_BETA) / len(model.S_BETA), + ) + + model.con_beta_bar = Constraint(rule=_beta_bar) -def _phidot_eq(model,i): + +def _phidot_eq(model, i): if i == 0: return Constraint.Skip fe = model.TIME.get_upper_element_boundary(i) j = model.TIME._fe.index(fe) - return model.phidot[i] == model.eps_I[j] \ - + (model.beta[model.P_BETA_NDX[j]]*model.I[i]*model.S[i])/model.P_POP + return ( + model.phidot[i] + == model.eps_I[j] + + (model.beta[model.P_BETA_NDX[j]] * model.I[i] * model.S[i]) / model.P_POP + ) + + model.phidot_eq = Constraint(model.TIME, rule=_phidot_eq) -def _Idot_eq(model,i): + +def _Idot_eq(model, i): if i == 0: return Constraint.Skip - return model.Idot[i] == model.phidot[i] - model.P_GAMMA*model.I[i] + return model.Idot[i] == model.phidot[i] - model.P_GAMMA * model.I[i] + + model.Idot_eq = Constraint(model.TIME, rule=_Idot_eq) -def _Sdot_eq(model,i): + +def _Sdot_eq(model, i): if i == 0: return Constraint.Skip fe = model.TIME.get_upper_element_boundary(i) j = model.TIME._fe.index(fe) return model.Sdot[i] == -model.phidot[i] + model.P_BIRTHS[j] + + model.Sdot_eq = Constraint(model.TIME, rule=_Sdot_eq) + def _scaled_beta(model, i): - return (model.beta[i], model.beta_c * model.beta_patt[i]) + return (model.beta[i], model.beta_c * model.beta_patt[i]) + + model.con_city_varying_beta = Constraint(model.S_BETA, rule=_scaled_beta) + def _mean_patt(model): - return (1.0, sum_product(model.beta_patt)/len(model.S_BETA)) + return (1.0, sum_product(model.beta_patt) / len(model.S_BETA)) + + model.con_mean_patt = Constraint(rule=_mean_patt) + def _beta_c(model): return (0.75, model.beta_c, 1.5) + + model.con_beta_c = Constraint(rule=_beta_c) - diff --git a/examples/dae/distill_DAE.py b/examples/dae/distill_DAE.py index f882eb87288..04e6c76a1f8 100644 --- a/examples/dae/distill_DAE.py +++ b/examples/dae/distill_DAE.py @@ -12,85 +12,120 @@ from pyomo.environ import * from pyomo.dae import * -model = AbstractModel() +model = AbstractModel() -model.Feed = Param(initialize = 24.0/60.0) -model.x_Feed = Param(initialize = 0.5) -model.D = Param(initialize = model.x_Feed*model.Feed) -model.vol = Param(initialize = 1.6) -model.atray = Param(initialize = 0.25) -model.acond = Param(initialize = 0.5) -model.areb = Param(initialize = 1.0) +model.Feed = Param(initialize=24.0 / 60.0) +model.x_Feed = Param(initialize=0.5) +model.D = Param(initialize=model.x_Feed * model.Feed) +model.vol = Param(initialize=1.6) +model.atray = Param(initialize=0.25) +model.acond = Param(initialize=0.5) +model.areb = Param(initialize=1.0) model.S_TRAYS = Set(dimen=1) -model.S_RECTIFICATION = Set(within = model.S_TRAYS) -model.S_STRIPPING = Set(within = model.S_TRAYS) +model.S_RECTIFICATION = Set(within=model.S_TRAYS) +model.S_STRIPPING = Set(within=model.S_TRAYS) model.x0 = Param(model.S_TRAYS) -model.t = ContinuousSet(initialize=range(1,52)) +model.t = ContinuousSet(initialize=range(1, 52)) # Alternatively you could simply specify bounds on the # ContinuousSet and let the finite element points be generated # automatically. # model.t = ContinuousSet(bounds=(1,51)) model.y = Var(model.S_TRAYS, model.t) -def x_init_rule(m,n,ti): + + +def x_init_rule(m, n, ti): return value(m.x0[n]) + + model.x = Var(model.S_TRAYS, model.t, initialize=x_init_rule) model.dx = DerivativeVar(model.x) -model.rr = Var(model.t,initialize=3.0) -model.L = Var(model.t,initialize=0.6) -model.V = Var(model.t,initialize=0.8) -model.FL = Var(model.t,initialize=1) -model.u1 = Var(model.t,initialize=3.0, bounds=(1,5)) +model.rr = Var(model.t, initialize=3.0) +model.L = Var(model.t, initialize=0.6) +model.V = Var(model.t, initialize=0.8) +model.FL = Var(model.t, initialize=1) +model.u1 = Var(model.t, initialize=3.0, bounds=(1, 5)) -model.alpha = Param(initialize = 1000) -model.rho = Param(initialize = 1) -model.u1_ref = Param(initialize = 2.0) -model.y1_ref = Param(initialize = 0.895814) +model.alpha = Param(initialize=1000) +model.rho = Param(initialize=1) +model.u1_ref = Param(initialize=2.0) +model.y1_ref = Param(initialize=0.895814) -### +### # Model constraints -### -def reflux_ratio_rule(m,t): +### +def reflux_ratio_rule(m, t): return m.rr[t] == m.u1[t] + + model.reflux_ratio = Constraint(model.t, rule=reflux_ratio_rule) -def flowrate_rectificaiton_rule(m,t): - return m.L[t] == m.rr[t]*m.D + +def flowrate_rectificaiton_rule(m, t): + return m.L[t] == m.rr[t] * m.D + + model.flowrate_rectificaiton = Constraint(model.t, rule=flowrate_rectificaiton_rule) -def vapor_column_rule(m,t): - return m.V[t] == m.L[t]+m.D + +def vapor_column_rule(m, t): + return m.V[t] == m.L[t] + m.D + + model.vapor_column = Constraint(model.t, rule=vapor_column_rule) -def flowrate_stripping_rule(m,t): + +def flowrate_stripping_rule(m, t): return m.FL[t] == m.Feed + m.L[t] + + model.flowrate_stripping = Constraint(model.t, rule=flowrate_stripping_rule) -def mole_frac_balance_rule(m,n,t): - return m.y[n,t] == m.x[n,t]*m.vol/(1+((m.vol-1)*m.x[n,t])) -model.mole_frac_balance = Constraint(model.S_TRAYS, model.t, rule=mole_frac_balance_rule) -def _diffeq(m,n,t): - +def mole_frac_balance_rule(m, n, t): + return m.y[n, t] == m.x[n, t] * m.vol / (1 + ((m.vol - 1) * m.x[n, t])) + + +model.mole_frac_balance = Constraint( + model.S_TRAYS, model.t, rule=mole_frac_balance_rule +) + + +def _diffeq(m, n, t): + if t == 1: return Constraint.Skip if n == 1: - return m.dx[n,t] == 1/m.acond*m.V[t]*(m.y[n+1,t]-m.x[n,t]) + return m.dx[n, t] == 1 / m.acond * m.V[t] * (m.y[n + 1, t] - m.x[n, t]) elif n in m.S_RECTIFICATION: - return m.dx[n,t] == 1/m.atray*(m.L[t]*(m.x[n-1,t]-m.x[n,t])-m.V[t]*(m.y[n,t]-m.y[n+1,t])) + return m.dx[n, t] == 1 / m.atray * ( + m.L[t] * (m.x[n - 1, t] - m.x[n, t]) - m.V[t] * (m.y[n, t] - m.y[n + 1, t]) + ) elif n == 17: - return m.dx[n,t] == 1/m.atray*(m.Feed*m.x_Feed+m.L[t]*m.x[n-1,t]-m.FL[t]*m.x[n,t]-m.V[t]*(m.y[n,t]-m.y[n+1,t])) + return m.dx[n, t] == 1 / m.atray * ( + m.Feed * m.x_Feed + + m.L[t] * m.x[n - 1, t] + - m.FL[t] * m.x[n, t] + - m.V[t] * (m.y[n, t] - m.y[n + 1, t]) + ) elif n in m.S_STRIPPING: - return m.dx[n,t] == 1/m.atray*(m.FL[t]*(m.x[n-1,t]-m.x[n,t])-m.V[t]*(m.y[n,t]-m.y[n+1,t])) - else : - return m.dx[n,t] == 1/m.areb*(m.FL[t]*m.x[n-1,t]-(m.Feed-m.D)*m.x[n,t]-m.V[t]*m.y[n,t]) + return m.dx[n, t] == 1 / m.atray * ( + m.FL[t] * (m.x[n - 1, t] - m.x[n, t]) - m.V[t] * (m.y[n, t] - m.y[n + 1, t]) + ) + else: + return m.dx[n, t] == 1 / m.areb * ( + m.FL[t] * m.x[n - 1, t] - (m.Feed - m.D) * m.x[n, t] - m.V[t] * m.y[n, t] + ) + + model.diffeq = Constraint(model.S_TRAYS, model.t, rule=_diffeq) -def _init_rule(m,n): - return m.x[n,1] == m.x0[n] -model.init_rule = Constraint(model.S_TRAYS, rule=_init_rule) - +def _init_rule(m, n): + return m.x[n, 1] == m.x0[n] + + +model.init_rule = Constraint(model.S_TRAYS, rule=_init_rule) diff --git a/examples/dae/dynamic_scheduling.py b/examples/dae/dynamic_scheduling.py index 571a1fbbd9b..d6355209300 100644 --- a/examples/dae/dynamic_scheduling.py +++ b/examples/dae/dynamic_scheduling.py @@ -8,7 +8,7 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -# +# # This is a toy example for scheduling a sequence of reactions taking # place in a single reactor. It combines the Pyomo DAE and GDP # packages and includes modeling concepts from the DAE car example and @@ -20,77 +20,93 @@ m = ConcreteModel() -m.products = Set(initialize=['A','B']) -m.AthenB = Set(initialize=[0,1]) +m.products = Set(initialize=['A', 'B']) +m.AthenB = Set(initialize=[0, 1]) -m.tau = ContinuousSet(bounds=[0,1]) # Unscaled Time +m.tau = ContinuousSet(bounds=[0, 1]) # Unscaled Time -m.k = Param(m.products, initialize={'A':1, 'B':5}) # Reaction Rates +m.k = Param(m.products, initialize={'A': 1, 'B': 5}) # Reaction Rates # Cost of having 'A' or 'B' in the final product stream -m.cost = Param(m.products, initialize={'A':15000, 'B':20000}) +m.cost = Param(m.products, initialize={'A': 15000, 'B': 20000}) -m.tstart = Var(m.products,bounds=(0,None)) # Start Time -m.tproc = Var(m.products,bounds=(0,None)) # Processing Time -m.time = Var(m.products, m.tau, bounds=(0,None)) # Scaled time over each job -m.totaltime = Var() # Total job time +m.tstart = Var(m.products, bounds=(0, None)) # Start Time +m.tproc = Var(m.products, bounds=(0, None)) # Processing Time +m.time = Var(m.products, m.tau, bounds=(0, None)) # Scaled time over each job +m.totaltime = Var() # Total job time -m.c = Var(m.products, m.tau, bounds=(0,None)) +m.c = Var(m.products, m.tau, bounds=(0, None)) m.dc = DerivativeVar(m.c, wrt=m.tau) m.dtime = DerivativeVar(m.time, wrt=m.tau) # Initial concentrations -m.c['A',0].fix(4) -m.c['B',0].fix(3) +m.c['A', 0].fix(4) +m.c['B', 0].fix(3) # Reaction kinetics -def _diffeq(m,p,t): - return m.dc[p,t] == -m.tproc[p]*m.k[p]*m.c[p,t] +def _diffeq(m, p, t): + return m.dc[p, t] == -m.tproc[p] * m.k[p] * m.c[p, t] + + m.diffeq = Constraint(m.products, m.tau, rule=_diffeq) # Initial time -m.time['A',0].fix(0) -m.time['B',0].fix(0) +m.time['A', 0].fix(0) +m.time['B', 0].fix(0) -# Bound on the final concentration of reactants +# Bound on the final concentration of reactants def _finalc(m, p): - return m.c[p,1] <= 0.001 + return m.c[p, 1] <= 0.001 + + m.finalc = Constraint(m.products, rule=_finalc) # Scaled time -def _diffeqtime(m,p,t): - return m.dtime[p,t] == m.tproc[p] +def _diffeqtime(m, p, t): + return m.dtime[p, t] == m.tproc[p] + + m.diffeqtime = Constraint(m.products, m.tau, rule=_diffeqtime) # No clash disjuncts def _noclash(disjunct, AthenB): model = disjunct.model() if AthenB: - e = model.tstart['A']+model.tproc['A'] <= model.tstart['B'] + e = model.tstart['A'] + model.tproc['A'] <= model.tstart['B'] disjunct.c = Constraint(expr=e) else: - e = model.tstart['B']+model.tproc['B'] <= model.tstart['A'] + e = model.tstart['B'] + model.tproc['B'] <= model.tstart['A'] disjunct.c = Constraint(expr=e) + + m.noclash = Disjunct(m.AthenB, rule=_noclash) # Define the disjunctions: either job I occurs before K or K before I def _disj(model): return [model.noclash[AthenB] for AthenB in model.AthenB] + + m.disj = Disjunction(rule=_disj) # Due Time def _duetime(m): - return m.tstart['B']+m.tproc['B'] <= 2.0 + return m.tstart['B'] + m.tproc['B'] <= 2.0 + + m.duetime = Constraint(rule=_duetime) # Feasibility def _feas(m, p): - return m.totaltime >= m.tstart[p]+m.tproc[p] + return m.totaltime >= m.tstart[p] + m.tproc[p] + + m.feas = Constraint(m.products, rule=_feas) # Objective def _obj(m): - return m.totaltime + sum(m.cost[p]*m.c[p,1] for p in m.products) + return m.totaltime + sum(m.cost[p] * m.c[p, 1] for p in m.products) + + m.obj = Objective(rule=_obj) # Discretize model @@ -103,19 +119,19 @@ def _obj(m): # Solve the model solver = SolverFactory('couenne') -solver.solve(m,tee=True) +solver.solve(m, tee=True) # Plot the results import matplotlib.pyplot as plt -timeA = [value(m.time['A',i])+value(m.tstart['A']) for i in m.tau] -timeB = [value(m.time['B',i])+value(m.tstart['B']) for i in m.tau] +timeA = [value(m.time['A', i]) + value(m.tstart['A']) for i in m.tau] +timeB = [value(m.time['B', i]) + value(m.tstart['B']) for i in m.tau] -concA = [value(m.c['A',i]) for i in m.tau] -concB = [value(m.c['B',i]) for i in m.tau] +concA = [value(m.c['A', i]) for i in m.tau] +concB = [value(m.c['B', i]) for i in m.tau] -plt.plot(timeA,concA,'r',label='Reactant A') -plt.plot(timeB,concB,'b',label='Reactant B') +plt.plot(timeA, concA, 'r', label='Reactant A') +plt.plot(timeB, concB, 'b', label='Reactant B') plt.legend(loc='best') plt.xlabel('Time') plt.ylabel('Concentration in Reactor') diff --git a/examples/dae/laplace_BVP.py b/examples/dae/laplace_BVP.py index 255a65df350..6b2e2841575 100644 --- a/examples/dae/laplace_BVP.py +++ b/examples/dae/laplace_BVP.py @@ -13,70 +13,88 @@ from pyomo.dae import * m = ConcreteModel() -m.x = ContinuousSet(bounds=(0,1)) -m.y = ContinuousSet(bounds=(0,1)) -m.u = Var(m.x,m.y) +m.x = ContinuousSet(bounds=(0, 1)) +m.y = ContinuousSet(bounds=(0, 1)) +m.u = Var(m.x, m.y) -m.dudx = DerivativeVar(m.u,wrt=(m.x,m.x)) -m.dudy = DerivativeVar(m.u,wrt=(m.y,m.y)) +m.dudx = DerivativeVar(m.u, wrt=(m.x, m.x)) +m.dudy = DerivativeVar(m.u, wrt=(m.y, m.y)) -def _lowerY(m,i): + +def _lowerY(m, i): if i == 0 or i == 1: return Constraint.Skip - return m.u[i,0] == 1 -m.lowerY = Constraint(m.x,rule=_lowerY) + return m.u[i, 0] == 1 + + +m.lowerY = Constraint(m.x, rule=_lowerY) -def _upperY(m,i): + +def _upperY(m, i): if i == 0 or i == 1: return Constraint.Skip - return m.u[i,1] == 2 -m.upperY = Constraint(m.x,rule=_upperY) + return m.u[i, 1] == 2 + -def _lowerX(m,j): +m.upperY = Constraint(m.x, rule=_upperY) + + +def _lowerX(m, j): if j == 0 or j == 1: return Constraint.Skip - return m.u[0,j] == 1 -m.lowerX = Constraint(m.y,rule=_lowerX) + return m.u[0, j] == 1 + + +m.lowerX = Constraint(m.y, rule=_lowerX) + -def _upperX(m,j): +def _upperX(m, j): if j == 0 or j == 1: return Constraint.Skip - return m.u[1,j] == 2 -m.upperX = Constraint(m.y,rule=_upperX) + return m.u[1, j] == 2 -def _laplace(m,i,j): + +m.upperX = Constraint(m.y, rule=_upperX) + + +def _laplace(m, i, j): if i == 0 or i == 1: return Constraint.Skip if j == 0 or j == 1: return Constraint.Skip - return m.dudx[i,j] + m.dudy[i,j] == 0 -m.laplace = Constraint(m.x,m.y,rule=_laplace) + return m.dudx[i, j] + m.dudy[i, j] == 0 + + +m.laplace = Constraint(m.x, m.y, rule=_laplace) + def _dummy(m): return 1.0 + + m.obj = Objective(rule=_dummy) discretizer = TransformationFactory('dae.finite_difference') -discretizer.apply_to(m,nfe=20,wrt=m.y,scheme='FORWARD') -discretizer.apply_to(m,nfe=20,wrt=m.x,scheme='CENTRAL') +discretizer.apply_to(m, nfe=20, wrt=m.y, scheme='FORWARD') +discretizer.apply_to(m, nfe=20, wrt=m.x, scheme='CENTRAL') -solver=SolverFactory('ipopt') +solver = SolverFactory('ipopt') -results = solver.solve(m,tee=True) +results = solver.solve(m, tee=True) -#disc.u.pprint() +# disc.u.pprint() x = [] y = [] u = [] for i in sorted(m.x): - temp=[] + temp = [] tempx = [] for j in sorted(m.y): tempx.append(i) - temp.append(value(m.u[i,j])) + temp.append(value(m.u[i, j])) x.append(tempx) y.append(sorted(m.y)) u.append(temp) @@ -85,7 +103,8 @@ def _dummy(m): import numpy import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.axes3d import Axes3D + fig = plt.figure() -ax = fig.add_subplot(1,1,1,projection='3d') -p = ax.plot_wireframe(x,y,u,rstride=1,cstride=1) +ax = fig.add_subplot(1, 1, 1, projection='3d') +p = ax.plot_wireframe(x, y, u, rstride=1, cstride=1) fig.show() diff --git a/examples/dae/run_Optimal_Control.py b/examples/dae/run_Optimal_Control.py index 7c767da2235..2523bd8c607 100644 --- a/examples/dae/run_Optimal_Control.py +++ b/examples/dae/run_Optimal_Control.py @@ -19,17 +19,17 @@ # Discretize model using Orthogonal Collocation discretizer = TransformationFactory('dae.collocation') -discretizer.apply_to(m,nfe=20,ncp=3,scheme='LAGRANGE-RADAU') -discretizer.reduce_collocation_points(m,var=m.u,ncp=1,contset=m.t) +discretizer.apply_to(m, nfe=20, ncp=3, scheme='LAGRANGE-RADAU') +discretizer.reduce_collocation_points(m, var=m.u, ncp=1, contset=m.t) -solver=SolverFactory('ipopt') +solver = SolverFactory('ipopt') -results = solver.solve(m,tee=True) +results = solver.solve(m, tee=True) x1 = [] x2 = [] u = [] -t=[] +t = [] print(sorted(m.t)) @@ -41,9 +41,9 @@ import matplotlib.pyplot as plt -plt.plot(t,x1) -plt.plot(t,x2) +plt.plot(t, x1) +plt.plot(t, x2) plt.show() -plt.plot(t,u) +plt.plot(t, u) plt.show() diff --git a/examples/dae/run_Parameter_Estimation.py b/examples/dae/run_Parameter_Estimation.py index 2e850eb5c9d..a319000cb59 100644 --- a/examples/dae/run_Parameter_Estimation.py +++ b/examples/dae/run_Parameter_Estimation.py @@ -22,16 +22,16 @@ # Discretize model using Orthogonal Collocation discretizer = TransformationFactory('dae.collocation') -discretizer.apply_to(instance,nfe=8,ncp=5) +discretizer.apply_to(instance, nfe=8, ncp=5) -solver=SolverFactory('ipopt') +solver = SolverFactory('ipopt') -results = solver.solve(instance,tee=True) +results = solver.solve(instance, tee=True) x1 = [] x1_meas = [] -t=[] -t_meas=[] +t = [] +t_meas = [] print(sorted(instance.t)) @@ -42,11 +42,11 @@ for i in sorted(instance.t): t.append(i) x1.append(value(instance.x1[i])) - + import matplotlib.pyplot as plt -plt.plot(t,x1) -plt.plot(t_meas,x1_meas,'o') +plt.plot(t, x1) +plt.plot(t_meas, x1_meas, 'o') plt.xlabel('t') plt.ylabel('x') plt.title('Dynamic Parameter Estimation Using Collocation') diff --git a/examples/dae/run_Path_Constraint.py b/examples/dae/run_Path_Constraint.py index 4da6e59b006..17a576a57d8 100644 --- a/examples/dae/run_Path_Constraint.py +++ b/examples/dae/run_Path_Constraint.py @@ -19,22 +19,28 @@ # Discretize model using Orthogonal Collocation discretizer = TransformationFactory('dae.collocation') -discretizer.apply_to(m,nfe=7,ncp=6,scheme='LAGRANGE-RADAU') -discretizer.reduce_collocation_points(m,var=m.u,ncp=1,contset=m.t) +discretizer.apply_to(m, nfe=7, ncp=6, scheme='LAGRANGE-RADAU') +discretizer.reduce_collocation_points(m, var=m.u, ncp=1, contset=m.t) results = SolverFactory('ipopt').solve(m, tee=True) + def plotter(subplot, x, *series, **kwds): plt.subplot(subplot) - for i,y in enumerate(series): - plt.plot(list(x), [value(y[t]) for t in x], - 'brgcmk'[i%6]+kwds.get('points','')) - plt.title(kwds.get('title','')) - plt.legend(tuple(y.name for y in series), frameon=True, edgecolor='k').draw_frame(True) + for i, y in enumerate(series): + plt.plot( + list(x), [value(y[t]) for t in x], 'brgcmk'[i % 6] + kwds.get('points', '') + ) + plt.title(kwds.get('title', '')) + plt.legend(tuple(y.name for y in series), frameon=True, edgecolor='k').draw_frame( + True + ) plt.xlabel(x.name) - plt.gca().set_xlim([0,1]) + plt.gca().set_xlim([0, 1]) + import matplotlib.pyplot as plt + plotter(121, m.t, m.x1, m.x2, m.x3, title='Differential Variables') plotter(122, m.t, m.u, title='Control Variables', points='o-') plt.show() diff --git a/examples/dae/run_disease.py b/examples/dae/run_disease.py index 9f6f7811eb0..139046d434e 100644 --- a/examples/dae/run_disease.py +++ b/examples/dae/run_disease.py @@ -5,12 +5,16 @@ instance = model.create_instance('disease.dat') discretizer = TransformationFactory('dae.collocation') -discretizer.apply_to(instance,nfe=520,ncp=3) +discretizer.apply_to(instance, nfe=520, ncp=3) + def _S_bar(model): - return model.S_bar == sum(model.S[i] for i in model.TIME if i != 0)/(len(model.TIME)-1) -instance.con_S_bar = Constraint(rule=_S_bar) + return model.S_bar == sum(model.S[i] for i in model.TIME if i != 0) / ( + len(model.TIME) - 1 + ) -solver=SolverFactory('ipopt') -results = solver.solve(instance,tee=True) +instance.con_S_bar = Constraint(rule=_S_bar) + +solver = SolverFactory('ipopt') +results = solver.solve(instance, tee=True) diff --git a/examples/dae/run_distill.py b/examples/dae/run_distill.py index df449277fa0..d9ececf34fc 100644 --- a/examples/dae/run_distill.py +++ b/examples/dae/run_distill.py @@ -17,7 +17,7 @@ # Discretize using Finite Difference Approach discretizer = TransformationFactory('dae.finite_difference') -discretizer.apply_to(instance,nfe=50,scheme='BACKWARD') +discretizer.apply_to(instance, nfe=50, scheme='BACKWARD') # Discretize using Orthogonal Collocation # discretizer = TransformationFactory('dae.collocation') @@ -30,27 +30,32 @@ # discretized to ensure that we include all the discretization points # when we take the sum. + def obj_rule(m): - return m.alpha*sum((m.y[1,i] - m.y1_ref)**2 for i in m.t if i != 1) + m.rho*sum((m.u1[i] - m.u1_ref)**2 for i in m.t if i!=1) -instance.OBJ = Objective(rule=obj_rule) + return m.alpha * sum( + (m.y[1, i] - m.y1_ref) ** 2 for i in m.t if i != 1 + ) + m.rho * sum((m.u1[i] - m.u1_ref) ** 2 for i in m.t if i != 1) + + +instance.OBJ = Objective(rule=obj_rule) -solver=SolverFactory('ipopt') +solver = SolverFactory('ipopt') -results = solver.solve(instance,tee=True) +results = solver.solve(instance, tee=True) # If you have matplotlib you can use the following code to plot the # results -t = [] -x5 = [] +t = [] +x5 = [] x20 = [] -for i in sorted(instance.t): - x5.append(value(instance.x[5,i])) - x20.append(value(instance.x[20,i])) +for i in sorted(instance.t): + x5.append(value(instance.x[5, i])) + x20.append(value(instance.x[20, i])) t.append(i) import matplotlib.pyplot as plt -plt.plot(t,x5) -plt.plot(t,x20) +plt.plot(t, x5) +plt.plot(t, x20) plt.show() diff --git a/examples/dae/run_stochpdegas_automatic.py b/examples/dae/run_stochpdegas_automatic.py index 7df16b0e844..dd710588406 100644 --- a/examples/dae/run_stochpdegas_automatic.py +++ b/examples/dae/run_stochpdegas_automatic.py @@ -9,65 +9,126 @@ # discretize model discretizer = TransformationFactory('dae.finite_difference') -discretizer.apply_to(instance,nfe=1,wrt=instance.DIS,scheme='FORWARD') -discretizer.apply_to(instance,nfe=47,wrt=instance.TIME,scheme='BACKWARD') +discretizer.apply_to(instance, nfe=1, wrt=instance.DIS, scheme='FORWARD') +discretizer.apply_to(instance, nfe=47, wrt=instance.TIME, scheme='BACKWARD') # What it should be to match description in paper -#discretizer.apply_to(instance,nfe=48,wrt=instance.TIME,scheme='BACKWARD') +# discretizer.apply_to(instance,nfe=48,wrt=instance.TIME,scheme='BACKWARD') TimeStep = instance.TIME.at(2) - instance.TIME.at(1) -def supcost_rule(m,k): - return sum(m.cs*m.s[k,j,t]*(TimeStep) for j in m.SUP for t in m.TIME.get_finite_elements()) -instance.supcost = Expression(instance.SCEN,rule=supcost_rule) -def boostcost_rule(m,k): - return sum(m.ce*m.pow[k,j,t]*(TimeStep) for j in m.LINK_A for t in m.TIME.get_finite_elements()) -instance.boostcost = Expression(instance.SCEN,rule=boostcost_rule) +def supcost_rule(m, k): + return sum( + m.cs * m.s[k, j, t] * (TimeStep) + for j in m.SUP + for t in m.TIME.get_finite_elements() + ) -def trackcost_rule(m,k): - return sum(m.cd*(m.dem[k,j,t]-m.stochd[k,j,t])**2.0 for j in m.DEM for t in m.TIME.get_finite_elements()) -instance.trackcost = Expression(instance.SCEN,rule=trackcost_rule) -def sspcost_rule(m,k): - return sum(m.cT*(m.px[k,i,m.TIME.last(),j]-m.px[k,i,m.TIME.first(),j])**2.0 for i in m.LINK for j in m.DIS) -instance.sspcost = Expression(instance.SCEN,rule=sspcost_rule) +instance.supcost = Expression(instance.SCEN, rule=supcost_rule) -def ssfcost_rule(m,k): - return sum(m.cT*(m.fx[k,i,m.TIME.last(),j]-m.fx[k,i,m.TIME.first(),j])**2.0 for i in m.LINK for j in m.DIS) -instance.ssfcost = Expression(instance.SCEN,rule=ssfcost_rule) -def cost_rule(m,k): - return 1e-6*(m.supcost[k] + m.boostcost[k] + m.trackcost[k] + m.sspcost[k] + m.ssfcost[k]) -instance.cost = Expression(instance.SCEN,rule=cost_rule) +def boostcost_rule(m, k): + return sum( + m.ce * m.pow[k, j, t] * (TimeStep) + for j in m.LINK_A + for t in m.TIME.get_finite_elements() + ) + + +instance.boostcost = Expression(instance.SCEN, rule=boostcost_rule) + + +def trackcost_rule(m, k): + return sum( + m.cd * (m.dem[k, j, t] - m.stochd[k, j, t]) ** 2.0 + for j in m.DEM + for t in m.TIME.get_finite_elements() + ) + + +instance.trackcost = Expression(instance.SCEN, rule=trackcost_rule) + + +def sspcost_rule(m, k): + return sum( + m.cT * (m.px[k, i, m.TIME.last(), j] - m.px[k, i, m.TIME.first(), j]) ** 2.0 + for i in m.LINK + for j in m.DIS + ) + + +instance.sspcost = Expression(instance.SCEN, rule=sspcost_rule) + + +def ssfcost_rule(m, k): + return sum( + m.cT * (m.fx[k, i, m.TIME.last(), j] - m.fx[k, i, m.TIME.first(), j]) ** 2.0 + for i in m.LINK + for j in m.DIS + ) + + +instance.ssfcost = Expression(instance.SCEN, rule=ssfcost_rule) + + +def cost_rule(m, k): + return 1e-6 * ( + m.supcost[k] + m.boostcost[k] + m.trackcost[k] + m.sspcost[k] + m.ssfcost[k] + ) + + +instance.cost = Expression(instance.SCEN, rule=cost_rule) + def mcost_rule(m): - return (1.0/m.S)*sum(m.cost[k] for k in m.SCEN) + return (1.0 / m.S) * sum(m.cost[k] for k in m.SCEN) + + instance.mcost = Expression(rule=mcost_rule) -def eqcvar_rule(m,k): - return m.cost[k] - m.nu <= m.phi[k]; -instance.eqcvar = Constraint(instance.SCEN,rule=eqcvar_rule) + +def eqcvar_rule(m, k): + return m.cost[k] - m.nu <= m.phi[k] + + +instance.eqcvar = Constraint(instance.SCEN, rule=eqcvar_rule) + def obj_rule(m): - return (1.0-m.cvar_lambda)*m.mcost + m.cvar_lambda*m.cvarcost + return (1.0 - m.cvar_lambda) * m.mcost + m.cvar_lambda * m.cvarcost + + instance.obj = Objective(rule=obj_rule) -endTime = time.time()-start +endTime = time.time() - start print('model creation time = %s' % (endTime,)) for i in instance.SCEN: - print("Scenario %s = %s" % ( - i, sum(sum(0.5*value(instance.pow[i,j,k]) - for j in instance.LINK_A) - for k in instance.TIME.get_finite_elements()) )) + print( + "Scenario %s = %s" + % ( + i, + sum( + sum(0.5 * value(instance.pow[i, j, k]) for j in instance.LINK_A) + for k in instance.TIME.get_finite_elements() + ), + ) + ) -solver=SolverFactory('ipopt') -results = solver.solve(instance,tee=True) +solver = SolverFactory('ipopt') +results = solver.solve(instance, tee=True) for i in instance.SCEN: - print("Scenario %s = %s" % ( - i, sum(sum(0.5*value(instance.pow[i,j,k]) - for j in instance.LINK_A) - for k in instance.TIME.get_finite_elements()) )) + print( + "Scenario %s = %s" + % ( + i, + sum( + sum(0.5 * value(instance.pow[i, j, k]) for j in instance.LINK_A) + for k in instance.TIME.get_finite_elements() + ), + ) + ) diff --git a/examples/dae/simulator_dae_example.py b/examples/dae/simulator_dae_example.py index 8847ab35d50..ef6484be6c6 100644 --- a/examples/dae/simulator_dae_example.py +++ b/examples/dae/simulator_dae_example.py @@ -38,15 +38,17 @@ def create_model(): def _diffeq1(m, t): return m.dza[t] == -m.p1 * m.za[t] + m.p2 * m.zb[t] + m.diffeq1 = Constraint(m.t, rule=_diffeq1) def _diffeq2(m, t): - return m.dzb[t] == m.p1 * m.za[t] - \ - (m.p2 + m.p3) * m.zb[t] + m.p4 * m.zc[t] + return m.dzb[t] == m.p1 * m.za[t] - (m.p2 + m.p3) * m.zb[t] + m.p4 * m.zc[t] + m.diffeq2 = Constraint(m.t, rule=_diffeq2) def _algeq1(m, t): return m.za[t] + m.zb[t] + m.zc[t] == 1 + m.algeq1 = Constraint(m.t, rule=_algeq1) return m @@ -90,6 +92,7 @@ def plot_result(m, sim, tsim, profiles): plt.legend(loc='best') plt.show() + if __name__ == "__main__": model = create_model() sim, tsim, profiles = simulate_model(model) diff --git a/examples/dae/simulator_dae_multindex_example.py b/examples/dae/simulator_dae_multindex_example.py index 497cfc3650c..d1a97fec79f 100644 --- a/examples/dae/simulator_dae_multindex_example.py +++ b/examples/dae/simulator_dae_multindex_example.py @@ -28,6 +28,7 @@ def _p1_init(m, t): if t >= 0.5: return 1.0 return 4.0 + m.p1 = Param(m.t, initialize=4.0, default=_p1_init) m.p2 = Param(initialize=2.0) m.p3 = Param(initialize=40.0) @@ -50,15 +51,17 @@ def _p1_init(m, t): def _diffeq1(m, t): return m.dza[t] == -m.p1[t] * m.za[t] + m.p2 * m.zb[t] + m.diffeq1 = Constraint(m.t, rule=_diffeq1) def _diffeq2(m, t): - return m.dzb[t] == m.p1[t] * m.za[t] - \ - (m.p2 + m.p3) * m.zb[t] + m.p4 * m.zc[t] + return m.dzb[t] == m.p1[t] * m.za[t] - (m.p2 + m.p3) * m.zb[t] + m.p4 * m.zc[t] + m.diffeq2 = Constraint(m.t, rule=_diffeq2) def _algeq1(m, t): return m.za[t] + m.zb[t] + m.zc[t] == 1 + m.algeq1 = Constraint(m.t, rule=_algeq1) return m @@ -66,8 +69,9 @@ def _algeq1(m, t): def simulate_model(m): # Simulate the model using casadi sim = Simulator(m, package='casadi') - tsim, profiles = sim.simulate(numpoints=100, integrator='idas', - varying_inputs=m.var_input) + tsim, profiles = sim.simulate( + numpoints=100, integrator='idas', varying_inputs=m.var_input + ) # Discretize model using Orthogonal Collocation discretizer = TransformationFactory('dae.collocation') @@ -103,6 +107,7 @@ def plot_results(m, sim, tsim, profiles): plt.legend(loc='best') plt.show() + if __name__ == "__main__": model = create_model() sim, tsim, profiles = simulate_model(model) diff --git a/examples/dae/simulator_ode_example.py b/examples/dae/simulator_ode_example.py index b5f7c85fe0d..bf600cf163e 100644 --- a/examples/dae/simulator_ode_example.py +++ b/examples/dae/simulator_ode_example.py @@ -32,10 +32,12 @@ def create_model(): def _diffeq1(m, t): return m.domegadt[t] == -m.b * m.omega[t] - m.c * sin(m.theta[t]) + m.diffeq1 = Constraint(m.t, rule=_diffeq1) def _diffeq2(m, t): return m.dthetadt[t] == m.omega[t] + m.diffeq2 = Constraint(m.t, rule=_diffeq2) return m @@ -78,6 +80,7 @@ def plot_result(m, sim, tsim, profiles): plt.legend(loc='best') plt.show() + if __name__ == "__main__": model = create_model() sim, tsim, profiles = simulate_model(model) diff --git a/examples/dae/simulator_ode_multindex_example.py b/examples/dae/simulator_ode_multindex_example.py index fc42d276d76..367a2fd099d 100644 --- a/examples/dae/simulator_ode_multindex_example.py +++ b/examples/dae/simulator_ode_multindex_example.py @@ -24,12 +24,14 @@ def _b_default(m, t): if t >= 15: return 0.025 return 0.25 + m.b = Param(m.t, initialize=0.25, default=_b_default) def _c_default(m, t): if t >= 7: return 50 return 5 + m.c = Param(m.t, initialize=5.0, default=_c_default) m.omega = Var(m.t) @@ -43,12 +45,13 @@ def _c_default(m, t): m.theta[0] = 3.14 - 0.1 def _diffeq1(m, t): - return m.domegadt[t] == -m.b[t] * m.omega[t] - \ - m.c[t] * sin(m.theta[t]) + return m.domegadt[t] == -m.b[t] * m.omega[t] - m.c[t] * sin(m.theta[t]) + m.diffeq1 = Constraint(m.t, rule=_diffeq1) def _diffeq2(m, t): return m.dthetadt[t] == m.omega[t] + m.diffeq2 = Constraint(m.t, rule=_diffeq2) b_profile = {0: 0.25, 15: 0.025} @@ -66,15 +69,15 @@ def simulate_model(m): if False: # Simulate the model using casadi sim = Simulator(m, package='casadi') - tsim, profiles = sim.simulate(numpoints=200, - integrator='cvodes', - varying_inputs=m.var_input) + tsim, profiles = sim.simulate( + numpoints=200, integrator='cvodes', varying_inputs=m.var_input + ) else: # Simulate the model using scipy sim = Simulator(m, package='scipy') - tsim, profiles = sim.simulate(numpoints=200, - integrator='vode', - varying_inputs=m.var_input) + tsim, profiles = sim.simulate( + numpoints=200, integrator='vode', varying_inputs=m.var_input + ) # Discretize model using Orthogonal Collocation discretizer = TransformationFactory('dae.collocation') @@ -102,6 +105,7 @@ def plot_result(m, sim, tsim, profiles): plt.legend(loc='best') plt.show() + if __name__ == "__main__": model = create_model() sim, tsim, profiles = simulate_model(model) diff --git a/examples/dae/stochpdegas_automatic.py b/examples/dae/stochpdegas_automatic.py index beb4099c453..7bc1ed6ee98 100644 --- a/examples/dae/stochpdegas_automatic.py +++ b/examples/dae/stochpdegas_automatic.py @@ -1,7 +1,7 @@ # stochastic pde model for natural gas network # victor m. zavala / 2013 -#from __future__ import division +# from __future__ import division from pyomo.environ import * from pyomo.dae import * @@ -10,117 +10,142 @@ # sets model.TF = Param(within=NonNegativeReals) + + def _tinit(m): - return [0.5,value(m.TF)] + return [0.5, value(m.TF)] # What it should be to match description in paper - #return [0,value(m.TF)] + # return [0,value(m.TF)] + + model.TIME = ContinuousSet(initialize=_tinit) -model.DIS = ContinuousSet(bounds=(0.0,1.0)) +model.DIS = ContinuousSet(bounds=(0.0, 1.0)) model.S = Param(within=PositiveIntegers) -model.SCEN = RangeSet(1,model.S) +model.SCEN = RangeSet(1, model.S) # links model.LINK = Set(dimen=1) model.lstartloc = Param(model.LINK, within=Any) model.lendloc = Param(model.LINK, within=Any) -model.ldiam = Param(model.LINK,within=PositiveReals,mutable=True) -model.llength = Param(model.LINK,within=PositiveReals,mutable=True) +model.ldiam = Param(model.LINK, within=PositiveReals, mutable=True) +model.llength = Param(model.LINK, within=PositiveReals, mutable=True) model.ltype = Param(model.LINK, within=Any) + def link_a_init_rule(m): return (l for l in m.LINK if m.ltype[l] == "a") + + model.LINK_A = Set(initialize=link_a_init_rule) + def link_p_init_rule(m): return (l for l in m.LINK if m.ltype[l] == "p") + + model.LINK_P = Set(initialize=link_p_init_rule) # nodes model.NODE = Set() -model.pmin = Param(model.NODE,within=PositiveReals,mutable=True) -model.pmax = Param(model.NODE,within=PositiveReals,mutable=True) +model.pmin = Param(model.NODE, within=PositiveReals, mutable=True) +model.pmax = Param(model.NODE, within=PositiveReals, mutable=True) # supply model.SUP = Set() model.sloc = Param(model.SUP, within=Any) -model.smin = Param(model.SUP,within=NonNegativeReals,mutable=True) -model.smax = Param(model.SUP,within=NonNegativeReals,mutable=True) -model.scost = Param(model.SUP,within=NonNegativeReals) +model.smin = Param(model.SUP, within=NonNegativeReals, mutable=True) +model.smax = Param(model.SUP, within=NonNegativeReals, mutable=True) +model.scost = Param(model.SUP, within=NonNegativeReals) # demand model.DEM = Set() model.dloc = Param(model.DEM, within=Any) -model.d = Param(model.DEM, within=PositiveReals,mutable=True) +model.d = Param(model.DEM, within=PositiveReals, mutable=True) # physical data -model.eps = Param(initialize=0.025,within=PositiveReals) -model.z = Param(initialize=0.80,within=PositiveReals) -model.rhon = Param(initialize=0.72,within=PositiveReals) -model.R = Param(initialize=8314.0,within=PositiveReals) -model.M = Param(initialize=18.0,within=PositiveReals) -model.pi = Param(initialize=3.14,within=PositiveReals) -model.nu2 = Param(within=PositiveReals,mutable=True) -model.lam = Param(model.LINK,within=PositiveReals,mutable=True) -model.A = Param(model.LINK,within=NonNegativeReals,mutable=True) -model.Tgas = Param(initialize=293.15,within=PositiveReals) -model.Cp = Param(initialize=2.34,within=PositiveReals) -model.Cv = Param(initialize=1.85,within=PositiveReals) -model.gam = Param(initialize=model.Cp/model.Cv, within=PositiveReals) -model.om = Param(initialize=(model.gam-1.0)/model.gam,within=PositiveReals) +model.eps = Param(initialize=0.025, within=PositiveReals) +model.z = Param(initialize=0.80, within=PositiveReals) +model.rhon = Param(initialize=0.72, within=PositiveReals) +model.R = Param(initialize=8314.0, within=PositiveReals) +model.M = Param(initialize=18.0, within=PositiveReals) +model.pi = Param(initialize=3.14, within=PositiveReals) +model.nu2 = Param(within=PositiveReals, mutable=True) +model.lam = Param(model.LINK, within=PositiveReals, mutable=True) +model.A = Param(model.LINK, within=NonNegativeReals, mutable=True) +model.Tgas = Param(initialize=293.15, within=PositiveReals) +model.Cp = Param(initialize=2.34, within=PositiveReals) +model.Cv = Param(initialize=1.85, within=PositiveReals) +model.gam = Param(initialize=model.Cp / model.Cv, within=PositiveReals) +model.om = Param(initialize=(model.gam - 1.0) / model.gam, within=PositiveReals) # scaling and constants -model.ffac = Param(within=PositiveReals,initialize=(1.0e+6*model.rhon)/(24.0*3600.0)) -model.ffac2 = Param(within=PositiveReals,initialize=(3600.0)/(1.0e+4*model.rhon)) -model.pfac = Param(within=PositiveReals,initialize=1.0e+5) -model.pfac2 = Param(within=PositiveReals,initialize=1.0e-5) -model.dfac = Param(within=PositiveReals,initialize=1.0e-3) -model.lfac = Param(within=PositiveReals,initialize=1.0e+3) - -model.c1 = Param(model.LINK,within=PositiveReals,mutable=True) -model.c2 = Param(model.LINK,within=PositiveReals,mutable=True) -model.c3 = Param(model.LINK,within=PositiveReals,mutable=True) -model.c4 = Param(within=PositiveReals,mutable=True) +model.ffac = Param( + within=PositiveReals, initialize=(1.0e6 * model.rhon) / (24.0 * 3600.0) +) +model.ffac2 = Param(within=PositiveReals, initialize=(3600.0) / (1.0e4 * model.rhon)) +model.pfac = Param(within=PositiveReals, initialize=1.0e5) +model.pfac2 = Param(within=PositiveReals, initialize=1.0e-5) +model.dfac = Param(within=PositiveReals, initialize=1.0e-3) +model.lfac = Param(within=PositiveReals, initialize=1.0e3) + +model.c1 = Param(model.LINK, within=PositiveReals, mutable=True) +model.c2 = Param(model.LINK, within=PositiveReals, mutable=True) +model.c3 = Param(model.LINK, within=PositiveReals, mutable=True) +model.c4 = Param(within=PositiveReals, mutable=True) # cost factors -model.ce = Param(initialize=0.1,within=NonNegativeReals) -model.cd = Param(initialize=1.0e+6,within=NonNegativeReals) -model.cT = Param(initialize=1.0e+6,within=NonNegativeReals) -model.cs = Param(initialize=0.0,within=NonNegativeReals) +model.ce = Param(initialize=0.1, within=NonNegativeReals) +model.cd = Param(initialize=1.0e6, within=NonNegativeReals) +model.cT = Param(initialize=1.0e6, within=NonNegativeReals) +model.cs = Param(initialize=0.0, within=NonNegativeReals) model.TDEC = Param(within=PositiveReals) # define stochastic info -model.rand_d = Param(model.SCEN,model.DEM,within=NonNegativeReals,mutable=True) +model.rand_d = Param(model.SCEN, model.DEM, within=NonNegativeReals, mutable=True) # convert units for input data def rescale_rule(m): for i in m.LINK: - m.ldiam[i] = m.ldiam[i]*m.dfac - m.llength[i] = m.llength[i]*m.lfac + m.ldiam[i] = m.ldiam[i] * m.dfac + m.llength[i] = m.llength[i] * m.lfac # m.dx[i] = m.llength[i]/float(m.DIS.last()) for i in m.SUP: - m.smin[i] = m.smin[i]*m.ffac*m.ffac2 # from scmx106/day to kg/s and then to scmx10-4/hr - m.smax[i] = m.smax[i]*m.ffac*m.ffac2 # from scmx106/day to kg/s and then to scmx10-4/hr + m.smin[i] = ( + m.smin[i] * m.ffac * m.ffac2 + ) # from scmx106/day to kg/s and then to scmx10-4/hr + m.smax[i] = ( + m.smax[i] * m.ffac * m.ffac2 + ) # from scmx106/day to kg/s and then to scmx10-4/hr for i in m.DEM: - m.d[i] = m.d[i]*m.ffac*m.ffac2 + m.d[i] = m.d[i] * m.ffac * m.ffac2 for i in m.NODE: - m.pmin[i] = m.pmin[i]*m.pfac*m.pfac2 # from bar to Pascals and then to bar - m.pmax[i] = m.pmax[i]*m.pfac*m.pfac2 # from bar to Pascals and then to bar + m.pmin[i] = m.pmin[i] * m.pfac * m.pfac2 # from bar to Pascals and then to bar + m.pmax[i] = m.pmax[i] * m.pfac * m.pfac2 # from bar to Pascals and then to bar + + model.rescale = BuildAction(rule=rescale_rule) + def compute_constants(m): for i in m.LINK: - m.lam[i] = (2.0*log10(3.7*m.ldiam[i]/(m.eps*m.dfac)))**(-2.0) - m.A[i] = (1.0/4.0)*m.pi*m.ldiam[i]*m.ldiam[i] - m.nu2 = m.gam*m.z*m.R*m.Tgas/m.M - m.c1[i] = (m.pfac2/m.ffac2)*(m.nu2/m.A[i]) - m.c2[i] = m.A[i]*(m.ffac2/m.pfac2) - m.c3[i] = m.A[i]*(m.pfac2/m.ffac2)*(8.0*m.lam[i]*m.nu2)/(m.pi*m.pi*(m.ldiam[i]**5.0)) - m.c4 = (1/m.ffac2)*(m.Cp*m.Tgas) + m.lam[i] = (2.0 * log10(3.7 * m.ldiam[i] / (m.eps * m.dfac))) ** (-2.0) + m.A[i] = (1.0 / 4.0) * m.pi * m.ldiam[i] * m.ldiam[i] + m.nu2 = m.gam * m.z * m.R * m.Tgas / m.M + m.c1[i] = (m.pfac2 / m.ffac2) * (m.nu2 / m.A[i]) + m.c2[i] = m.A[i] * (m.ffac2 / m.pfac2) + m.c3[i] = ( + m.A[i] + * (m.pfac2 / m.ffac2) + * (8.0 * m.lam[i] * m.nu2) + / (m.pi * m.pi * (m.ldiam[i] ** 5.0)) + ) + m.c4 = (1 / m.ffac2) * (m.Cp * m.Tgas) + model.compute_constants = BuildAction(rule=compute_constants) @@ -130,14 +155,17 @@ def compute_demands_rule(m): for k in m.SCEN: for j in m.DEM: if k == 2: - m.rand_d[k,j] = 1.1*m.d[j] + m.rand_d[k, j] = 1.1 * m.d[j] elif k == 1: - m.rand_d[k,j] = 1.2*m.d[j] + m.rand_d[k, j] = 1.2 * m.d[j] else: - m.rand_d[k,j] = 1.3*m.d[j] + m.rand_d[k, j] = 1.3 * m.d[j] + + model.compute_demands = BuildAction(rule=compute_demands_rule) -def stochd_init(m,k,j,t): + +def stochd_init(m, k, j, t): # What it should be to match description in paper # if t < m.TDEC: # return m.d[j] @@ -145,152 +173,252 @@ def stochd_init(m,k,j,t): # return m.rand_d[k,j] # if t >= m.TDEC+5: # return m.d[j] - if t < m.TDEC+1: + if t < m.TDEC + 1: return m.d[j] - if t >= m.TDEC+1 and t < m.TDEC+1+4.5: - return m.rand_d[k,j] - if t >= m.TDEC+1+4.5: + if t >= m.TDEC + 1 and t < m.TDEC + 1 + 4.5: + return m.rand_d[k, j] + if t >= m.TDEC + 1 + 4.5: return m.d[j] -model.stochd = Param(model.SCEN,model.DEM,model.TIME,within=PositiveReals,mutable=True,default=stochd_init) + +model.stochd = Param( + model.SCEN, + model.DEM, + model.TIME, + within=PositiveReals, + mutable=True, + default=stochd_init, +) # define temporal variables -def p_bounds_rule(m,k,j,t): - return (value(m.pmin[j]),value(m.pmax[j])) -def p_init(m,k,j,t): +def p_bounds_rule(m, k, j, t): + return (value(m.pmin[j]), value(m.pmax[j])) + + +def p_init(m, k, j, t): return (value(m.pmax[j]) + value(m.pmin[j])) / 2 -model.p = Var(model.SCEN, model.NODE, model.TIME, bounds=p_bounds_rule, initialize=p_init) -model.dp = Var(model.SCEN,model.LINK_A,model.TIME,bounds=(0.0,100.0), initialize=10.0) -model.fin = Var(model.SCEN,model.LINK,model.TIME,bounds=(1.0,500.0),initialize=100.0) -model.fout = Var(model.SCEN,model.LINK,model.TIME,bounds=(1.0,500.0),initialize=100.0) - -def s_bounds_rule(m,k,j,t): - return (0.01,value(m.smax[j])) -model.s = Var(model.SCEN,model.SUP,model.TIME,bounds=s_bounds_rule,initialize=10.0) -model.dem = Var(model.SCEN,model.DEM,model.TIME,initialize=100.0) -model.pow = Var(model.SCEN,model.LINK_A,model.TIME,bounds=(0.0,3000.0),initialize=1000.0) -model.slack = Var(model.SCEN,model.LINK,model.TIME,model.DIS,bounds=(0.0,None),initialize=10.0) + + +model.p = Var( + model.SCEN, model.NODE, model.TIME, bounds=p_bounds_rule, initialize=p_init +) +model.dp = Var( + model.SCEN, model.LINK_A, model.TIME, bounds=(0.0, 100.0), initialize=10.0 +) +model.fin = Var( + model.SCEN, model.LINK, model.TIME, bounds=(1.0, 500.0), initialize=100.0 +) +model.fout = Var( + model.SCEN, model.LINK, model.TIME, bounds=(1.0, 500.0), initialize=100.0 +) + + +def s_bounds_rule(m, k, j, t): + return (0.01, value(m.smax[j])) + + +model.s = Var(model.SCEN, model.SUP, model.TIME, bounds=s_bounds_rule, initialize=10.0) +model.dem = Var(model.SCEN, model.DEM, model.TIME, initialize=100.0) +model.pow = Var( + model.SCEN, model.LINK_A, model.TIME, bounds=(0.0, 3000.0), initialize=1000.0 +) +model.slack = Var( + model.SCEN, model.LINK, model.TIME, model.DIS, bounds=(0.0, None), initialize=10.0 +) # define spatio-temporal variables -model.px = Var(model.SCEN,model.LINK,model.TIME,model.DIS,bounds=(10.0,100.0),initialize=50.0) -model.fx = Var(model.SCEN,model.LINK,model.TIME,model.DIS,bounds=(1.0,100.0),initialize=100.0) +model.px = Var( + model.SCEN, model.LINK, model.TIME, model.DIS, bounds=(10.0, 100.0), initialize=50.0 +) +model.fx = Var( + model.SCEN, model.LINK, model.TIME, model.DIS, bounds=(1.0, 100.0), initialize=100.0 +) # define derivatives -model.dpxdt = DerivativeVar(model.px,wrt=model.TIME,initialize=0) -model.dpxdx = DerivativeVar(model.px,wrt=model.DIS,initialize=0) -model.dfxdt = DerivativeVar(model.fx,wrt=model.TIME,initialize=0) -model.dfxdx = DerivativeVar(model.fx,wrt=model.DIS,initialize=0) +model.dpxdt = DerivativeVar(model.px, wrt=model.TIME, initialize=0) +model.dpxdx = DerivativeVar(model.px, wrt=model.DIS, initialize=0) +model.dfxdt = DerivativeVar(model.fx, wrt=model.TIME, initialize=0) +model.dfxdx = DerivativeVar(model.fx, wrt=model.DIS, initialize=0) # ----------- MODEL -------------- # compressor equations -def powereq_rule(m,j,i,t): - return m.pow[j,i,t] == m.c4*m.fin[j,i,t]*(((m.p[j,m.lstartloc[i],t]+m.dp[j,i,t])/m.p[j,m.lstartloc[i],t])**m.om - 1.0) -model.powereq = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=powereq_rule) +def powereq_rule(m, j, i, t): + return m.pow[j, i, t] == m.c4 * m.fin[j, i, t] * ( + ((m.p[j, m.lstartloc[i], t] + m.dp[j, i, t]) / m.p[j, m.lstartloc[i], t]) + ** m.om + - 1.0 + ) + + +model.powereq = Constraint(model.SCEN, model.LINK_A, model.TIME, rule=powereq_rule) # cvar model model.cvar_lambda = Param(within=NonNegativeReals) model.nu = Var(initialize=100.0) -model.phi = Var(model.SCEN,bounds=(0.0,None),initialize=100.0) +model.phi = Var(model.SCEN, bounds=(0.0, None), initialize=100.0) def cvarcost_rule(m): - return (1.0/m.S)*sum((m.phi[k]/(1.0-0.95) + m.nu) for k in m.SCEN) + return (1.0 / m.S) * sum((m.phi[k] / (1.0 - 0.95) + m.nu) for k in m.SCEN) + + model.cvarcost = Expression(rule=cvarcost_rule) # node balances -def nodeeq_rule(m,k,i,t): - return sum(m.fout[k,j,t] for j in m.LINK if m.lendloc[j]==i) + \ - sum(m.s[k,j,t] for j in m.SUP if m.sloc[j]==i) - \ - sum(m.fin[k,j,t] for j in m.LINK if m.lstartloc[j]==i) - \ - sum(m.dem[k,j,t] for j in m.DEM if m.dloc[j]==i) == 0.0 -model.nodeeq = Constraint(model.SCEN,model.NODE,model.TIME,rule=nodeeq_rule) +def nodeeq_rule(m, k, i, t): + return ( + sum(m.fout[k, j, t] for j in m.LINK if m.lendloc[j] == i) + + sum(m.s[k, j, t] for j in m.SUP if m.sloc[j] == i) + - sum(m.fin[k, j, t] for j in m.LINK if m.lstartloc[j] == i) + - sum(m.dem[k, j, t] for j in m.DEM if m.dloc[j] == i) + == 0.0 + ) + + +model.nodeeq = Constraint(model.SCEN, model.NODE, model.TIME, rule=nodeeq_rule) # boundary conditions flow -def flow_start_rule(m,j,i,t): - return m.fx[j,i,t,m.DIS.first()] == m.fin[j,i,t] -model.flow_start = Constraint(model.SCEN,model.LINK,model.TIME,rule=flow_start_rule) +def flow_start_rule(m, j, i, t): + return m.fx[j, i, t, m.DIS.first()] == m.fin[j, i, t] + -def flow_end_rule(m,j,i,t): - return m.fx[j,i,t,m.DIS.last()] == m.fout[j,i,t] -model.flow_end = Constraint(model.SCEN,model.LINK,model.TIME,rule=flow_end_rule) +model.flow_start = Constraint(model.SCEN, model.LINK, model.TIME, rule=flow_start_rule) + + +def flow_end_rule(m, j, i, t): + return m.fx[j, i, t, m.DIS.last()] == m.fout[j, i, t] + + +model.flow_end = Constraint(model.SCEN, model.LINK, model.TIME, rule=flow_end_rule) # First PDE for gas network model -def flow_rule(m,j,i,t,k): +def flow_rule(m, j, i, t, k): if t == m.TIME.first() or k == m.DIS.last(): - return Constraint.Skip # Do not apply pde at initial time or final location - return m.dpxdt[j,i,t,k]/3600 + m.c1[i]/m.llength[i]*m.dfxdx[j,i,t,k] == 0 -model.flow = Constraint(model.SCEN,model.LINK,model.TIME,model.DIS,rule=flow_rule) + return Constraint.Skip # Do not apply pde at initial time or final location + return ( + m.dpxdt[j, i, t, k] / 3600 + m.c1[i] / m.llength[i] * m.dfxdx[j, i, t, k] == 0 + ) + + +model.flow = Constraint(model.SCEN, model.LINK, model.TIME, model.DIS, rule=flow_rule) # Second PDE for gas network model -def press_rule(m,j,i,t,k): +def press_rule(m, j, i, t, k): if t == m.TIME.first() or k == m.DIS.last(): - return Constraint.Skip # Do not apply pde at initial time or final location - return m.dfxdt[j,i,t,k]/3600 == -m.c2[i]/m.llength[i]*m.dpxdx[j,i,t,k] - m.slack[j,i,t,k] -model.press = Constraint(model.SCEN,model.LINK,model.TIME,model.DIS,rule=press_rule) + return Constraint.Skip # Do not apply pde at initial time or final location + return ( + m.dfxdt[j, i, t, k] / 3600 + == -m.c2[i] / m.llength[i] * m.dpxdx[j, i, t, k] - m.slack[j, i, t, k] + ) + + +model.press = Constraint(model.SCEN, model.LINK, model.TIME, model.DIS, rule=press_rule) + -def slackeq_rule(m,j,i,t,k): +def slackeq_rule(m, j, i, t, k): if t == m.TIME.last(): return Constraint.Skip - return m.slack[j,i,t,k]*m.px[j,i,t,k] == m.c3[i]*m.fx[j,i,t,k]*m.fx[j,i,t,k] -model.slackeq = Constraint(model.SCEN,model.LINK,model.TIME,model.DIS,rule=slackeq_rule) + return ( + m.slack[j, i, t, k] * m.px[j, i, t, k] + == m.c3[i] * m.fx[j, i, t, k] * m.fx[j, i, t, k] + ) + + +model.slackeq = Constraint( + model.SCEN, model.LINK, model.TIME, model.DIS, rule=slackeq_rule +) # boundary conditions pressure, passive links -def presspas_start_rule(m,j,i,t): - return m.px[j,i,t,m.DIS.first()] == m.p[j,m.lstartloc[i],t] -model.presspas_start = Constraint(model.SCEN,model.LINK_P,model.TIME,rule=presspas_start_rule) +def presspas_start_rule(m, j, i, t): + return m.px[j, i, t, m.DIS.first()] == m.p[j, m.lstartloc[i], t] + + +model.presspas_start = Constraint( + model.SCEN, model.LINK_P, model.TIME, rule=presspas_start_rule +) -def presspas_end_rule(m,j,i,t): - return m.px[j,i,t,m.DIS.last()] == m.p[j,m.lendloc[i],t] -model.presspas_end = Constraint(model.SCEN,model.LINK_P,model.TIME,rule=presspas_end_rule) + +def presspas_end_rule(m, j, i, t): + return m.px[j, i, t, m.DIS.last()] == m.p[j, m.lendloc[i], t] + + +model.presspas_end = Constraint( + model.SCEN, model.LINK_P, model.TIME, rule=presspas_end_rule +) # boundary conditions pressure, active links -def pressact_start_rule(m,j,i,t): - return m.px[j,i,t,m.DIS.first()] == m.p[j,m.lstartloc[i],t]+m.dp[j,i,t] -model.pressact_start = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=pressact_start_rule) +def pressact_start_rule(m, j, i, t): + return m.px[j, i, t, m.DIS.first()] == m.p[j, m.lstartloc[i], t] + m.dp[j, i, t] + -def pressact_end_rule(m,j,i,t): - return m.px[j,i,t,m.DIS.last()] == m.p[j,m.lendloc[i],t] -model.pressact_end = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=pressact_end_rule) +model.pressact_start = Constraint( + model.SCEN, model.LINK_A, model.TIME, rule=pressact_start_rule +) + + +def pressact_end_rule(m, j, i, t): + return m.px[j, i, t, m.DIS.last()] == m.p[j, m.lendloc[i], t] + + +model.pressact_end = Constraint( + model.SCEN, model.LINK_A, model.TIME, rule=pressact_end_rule +) # fix pressure at supply nodes -def suppres_rule(m,k,j,t): - return m.p[k,m.sloc[j],t] == m.pmin[m.sloc[j]] -model.suppres = Constraint(model.SCEN,model.SUP,model.TIME,rule=suppres_rule) +def suppres_rule(m, k, j, t): + return m.p[k, m.sloc[j], t] == m.pmin[m.sloc[j]] + + +model.suppres = Constraint(model.SCEN, model.SUP, model.TIME, rule=suppres_rule) # discharge pressure for compressors -def dispress_rule(m,j,i,t): - return m.p[j,m.lstartloc[i],t]+m.dp[j,i,t] <= m.pmax[m.lstartloc[i]] -model.dispress = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=dispress_rule) +def dispress_rule(m, j, i, t): + return m.p[j, m.lstartloc[i], t] + m.dp[j, i, t] <= m.pmax[m.lstartloc[i]] + + +model.dispress = Constraint(model.SCEN, model.LINK_A, model.TIME, rule=dispress_rule) # ss constraints -def flow_ss_rule(m,j,i,k): +def flow_ss_rule(m, j, i, k): if k == m.DIS.last(): return Constraint.Skip - return m.dfxdx[j,i,m.TIME.first(),k]/m.llength[i] == 0.0 -model.flow_ss = Constraint(model.SCEN,model.LINK,model.DIS,rule=flow_ss_rule) + return m.dfxdx[j, i, m.TIME.first(), k] / m.llength[i] == 0.0 -def pres_ss_rule(m,j,i,k): + +model.flow_ss = Constraint(model.SCEN, model.LINK, model.DIS, rule=flow_ss_rule) + + +def pres_ss_rule(m, j, i, k): if k == m.DIS.last(): return Constraint.Skip - return 0.0 == - m.c2[i]/m.llength[i]*m.dpxdx[j,i,m.TIME.first(),k] - m.slack[j,i,m.TIME.first(),k]; -model.pres_ss = Constraint(model.SCEN,model.LINK,model.DIS,rule=pres_ss_rule) + return ( + 0.0 + == -m.c2[i] / m.llength[i] * m.dpxdx[j, i, m.TIME.first(), k] + - m.slack[j, i, m.TIME.first(), k] + ) + + +model.pres_ss = Constraint(model.SCEN, model.LINK, model.DIS, rule=pres_ss_rule) # non-anticipativity constraints -def nonantdq_rule(m,j,i,t): +def nonantdq_rule(m, j, i, t): if j == 1: return Constraint.Skip - if t >= m.TDEC+1: + if t >= m.TDEC + 1: return Constraint.Skip - return m.dp[j,i,t] == m.dp[1,i,t] + return m.dp[j, i, t] == m.dp[1, i, t] + -model.nonantdq = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=nonantdq_rule) +model.nonantdq = Constraint(model.SCEN, model.LINK_A, model.TIME, rule=nonantdq_rule) -def nonantde_rule(m,j,i,t): + +def nonantde_rule(m, j, i, t): if j == 1: return Constraint.Skip - if t >= m.TDEC+1: + if t >= m.TDEC + 1: return Constraint.Skip - return m.dem[j,i,t] == m.dem[1,i,t] + return m.dem[j, i, t] == m.dem[1, i, t] + -model.nonantde = Constraint(model.SCEN,model.DEM,model.TIME,rule=nonantde_rule) +model.nonantde = Constraint(model.SCEN, model.DEM, model.TIME, rule=nonantde_rule) diff --git a/examples/doc/samples/case_studies/deer/DeerProblem.py b/examples/doc/samples/case_studies/deer/DeerProblem.py index b94e92d5b2d..0b6b7252aaa 100644 --- a/examples/doc/samples/case_studies/deer/DeerProblem.py +++ b/examples/doc/samples/case_studies/deer/DeerProblem.py @@ -6,24 +6,24 @@ model = AbstractModel() -model.p1 = Param(); -model.p2 = Param(); -model.p3 = Param(); -model.p4 = Param(); -model.p5 = Param(); -model.p6 = Param(); -model.p7 = Param(); -model.p8 = Param(); -model.p9 = Param(); -model.ps = Param(); - -model.f = Var(initialize = 20, within=PositiveReals) -model.d = Var(initialize = 20, within=PositiveReals) -model.b = Var(initialize = 20, within=PositiveReals) - -model.hf = Var(initialize = 20, within=PositiveReals) -model.hd = Var(initialize = 20, within=PositiveReals) -model.hb = Var(initialize = 20, within=PositiveReals) +model.p1 = Param() +model.p2 = Param() +model.p3 = Param() +model.p4 = Param() +model.p5 = Param() +model.p6 = Param() +model.p7 = Param() +model.p8 = Param() +model.p9 = Param() +model.ps = Param() + +model.f = Var(initialize=20, within=PositiveReals) +model.d = Var(initialize=20, within=PositiveReals) +model.b = Var(initialize=20, within=PositiveReals) + +model.hf = Var(initialize=20, within=PositiveReals) +model.hd = Var(initialize=20, within=PositiveReals) +model.hb = Var(initialize=20, within=PositiveReals) model.br = Var(initialize=1.5, within=PositiveReals) @@ -31,33 +31,62 @@ def obj_rule(amodel): - return 10*amodel.hb + amodel.hd + amodel.hf + return 10 * amodel.hb + amodel.hd + amodel.hf + + model.obj = Objective(rule=obj_rule, sense=maximize) + def f_bal_rule(amodel): - return amodel.f == amodel.p1*amodel.br*(amodel.p2/10.0*amodel.f + amodel.p3*amodel.d)-amodel.hf + return ( + amodel.f + == amodel.p1 * amodel.br * (amodel.p2 / 10.0 * amodel.f + amodel.p3 * amodel.d) + - amodel.hf + ) + + model.f_bal = Constraint(rule=f_bal_rule) + def d_bal_rule(amodel): - return amodel.d == amodel.p4*amodel.d + amodel.p5/2.0*amodel.f - amodel.hd + return amodel.d == amodel.p4 * amodel.d + amodel.p5 / 2.0 * amodel.f - amodel.hd + + model.d_bal = Constraint(rule=d_bal_rule) + def b_bal_rule(amodel): - return amodel.b == amodel.p6*amodel.b + amodel.p5/2.0*amodel.f - amodel.hb + return amodel.b == amodel.p6 * amodel.b + amodel.p5 / 2.0 * amodel.f - amodel.hb + + model.b_bal = Constraint(rule=b_bal_rule) + def food_cons_rule(amodel): - return amodel.c == amodel.p7*amodel.b + amodel.p8*amodel.d + amodel.p9*amodel.f + return ( + amodel.c == amodel.p7 * amodel.b + amodel.p8 * amodel.d + amodel.p9 * amodel.f + ) + + model.food_cons = Constraint(rule=food_cons_rule) + def supply_rule(amodel): return amodel.c <= amodel.ps + + model.supply = Constraint(rule=supply_rule) + def birth_rule(amodel): - return amodel.br == 1.1 + 0.8*(amodel.ps - amodel.c)/amodel.ps + return amodel.br == 1.1 + 0.8 * (amodel.ps - amodel.c) / amodel.ps + + model.birth = Constraint(rule=birth_rule) + def proc_rule(amodel): - return amodel.b >= 1.0/5.0*(0.4*amodel.f + amodel.d) + return amodel.b >= 1.0 / 5.0 * (0.4 * amodel.f + amodel.d) + + model.proc = Constraint(rule=proc_rule) diff --git a/examples/doc/samples/case_studies/diet/DietProblem.py b/examples/doc/samples/case_studies/diet/DietProblem.py index f72a574f2b8..f070201c28e 100644 --- a/examples/doc/samples/case_studies/diet/DietProblem.py +++ b/examples/doc/samples/case_studies/diet/DietProblem.py @@ -5,25 +5,33 @@ model.foods = Set() model.nutrients = Set() model.costs = Param(model.foods) -model.min_nutrient=Param(model.nutrients) -model.max_nutrient=Param(model.nutrients) -model.volumes=Param(model.foods) -model.max_volume=Param() -model.nutrient_value=Param(model.nutrients, model.foods) -model.amount=Var(model.foods, within = NonNegativeReals) +model.min_nutrient = Param(model.nutrients) +model.max_nutrient = Param(model.nutrients) +model.volumes = Param(model.foods) +model.max_volume = Param() +model.nutrient_value = Param(model.nutrients, model.foods) +model.amount = Var(model.foods, within=NonNegativeReals) + def costRule(model): - return sum(model.costs[n]*model.amount[n] for n in model.foods) + return sum(model.costs[n] * model.amount[n] for n in model.foods) + + +model.cost = Objective(rule=costRule) -model.cost=Objective(rule=costRule) def volumeRule(model): - return sum(model.volumes[n]*model.amount[n] for n in model.foods) <= model.max_volume + return ( + sum(model.volumes[n] * model.amount[n] for n in model.foods) <= model.max_volume + ) + model.volume = Constraint(rule=volumeRule) + def nutrientRule(model, n): - value = sum(model.nutrient_value[n,f]*model.amount[f] for f in model.foods) + value = sum(model.nutrient_value[n, f] * model.amount[f] for f in model.foods) return (model.min_nutrient[n], value, model.max_nutrient[n]) + model.nutrientConstraint = Constraint(model.nutrients, rule=nutrientRule) diff --git a/examples/doc/samples/case_studies/disease_est/DiseaseEstimation.py b/examples/doc/samples/case_studies/disease_est/DiseaseEstimation.py index b9aa480c8a6..c685a6ee67f 100644 --- a/examples/doc/samples/case_studies/disease_est/DiseaseEstimation.py +++ b/examples/doc/samples/case_studies/disease_est/DiseaseEstimation.py @@ -7,26 +7,42 @@ model.P_REP_CASES = Param(model.S_SI) model.P_POP = Param() -model.I = Var(model.S_SI, bounds=(0,model.P_POP), initialize=1) -model.S = Var(model.S_SI, bounds=(0,model.P_POP), initialize=300) +model.I = Var(model.S_SI, bounds=(0, model.P_POP), initialize=1) +model.S = Var(model.S_SI, bounds=(0, model.P_POP), initialize=300) model.beta = Var(bounds=(0.05, 70)) model.alpha = Var(bounds=(0.5, 1.5)) model.eps_I = Var(model.S_SI, initialize=0.0) + def _objective(model): - return sum((model.eps_I[i])**2 for i in model.S_SI) + return sum((model.eps_I[i]) ** 2 for i in model.S_SI) + + model.objective = Objective(rule=_objective, sense=minimize) + def _InfDynamics(model, i): if i != 1: - return model.I[i] == (model.beta*model.S[i-1]*model.I[i-1]**model.alpha)/model.P_POP + return ( + model.I[i] + == (model.beta * model.S[i - 1] * model.I[i - 1] ** model.alpha) + / model.P_POP + ) + + model.InfDynamics = Constraint(model.S_SI, rule=_InfDynamics) + def _SusDynamics(model, i): if i != 1: - return model.S[i] == model.S[i-1] - model.I[i] + return model.S[i] == model.S[i - 1] - model.I[i] + + model.SusDynamics = Constraint(model.S_SI, rule=_SusDynamics) + def _Data(model, i): - return model.P_REP_CASES[i] == model.I[i]+model.eps_I[i] + return model.P_REP_CASES[i] == model.I[i] + model.eps_I[i] + + model.Data = Constraint(model.S_SI, rule=_Data) diff --git a/examples/doc/samples/case_studies/max_flow/MaxFlow.py b/examples/doc/samples/case_studies/max_flow/MaxFlow.py index c8e25dd968e..c6eb42ccf7d 100644 --- a/examples/doc/samples/case_studies/max_flow/MaxFlow.py +++ b/examples/doc/samples/case_studies/max_flow/MaxFlow.py @@ -3,7 +3,7 @@ model = AbstractModel() model.nodes = Set() -model.arcs = Set(within=model.nodes*model.nodes) +model.arcs = Set(within=model.nodes * model.nodes) model.sources = Set(within=model.nodes) model.sinks = Set(within=model.nodes) model.upperBound = Param(model.arcs) @@ -11,52 +11,38 @@ model.demand = Param(model.sinks) model.amount = Var(model.arcs, within=NonNegativeReals) + def totalRule(model): - expression = sum( - model.amount[i,j] - for (i, j) in model.arcs - if j in model.sinks - ) + expression = sum(model.amount[i, j] for (i, j) in model.arcs if j in model.sinks) return expression + model.maxFlow = Objective(rule=totalRule, sense=maximize) + def maxRule(model, arcIn, arcOut): - constraint_equation = (model.amount[arcIn, arcOut] <= model.upperBound[arcIn, arcOut]) + constraint_equation = model.amount[arcIn, arcOut] <= model.upperBound[arcIn, arcOut] return constraint_equation + model.loadOnArc = Constraint(model.arcs, rule=maxRule) + def flowRule(model, node): if node in model.sources: - flow_out = sum( - model.amount[i,j] - for (i,j) in model.arcs - if i == node - ) - constraint_equation = ( flow_out <= model.supply[node] ) + flow_out = sum(model.amount[i, j] for (i, j) in model.arcs if i == node) + constraint_equation = flow_out <= model.supply[node] elif node in model.sinks: - flow_in = sum( - model.amount[i,j] - for (i,j) in model.arcs - if j == node - ) - constraint_equation = (flow_in >= model.demand[node]) + flow_in = sum(model.amount[i, j] for (i, j) in model.arcs if j == node) + constraint_equation = flow_in >= model.demand[node] else: - amountIn = sum( - model.amount[i,j] - for (i,j) in model.arcs - if j == node - ) - amountOut = sum( - model.amount[i,j] - for (i,j) in model.arcs - if i == node - ) - constraint_equation = ( amountIn == amountOut ) + amountIn = sum(model.amount[i, j] for (i, j) in model.arcs if j == node) + amountOut = sum(model.amount[i, j] for (i, j) in model.arcs if i == node) + constraint_equation = amountIn == amountOut return constraint_equation + model.flow = Constraint(model.nodes, rule=flowRule) diff --git a/examples/doc/samples/case_studies/network_flow/networkFlow1.py b/examples/doc/samples/case_studies/network_flow/networkFlow1.py index 00c5c35b37d..d705db01ac8 100644 --- a/examples/doc/samples/case_studies/network_flow/networkFlow1.py +++ b/examples/doc/samples/case_studies/network_flow/networkFlow1.py @@ -3,7 +3,7 @@ model = AbstractModel() model.places = Set() -model.routes = Set(within=model.places*model.places) +model.routes = Set(within=model.places * model.places) model.supply = Param(model.places) model.demand = Param(model.places) model.cost = Param(model.routes) @@ -12,24 +12,30 @@ model.amount = Var(model.routes, within=NonNegativeReals) model.excess = Var(model.places, within=NonNegativeReals) + def costRule(model): - return sum(model.cost[n]*model.amount[n] for n in model.routes) + return sum(model.cost[n] * model.amount[n] for n in model.routes) + model.costTotal = Objective(rule=costRule) + def loadRule(model, i, j): - return (model.minimum[i,j], model.amount[i,j], model.maximum[i,j]) + return (model.minimum[i, j], model.amount[i, j], model.maximum[i, j]) + model.loadOnRoad = Constraint(model.routes, rule=loadRule) + def supplyDemandRule(model, nn): - amountIn = sum(model.amount[i,j] for (i,j) in model.routes if j == nn) - amountOut = sum(model.amount[i,j] for (i,j) in model.routes if i == nn) + amountIn = sum(model.amount[i, j] for (i, j) in model.routes if j == nn) + amountOut = sum(model.amount[i, j] for (i, j) in model.routes if i == nn) - input = amountIn + model.supply[nn] + input = amountIn + model.supply[nn] output = amountOut + model.demand[nn] + model.excess[nn] return input == output + model.supplyDemand = Constraint(model.places, rule=supplyDemandRule) diff --git a/examples/doc/samples/case_studies/rosen/Rosenbrock.py b/examples/doc/samples/case_studies/rosen/Rosenbrock.py index 02b9136b992..ceed90c8760 100644 --- a/examples/doc/samples/case_studies/rosen/Rosenbrock.py +++ b/examples/doc/samples/case_studies/rosen/Rosenbrock.py @@ -4,12 +4,13 @@ model = AbstractModel() # @:intro # @vars: -model.x = Var(initialize = 1.5) -model.y = Var(initialize = 1.5) +model.x = Var(initialize=1.5) +model.y = Var(initialize=1.5) # @:vars # @obj: def rosenbrock(amodel): - return (1.0-amodel.x)**2 \ - + 100.0*(amodel.y - amodel.x**2)**2 + return (1.0 - amodel.x) ** 2 + 100.0 * (amodel.y - amodel.x**2) ** 2 + + model.obj = Objective(rule=rosenbrock, sense=minimize) # @:obj diff --git a/examples/doc/samples/case_studies/transportation/transportation.py b/examples/doc/samples/case_studies/transportation/transportation.py index 5630aa086b8..26fcb5f0b66 100644 --- a/examples/doc/samples/case_studies/transportation/transportation.py +++ b/examples/doc/samples/case_studies/transportation/transportation.py @@ -7,23 +7,32 @@ model.supply = Param(model.warehouses) model.demand = Param(model.stores) model.costs = Param(model.warehouses, model.stores) -model.amounts = Var(model.warehouses, model.stores, within = NonNegativeReals) +model.amounts = Var(model.warehouses, model.stores, within=NonNegativeReals) + def costRule(model): return sum( - model.costs[n,i] * model.amounts[n,i] + model.costs[n, i] * model.amounts[n, i] for n in model.warehouses for i in model.stores ) -model.cost=Objective(rule=costRule) + +model.cost = Objective(rule=costRule) + def minDemandRule(model, store): return sum(model.amounts[i, store] for i in model.warehouses) >= model.demand[store] + model.demandConstraint = Constraint(model.stores, rule=minDemandRule) + def maxSupplyRule(model, warehouse): - return sum(model.amounts[warehouse, j] for j in model.stores) <= model.supply[warehouse] + return ( + sum(model.amounts[warehouse, j] for j in model.stores) + <= model.supply[warehouse] + ) + model.supplyConstraint = Constraint(model.warehouses, rule=maxSupplyRule) diff --git a/examples/doc/samples/comparisons/cutstock/cutstock_util.py b/examples/doc/samples/comparisons/cutstock/cutstock_util.py index 46c6c63f92a..1cd8c61922f 100644 --- a/examples/doc/samples/comparisons/cutstock/cutstock_util.py +++ b/examples/doc/samples/comparisons/cutstock/cutstock_util.py @@ -5,7 +5,8 @@ def getCutCount(): cutCount += 1 fout1.close() return cutCount - + + def getPatCount(): patCount = 0 fout2 = open('Waste.csv', 'r') @@ -14,28 +15,33 @@ def getPatCount(): fout2.close() return patCount + def getPriceSheetData(): return 28 - + + def getSheetsAvail(): return 2000 - + + def getCuts(): cutcount = getCutCount() Cuts = range(cutcount) for i in range(cutcount): - nstr = str(i+1) + nstr = str(i + 1) Cuts[i] = 'w' + nstr return Cuts + def getPatterns(): patcount = getPatCount() Patterns = range(patcount) for j in range(patcount): - pstr = str(j+1) + pstr = str(j + 1) Patterns[j] = 'P' + pstr - return Patterns - + return Patterns + + def getCutDemand(): i = 0 cutcount = getCutCount() @@ -48,6 +54,7 @@ def getCutDemand(): fout1.close() return CutDemand + def getCutsInPattern(): cutcount = getCutCount() patcount = getPatCount() @@ -59,12 +66,12 @@ def getCutsInPattern(): pstr = lstr[0] wstr = lstr[1] cstr = lstr[2] - pstr = pstr.replace("P","") - wstr = wstr.replace("w","") + pstr = pstr.replace("P", "") + wstr = wstr.replace("w", "") cstr = cstr.rstrip("\n") p = int(pstr) w = int(wstr) c = int(cstr) - CutsInPattern[w-1][p-1] = c + CutsInPattern[w - 1][p - 1] = c fout2.close() return CutsInPattern diff --git a/examples/doc/samples/comparisons/sched/pyomo/sched.py b/examples/doc/samples/comparisons/sched/pyomo/sched.py index 7d1a077ac62..627bc083fbe 100644 --- a/examples/doc/samples/comparisons/sched/pyomo/sched.py +++ b/examples/doc/samples/comparisons/sched/pyomo/sched.py @@ -11,42 +11,71 @@ model.ntasks = Param(model.TASKS, within=NonNegativeReals) model.minp = Param(model.TASKS, within=NonNegativeReals) + def maxp_valid(value, i, Model): return Model.maxp[i] >= Model.minp[i] + + model.maxp = Param(model.TASKS, validate=maxp_valid) model.x = Var(model.TASKS, model.PEOPLE, model.SLOTS, within=Binary) model.xts = Var(model.TASKS, model.SLOTS, within=Binary) model.xtp = Var(model.TASKS, model.PEOPLE, within=Binary) + def rule1_rule(t, s, Model): - return sum(Model.x[t,p,s] for p in Model.PEOPLE) >= Model.xts[t,s] + return sum(Model.x[t, p, s] for p in Model.PEOPLE) >= Model.xts[t, s] + + model.rule1 = Constraint(model.TASKS, model.SLOTS) + def rule2_rule(t, p, s, Model): - return Model.x[t,p,s] <= Model.xts[t,s] + return Model.x[t, p, s] <= Model.xts[t, s] + + model.rule2 = Constraint(model.TASKS, model.PEOPLE, model.SLOTS) + def rule3_rule(t, p, Model): - return sum(Model.x[t,p,s] for s in Model.SLOTS) == Model.xtp[t,p] + return sum(Model.x[t, p, s] for s in Model.SLOTS) == Model.xtp[t, p] + + model.rule3 = Constraint(model.TASKS, model.PEOPLE) + def rule4_rule(t, Model): - return sum(Model.xts[t,s] for s in Model.SLOTS) == Model.ntasks[t] + return sum(Model.xts[t, s] for s in Model.SLOTS) == Model.ntasks[t] + + model.rule4 = Constraint(model.TASKS) + def rule5_rule(t, Model): - return Model.minp[t] <= sum(Model.xtp[t,p] for p in Model.PEOPLE) <= Model.maxp[t] + return Model.minp[t] <= sum(Model.xtp[t, p] for p in Model.PEOPLE) <= Model.maxp[t] + + model.rule5 = Constraint(model.TASKS) + def rule6_rule(s, Model): - return sum(Model.xts[t,s] for t in Model.TASKS) <= Model.nrooms[s] + return sum(Model.xts[t, s] for t in Model.TASKS) <= Model.nrooms[s] + + model.rule6 = Constraint(model.SLOTS) + def rule7_rule(p, s, Model): - return sum(Model.x[t,p,s] for t in Model.TASKS) == 1 + return sum(Model.x[t, p, s] for t in Model.TASKS) == 1 + + model.rule7 = Constraint(model.PEOPLE, model.SLOTS) + def z_rule(Model): - return sum(Model.amt[t,p] * Model.xtp[t,p] for t in Model.TASKS for p in Model.PEOPLE) + return sum( + Model.amt[t, p] * Model.xtp[t, p] for t in Model.TASKS for p in Model.PEOPLE + ) + + model.z = Objective(sense=maximize) diff --git a/examples/doc/samples/scripts/s1/knapsack.py b/examples/doc/samples/scripts/s1/knapsack.py index b6066f8b5ce..642e0faaaed 100644 --- a/examples/doc/samples/scripts/s1/knapsack.py +++ b/examples/doc/samples/scripts/s1/knapsack.py @@ -13,10 +13,16 @@ model.x = Var(model.ITEMS, within=Binary) + def value_rule(model): - return sum(model.v[i]*model.x[i] for i in model.ITEMS) + return sum(model.v[i] * model.x[i] for i in model.ITEMS) + + model.value = Objective(sense=maximize, rule=value_rule) + def weight_rule(model): - return sum(model.w[i]*model.x[i] for i in model.ITEMS) <= model.limit + return sum(model.w[i] * model.x[i] for i in model.ITEMS) <= model.limit + + model.weight = Constraint(rule=weight_rule) diff --git a/examples/doc/samples/scripts/s1/script.py b/examples/doc/samples/scripts/s1/script.py index 137669c2062..02b6b406922 100644 --- a/examples/doc/samples/scripts/s1/script.py +++ b/examples/doc/samples/scripts/s1/script.py @@ -1,9 +1,11 @@ from pyomo.core import * import pyomo.opt import pyomo.environ + # # Import model import knapsack + # # Create the model instance instance = knapsack.model.create_instance("knapsack.dat") @@ -12,7 +14,7 @@ opt = pyomo.opt.SolverFactory("glpk") # # Optimize -results = opt.solve(instance,symbolic_solver_labels=True) +results = opt.solve(instance, symbolic_solver_labels=True) instance.solutions.store_to(results) # # Write the output diff --git a/examples/doc/samples/scripts/s2/knapsack.py b/examples/doc/samples/scripts/s2/knapsack.py index 268b12aa331..ff583ae7160 100644 --- a/examples/doc/samples/scripts/s2/knapsack.py +++ b/examples/doc/samples/scripts/s2/knapsack.py @@ -13,16 +13,24 @@ model.x = Var(model.ITEMS, within=PercentFraction) + def value_rule(model): - return sum(model.v[i]*model.x[i] for i in model.ITEMS) + return sum(model.v[i] * model.x[i] for i in model.ITEMS) + + model.value = Objective(sense=maximize, rule=value_rule) + def weight_rule(model): - return sum(model.w[i]*model.x[i] for i in model.ITEMS) <= model.limit + return sum(model.w[i] * model.x[i] for i in model.ITEMS) <= model.limit + + model.weight = Constraint(rule=weight_rule) # This constraint is not active, to illustrate how zero dual values are # handled by the pyomo command. def W_rule(model): - return sum(model.w[i]*model.x[i] for i in model.ITEMS) <= 2*model.limit + return sum(model.w[i] * model.x[i] for i in model.ITEMS) <= 2 * model.limit + + model.W = Constraint(rule=W_rule) diff --git a/examples/doc/samples/scripts/s2/script.py b/examples/doc/samples/scripts/s2/script.py index c60743ef5b9..88de1dec680 100644 --- a/examples/doc/samples/scripts/s2/script.py +++ b/examples/doc/samples/scripts/s2/script.py @@ -1,9 +1,11 @@ from pyomo.core import * import pyomo.opt import pyomo.environ + # # Import model import knapsack + # # Create the model instance instance = knapsack.model.create_instance("knapsack.dat") @@ -21,19 +23,19 @@ # Print the results i = 0 for sol in results.solution: - print("Solution "+str(i)) + print("Solution " + str(i)) # print(sorted(sol.variable.keys())) for var in sorted(sol.variable.keys()): - print(" Variable "+str(var)) - print(" "+str(sol.variable[var]['Value'])) - #for key in sorted(sol.variable[var].keys()): - #print(' '+str(key)+' '+str(sol.variable[var][key])) + print(" Variable " + str(var)) + print(" " + str(sol.variable[var]['Value'])) + # for key in sorted(sol.variable[var].keys()): + # print(' '+str(key)+' '+str(sol.variable[var][key])) # for con in sorted(sol.constraint.keys()): - print(" Constraint "+str(con)) + print(" Constraint " + str(con)) for key in sorted(sol.constraint[con].keys()): - print(' '+str(key)+' '+str(sol.constraint[con][key])) + print(' ' + str(key) + ' ' + str(sol.constraint[con][key])) # i += 1 # @@ -41,4 +43,4 @@ print("") print("Dual Values") for con in sorted(results.solution(0).constraint.keys()): - print(str(con)+' '+str(results.solution(0).constraint[con]["Dual"])) + print(str(con) + ' ' + str(results.solution(0).constraint[con]["Dual"])) diff --git a/examples/doc/samples/scripts/test_scripts.py b/examples/doc/samples/scripts/test_scripts.py index ee2e0d23f0a..ca0c8a7cc4e 100644 --- a/examples/doc/samples/scripts/test_scripts.py +++ b/examples/doc/samples/scripts/test_scripts.py @@ -14,23 +14,25 @@ import sys import subprocess from os.path import abspath, dirname -currdir = dirname(abspath(__file__))+os.sep + +currdir = dirname(abspath(__file__)) + os.sep import pyomo.core import pyomo.common.unittest as unittest try: import yaml - yaml_available=True + + yaml_available = True except ImportError: - yaml_available=False + yaml_available = False @unittest.skipIf(not yaml_available, "PyYaml is not installed") -@unittest.skipIf(not pyomo.common.Executable("glpsol"), - "The 'glpsol' executable is not available") +@unittest.skipIf( + not pyomo.common.Executable("glpsol"), "The 'glpsol' executable is not available" +) class Test(unittest.TestCase): - def setUp(self): self.cwd = currdir os.chdir(self.cwd) @@ -39,23 +41,24 @@ def tearDown(self): os.chdir(self.cwd) def run_script(self, test, yaml_available=False): - cwd = self.cwd+os.sep+test+os.sep + cwd = self.cwd + os.sep + test + os.sep os.chdir(cwd) - with open(cwd+os.sep+'script.log', 'w') as f: - subprocess.run([sys.executable, 'script.py'], - stdout=f, stderr=f, cwd=cwd) + with open(cwd + os.sep + 'script.log', 'w') as f: + subprocess.run([sys.executable, 'script.py'], stdout=f, stderr=f, cwd=cwd) if yaml_available: - with open(cwd+'script.log', 'r') as f1: - with open(cwd+'script.out', 'r') as f2: + with open(cwd + 'script.log', 'r') as f1: + with open(cwd + 'script.out', 'r') as f2: baseline = yaml.full_load(f1) output = yaml.full_load(f2) - self.assertStructuredAlmostEqual(output, baseline, - allow_second_superset=True) + self.assertStructuredAlmostEqual( + output, baseline, allow_second_superset=True + ) else: _log = os.path.join(cwd, 'script.log') _out = os.path.join(cwd, 'script.out') - self.assertTrue(cmp(_log, _out), - msg="Files %s and %s differ" % (_log, _out)) + self.assertTrue( + cmp(_log, _out), msg="Files %s and %s differ" % (_log, _out) + ) def test_s1(self): self.run_script('s1', True) diff --git a/examples/doc/samples/update.py b/examples/doc/samples/update.py index 1f824a4421d..9eae2f4b694 100644 --- a/examples/doc/samples/update.py +++ b/examples/doc/samples/update.py @@ -7,13 +7,14 @@ import glob import os.path + def get_title(fname): INPUT = open(fname, 'r') for line in INPUT: sline = line.strip() - #print sline - #print sline[0:2] - #print '.%s.' % sline[-2:] + # print sline + # print sline[0:2] + # print '.%s.' % sline[-2:] if sline[0:2] == '= ' and sline[-2:] == ' =': tmp = sline[2:-2] tmp.strip() @@ -22,7 +23,7 @@ def get_title(fname): OUTPUT = open('TRAC.txt', 'w') -print >>OUTPUT, """{{{ +print >> OUTPUT, """{{{ #!comment ; ; Trac examples generated automatically by the update.py script @@ -36,41 +37,50 @@ def get_title(fname): """ -print >>OUTPUT, '== Case Studies ==' -print >>OUTPUT, '' -print >>OUTPUT, """The following links provide case studies that illustrate the use of Pyomo to formulate and analyze optimization models.""" -print >>OUTPUT, '' +print >> OUTPUT, '== Case Studies ==' +print >> OUTPUT, '' +print >> OUTPUT, """The following links provide case studies that illustrate the use of Pyomo to formulate and analyze optimization models.""" +print >> OUTPUT, '' for Dir in glob.glob('case_studies/*'): dir = os.path.basename(Dir) fname = 'case_studies/%s/README.txt' % dir if os.path.exists(fname): - print >>OUTPUT, " * [wiki:Documentation/PyomoGallery/CaseStudies/%s %s]" % (dir, get_title(fname)) - print >>OUTPUT, "{{{\n#!comment\n[[Include(source:pyomo.data.samples/trunk/pyomo/data/samples/case_studies/%s/README.txt, text/x-trac-wiki)]]\n}}}" % dir + print >> OUTPUT, " * [wiki:Documentation/PyomoGallery/CaseStudies/%s %s]" % ( + dir, + get_title(fname), + ) + print >> OUTPUT, "{{{\n#!comment\n[[Include(source:pyomo.data.samples/trunk/pyomo/data/samples/case_studies/%s/README.txt, text/x-trac-wiki)]]\n}}}" % dir -print >>OUTPUT, '' -print >>OUTPUT, '== Pyomo Scripts ==' -print >>OUTPUT, '' -print >>OUTPUT, """The following links describe examples that show how to execute Pyomo functionality with Python scripts.""" -print >>OUTPUT, '' +print >> OUTPUT, '' +print >> OUTPUT, '== Pyomo Scripts ==' +print >> OUTPUT, '' +print >> OUTPUT, """The following links describe examples that show how to execute Pyomo functionality with Python scripts.""" +print >> OUTPUT, '' for Dir in glob.glob('scripts/*'): dir = os.path.basename(Dir) fname = 'scripts/%s/README.txt' % dir if os.path.exists(fname): - print >>OUTPUT, " * [wiki:Documentation/PyomoGallery/Scripts/%s %s]" % (dir, get_title(fname)) - print >>OUTPUT, "{{{\n#!comment\n[[Include(source:pyomo.data.samples/trunk/pyomo/data/samples/scripts/%s/README.txt, text/x-trac-wiki)]]\n}}}" % dir + print >> OUTPUT, " * [wiki:Documentation/PyomoGallery/Scripts/%s %s]" % ( + dir, + get_title(fname), + ) + print >> OUTPUT, "{{{\n#!comment\n[[Include(source:pyomo.data.samples/trunk/pyomo/data/samples/scripts/%s/README.txt, text/x-trac-wiki)]]\n}}}" % dir -print >>OUTPUT, '' -print >>OUTPUT, '== Modeling Comparisons ==' -print >>OUTPUT, '' -print >>OUTPUT, """The following links provide documentation of optimization models that can be used to compare and contrast Pyomo with other optimization modeling tools. Note that the list of [wiki:Documentation/RelatedProjects related projects] summarizes Python software frameworks that provide optimization functionality that is similar to Pyomo.""" -print >>OUTPUT, '' +print >> OUTPUT, '' +print >> OUTPUT, '== Modeling Comparisons ==' +print >> OUTPUT, '' +print >> OUTPUT, """The following links provide documentation of optimization models that can be used to compare and contrast Pyomo with other optimization modeling tools. Note that the list of [wiki:Documentation/RelatedProjects related projects] summarizes Python software frameworks that provide optimization functionality that is similar to Pyomo.""" +print >> OUTPUT, '' for Dir in glob.glob('comparisons/*'): dir = os.path.basename(Dir) fname = 'comparisons/%s/README.txt' % dir if os.path.exists(fname): - print >>OUTPUT, " * [wiki:Documentation/PyomoGallery/ModelingComparisons/%s %s]" % (dir, get_title(fname)) - print >>OUTPUT, "{{{\n#!comment\n[[Include(source:pyomo.data.samples/trunk/pyomo/data/samples/comparisons/%s/README.txt, text/x-trac-wiki)]]\n}}}" % dir + print >> OUTPUT, " * [wiki:Documentation/PyomoGallery/ModelingComparisons/%s %s]" % ( + dir, + get_title(fname), + ) + print >> OUTPUT, "{{{\n#!comment\n[[Include(source:pyomo.data.samples/trunk/pyomo/data/samples/comparisons/%s/README.txt, text/x-trac-wiki)]]\n}}}" % dir diff --git a/examples/gdp/batchProcessing.py b/examples/gdp/batchProcessing.py index 7ac536b2eb9..f0980dd5034 100644 --- a/examples/gdp/batchProcessing.py +++ b/examples/gdp/batchProcessing.py @@ -10,6 +10,7 @@ because the _opt file is different (It has hard-coded bigM parameters so that each constraint has the "optimal" bigM).''' + def build_model(): model = AbstractModel() @@ -17,9 +18,10 @@ def build_model(): model.BigM = Suffix(direction=Suffix.LOCAL) model.BigM[None] = 1000 - ## Constants from GAMS - StorageTankSizeFactor = 2*5 # btw, I know 2*5 is 10... I don't know why it's written this way in GAMS? + StorageTankSizeFactor = ( + 2 * 5 + ) # btw, I know 2*5 is 10... I don't know why it's written this way in GAMS? StorageTankSizeFactorByProd = 3 MinFlow = -log(10000) VolumeLB = log(300) @@ -31,7 +33,6 @@ def build_model(): # TODO: YOU ARE HERE. YOU HAVEN'T ACTUALLY MADE THESE THE BOUNDS YET, NOR HAVE YOU FIGURED OUT WHOSE # BOUNDS THEY ARE. AND THERE ARE MORE IN GAMS. - ########## # Sets ########## @@ -43,12 +44,11 @@ def build_model(): # TODO: this seems like an over-complicated way to accomplish this task... def filter_out_last(model, j): return j != model.STAGES.last() - model.STAGESExceptLast = Set(initialize=model.STAGES, filter=filter_out_last) + model.STAGESExceptLast = Set(initialize=model.STAGES, filter=filter_out_last) # TODO: these aren't in the formulation?? - #model.STORAGE_TANKS = Set() - + # model.STORAGE_TANKS = Set() ############### # Parameters @@ -66,8 +66,9 @@ def filter_out_last(model, j): # These are hard-coded in the GAMS file, hence the defaults model.StorageTankSizeFactor = Param(model.STAGES, default=StorageTankSizeFactor) - model.StorageTankSizeFactorByProd = Param(model.PRODUCTS, model.STAGES, - default=StorageTankSizeFactorByProd) + model.StorageTankSizeFactorByProd = Param( + model.PRODUCTS, model.STAGES, default=StorageTankSizeFactorByProd + ) # TODO: bonmin wasn't happy and I think it might have something to do with this? # or maybe issues with convexity or a lack thereof... I don't know yet. @@ -86,7 +87,6 @@ def get_log_coeffs(model, k): model.unitsInPhaseUB = Param(model.STAGES, default=UnitsInPhaseUB) model.unitsOutOfPhaseUB = Param(model.STAGES, default=UnitsOutOfPhaseUB) - ################ # Variables ################ @@ -115,17 +115,24 @@ def get_log_coeffs(model, k): # must be the log ones. def get_volume_bounds(model, j): return (model.volumeLB[j], model.volumeUB[j]) + model.volume_log = Var(model.STAGES, bounds=get_volume_bounds) model.batchSize_log = Var(model.PRODUCTS, model.STAGES) model.cycleTime_log = Var(model.PRODUCTS) + def get_unitsOutOfPhase_bounds(model, j): return (0, model.unitsOutOfPhaseUB[j]) + model.unitsOutOfPhase_log = Var(model.STAGES, bounds=get_unitsOutOfPhase_bounds) + def get_unitsInPhase_bounds(model, j): return (0, model.unitsInPhaseUB[j]) + model.unitsInPhase_log = Var(model.STAGES, bounds=get_unitsInPhase_bounds) + def get_storageTankSize_bounds(model, j): return (model.storageTankSizeLB[j], model.storageTankSizeUB[j]) + # TODO: these bounds make it infeasible... model.storageTankSize_log = Var(model.STAGES, bounds=get_storageTankSize_bounds) @@ -138,31 +145,55 @@ def get_storageTankSize_bounds(model, j): ############### def get_cost_rule(model): - return model.Alpha1 * sum(exp(model.unitsInPhase_log[j] + model.unitsOutOfPhase_log[j] + \ - model.Beta1 * model.volume_log[j]) for j in model.STAGES) +\ - model.Alpha2 * sum(exp(model.Beta2 * model.storageTankSize_log[j]) for j in model.STAGESExceptLast) - model.min_cost = Objective(rule=get_cost_rule) + return model.Alpha1 * sum( + exp( + model.unitsInPhase_log[j] + + model.unitsOutOfPhase_log[j] + + model.Beta1 * model.volume_log[j] + ) + for j in model.STAGES + ) + model.Alpha2 * sum( + exp(model.Beta2 * model.storageTankSize_log[j]) + for j in model.STAGESExceptLast + ) + model.min_cost = Objective(rule=get_cost_rule) ############## # Constraints ############## def processing_capacity_rule(model, j, i): - return model.volume_log[j] >= log(model.ProductSizeFactor[i, j]) + model.batchSize_log[i, j] - \ - model.unitsInPhase_log[j] - model.processing_capacity = Constraint(model.STAGES, model.PRODUCTS, rule=processing_capacity_rule) + return ( + model.volume_log[j] + >= log(model.ProductSizeFactor[i, j]) + + model.batchSize_log[i, j] + - model.unitsInPhase_log[j] + ) + + model.processing_capacity = Constraint( + model.STAGES, model.PRODUCTS, rule=processing_capacity_rule + ) def processing_time_rule(model, j, i): - return model.cycleTime_log[i] >= log(model.ProcessingTime[i, j]) - model.batchSize_log[i, j] - \ - model.unitsOutOfPhase_log[j] - model.processing_time = Constraint(model.STAGES, model.PRODUCTS, rule=processing_time_rule) + return ( + model.cycleTime_log[i] + >= log(model.ProcessingTime[i, j]) + - model.batchSize_log[i, j] + - model.unitsOutOfPhase_log[j] + ) + + model.processing_time = Constraint( + model.STAGES, model.PRODUCTS, rule=processing_time_rule + ) def finish_in_time_rule(model): - return model.HorizonTime >= sum(model.ProductionAmount[i]*exp(model.cycleTime_log[i]) \ - for i in model.PRODUCTS) - model.finish_in_time = Constraint(rule=finish_in_time_rule) + return model.HorizonTime >= sum( + model.ProductionAmount[i] * exp(model.cycleTime_log[i]) + for i in model.PRODUCTS + ) + model.finish_in_time = Constraint(rule=finish_in_time_rule) ############### # Disjunctions @@ -170,55 +201,84 @@ def finish_in_time_rule(model): def storage_tank_selection_disjunct_rule(disjunct, selectStorageTank, j): model = disjunct.model() + def volume_stage_j_rule(disjunct, i): - return model.storageTankSize_log[j] >= log(model.StorageTankSizeFactor[j]) + \ - model.batchSize_log[i, j] + return ( + model.storageTankSize_log[j] + >= log(model.StorageTankSizeFactor[j]) + model.batchSize_log[i, j] + ) + def volume_stage_jPlus1_rule(disjunct, i): - return model.storageTankSize_log[j] >= log(model.StorageTankSizeFactor[j]) + \ - model.batchSize_log[i, j+1] + return ( + model.storageTankSize_log[j] + >= log(model.StorageTankSizeFactor[j]) + model.batchSize_log[i, j + 1] + ) + def batch_size_rule(disjunct, i): - return inequality(-log(model.StorageTankSizeFactorByProd[i,j]), - model.batchSize_log[i,j] - model.batchSize_log[i, j+1], - log(model.StorageTankSizeFactorByProd[i,j])) + return inequality( + -log(model.StorageTankSizeFactorByProd[i, j]), + model.batchSize_log[i, j] - model.batchSize_log[i, j + 1], + log(model.StorageTankSizeFactorByProd[i, j]), + ) + def no_batch_rule(disjunct, i): - return model.batchSize_log[i,j] - model.batchSize_log[i,j+1] == 0 + return model.batchSize_log[i, j] - model.batchSize_log[i, j + 1] == 0 if selectStorageTank: - disjunct.volume_stage_j = Constraint(model.PRODUCTS, rule=volume_stage_j_rule) - disjunct.volume_stage_jPlus1 = Constraint(model.PRODUCTS, - rule=volume_stage_jPlus1_rule) + disjunct.volume_stage_j = Constraint( + model.PRODUCTS, rule=volume_stage_j_rule + ) + disjunct.volume_stage_jPlus1 = Constraint( + model.PRODUCTS, rule=volume_stage_jPlus1_rule + ) disjunct.batch_size = Constraint(model.PRODUCTS, rule=batch_size_rule) else: # The formulation says 0, but GAMS has this constant. # 04/04: Francisco says volume should be free: # disjunct.no_volume = Constraint(expr=model.storageTankSize_log[j] == MinFlow) disjunct.no_batch = Constraint(model.PRODUCTS, rule=no_batch_rule) - model.storage_tank_selection_disjunct = Disjunct([0,1], model.STAGESExceptLast, - rule=storage_tank_selection_disjunct_rule) + + model.storage_tank_selection_disjunct = Disjunct( + [0, 1], model.STAGESExceptLast, rule=storage_tank_selection_disjunct_rule + ) def select_storage_tanks_rule(model, j): - return [model.storage_tank_selection_disjunct[selectTank, j] for selectTank in [0,1]] - model.select_storage_tanks = Disjunction(model.STAGESExceptLast, rule=select_storage_tanks_rule) + return [ + model.storage_tank_selection_disjunct[selectTank, j] + for selectTank in [0, 1] + ] + + model.select_storage_tanks = Disjunction( + model.STAGESExceptLast, rule=select_storage_tanks_rule + ) # though this is a disjunction in the GAMs model, it is more efficiently formulated this way: # TODO: what on earth is k? def units_out_of_phase_rule(model, j): - return model.unitsOutOfPhase_log[j] == sum(model.LogCoeffs[k] * model.outOfPhase[j,k] \ - for k in model.PARALLELUNITS) + return model.unitsOutOfPhase_log[j] == sum( + model.LogCoeffs[k] * model.outOfPhase[j, k] for k in model.PARALLELUNITS + ) + model.units_out_of_phase = Constraint(model.STAGES, rule=units_out_of_phase_rule) def units_in_phase_rule(model, j): - return model.unitsInPhase_log[j] == sum(model.LogCoeffs[k] * model.inPhase[j,k] \ - for k in model.PARALLELUNITS) + return model.unitsInPhase_log[j] == sum( + model.LogCoeffs[k] * model.inPhase[j, k] for k in model.PARALLELUNITS + ) + model.units_in_phase = Constraint(model.STAGES, rule=units_in_phase_rule) # and since I didn't do the disjunction as a disjunction, we need the XORs: def units_out_of_phase_xor_rule(model, j): - return sum(model.outOfPhase[j,k] for k in model.PARALLELUNITS) == 1 - model.units_out_of_phase_xor = Constraint(model.STAGES, rule=units_out_of_phase_xor_rule) + return sum(model.outOfPhase[j, k] for k in model.PARALLELUNITS) == 1 + + model.units_out_of_phase_xor = Constraint( + model.STAGES, rule=units_out_of_phase_xor_rule + ) def units_in_phase_xor_rule(model, j): - return sum(model.inPhase[j,k] for k in model.PARALLELUNITS) == 1 + return sum(model.inPhase[j, k] for k in model.PARALLELUNITS) == 1 + model.units_in_phase_xor = Constraint(model.STAGES, rule=units_in_phase_xor_rule) return model @@ -227,5 +287,7 @@ def units_in_phase_xor_rule(model, j): if __name__ == "__main__": m = build_model().create_instance('batchProcessing1.dat') TransformationFactory('gdp.bigm').apply_to(m) - SolverFactory('gams').solve(m, solver='baron', tee=True, add_options=['option optcr=1e-6;']) + SolverFactory('gams').solve( + m, solver='baron', tee=True, add_options=['option optcr=1e-6;'] + ) m.min_cost.display() diff --git a/examples/gdp/constrained_layout/cons_layout_model.py b/examples/gdp/constrained_layout/cons_layout_model.py index b12cf1463d1..f9110ea5fdf 100644 --- a/examples/gdp/constrained_layout/cons_layout_model.py +++ b/examples/gdp/constrained_layout/cons_layout_model.py @@ -11,8 +11,7 @@ """ from __future__ import division -from pyomo.environ import (ConcreteModel, Objective, Param, - RangeSet, Set, Var) +from pyomo.environ import ConcreteModel, Objective, Param, RangeSet, Set, Var def build_constrained_layout_model(): @@ -22,53 +21,60 @@ def build_constrained_layout_model(): m.circles = RangeSet(2, doc="Two circles") m.rect_length = Param( - m.rectangles, initialize={1: 5, 2: 7, 3: 3}, - doc="Rectangle length") + m.rectangles, initialize={1: 5, 2: 7, 3: 3}, doc="Rectangle length" + ) m.rect_height = Param( - m.rectangles, initialize={1: 6, 2: 5, 3: 3}, - doc="Rectangle height") + m.rectangles, initialize={1: 6, 2: 5, 3: 3}, doc="Rectangle height" + ) - m.circle_x = Param(m.circles, initialize={1: 15, 2: 50}, - doc="x-coordinate of circle center") - m.circle_y = Param(m.circles, initialize={1: 10, 2: 80}, - doc="y-coordinate of circle center") - m.circle_r = Param(m.circles, initialize={1: 6, 2: 5}, - doc="radius of circle") + m.circle_x = Param( + m.circles, initialize={1: 15, 2: 50}, doc="x-coordinate of circle center" + ) + m.circle_y = Param( + m.circles, initialize={1: 10, 2: 80}, doc="y-coordinate of circle center" + ) + m.circle_r = Param(m.circles, initialize={1: 6, 2: 5}, doc="radius of circle") @m.Param(m.rectangles, doc="Minimum feasible x value for rectangle") def x_min(m, rect): return min( m.circle_x[circ] - m.circle_r[circ] + m.rect_length[rect] / 2 - for circ in m.circles) + for circ in m.circles + ) @m.Param(m.rectangles, doc="Maximum feasible x value for rectangle") def x_max(m, rect): return max( m.circle_x[circ] + m.circle_r[circ] - m.rect_length[rect] / 2 - for circ in m.circles) + for circ in m.circles + ) @m.Param(m.rectangles, doc="Minimum feasible y value for rectangle") def y_min(m, rect): return min( m.circle_y[circ] - m.circle_r[circ] + m.rect_height[rect] / 2 - for circ in m.circles) + for circ in m.circles + ) @m.Param(m.rectangles, doc="Maximum feasible y value for rectangle") def y_max(m, rect): return max( m.circle_y[circ] + m.circle_r[circ] - m.rect_height[rect] / 2 - for circ in m.circles) + for circ in m.circles + ) m.ordered_rect_pairs = Set( - initialize=m.rectangles * m.rectangles, - filter=lambda _, r1, r2: r1 != r2) - m.rect_pairs = Set(initialize=[ - (r1, r2) for r1, r2 in m.ordered_rect_pairs - if r1 < r2]) + initialize=m.rectangles * m.rectangles, filter=lambda _, r1, r2: r1 != r2 + ) + m.rect_pairs = Set( + initialize=[(r1, r2) for r1, r2 in m.ordered_rect_pairs if r1 < r2] + ) m.rect_sep_penalty = Param( - m.rect_pairs, initialize={(1, 2): 300, (1, 3): 240, (2, 3): 100}, - doc="Penalty for separation distance between two rectangles.") + m.rect_pairs, + initialize={(1, 2): 300, (1, 3): 240, (2, 3): 100}, + doc="Penalty for separation distance between two rectangles.", + ) def x_bounds(m, rect): return m.x_min[rect], m.x_max[rect] @@ -77,47 +83,44 @@ def y_bounds(m, rect): return m.y_min[rect], m.y_max[rect] m.rect_x = Var( - m.rectangles, doc="x-coordinate of rectangle center", - bounds=x_bounds) + m.rectangles, doc="x-coordinate of rectangle center", bounds=x_bounds + ) m.rect_y = Var( - m.rectangles, doc="y-coordinate of rectangle center", - bounds=y_bounds) - m.dist_x = Var( - m.rect_pairs, doc="x-axis separation between rectangle pair") - m.dist_y = Var( - m.rect_pairs, doc="y-axis separation between rectangle pair") + m.rectangles, doc="y-coordinate of rectangle center", bounds=y_bounds + ) + m.dist_x = Var(m.rect_pairs, doc="x-axis separation between rectangle pair") + m.dist_y = Var(m.rect_pairs, doc="y-axis separation between rectangle pair") m.min_dist_cost = Objective( - expr=sum(m.rect_sep_penalty[r1, r2] * - (m.dist_x[r1, r2] + m.dist_y[r1, r2]) - for (r1, r2) in m.rect_pairs)) + expr=sum( + m.rect_sep_penalty[r1, r2] * (m.dist_x[r1, r2] + m.dist_y[r1, r2]) + for (r1, r2) in m.rect_pairs + ) + ) - @m.Constraint(m.ordered_rect_pairs, - doc="x-distance between rectangles") + @m.Constraint(m.ordered_rect_pairs, doc="x-distance between rectangles") def dist_x_defn(m, r1, r2): - return m.dist_x[ - tuple(sorted([r1, r2]))] >= m.rect_x[r2] - m.rect_x[r1] + return m.dist_x[tuple(sorted([r1, r2]))] >= m.rect_x[r2] - m.rect_x[r1] - @m.Constraint(m.ordered_rect_pairs, - doc="y-distance between rectangles") + @m.Constraint(m.ordered_rect_pairs, doc="y-distance between rectangles") def dist_y_defn(m, r1, r2): - return m.dist_y[ - tuple(sorted([r1, r2]))] >= m.rect_y[r2] - m.rect_y[r1] + return m.dist_y[tuple(sorted([r1, r2]))] >= m.rect_y[r2] - m.rect_y[r1] @m.Disjunction( m.rect_pairs, doc="Make sure that none of the rectangles overlap in " - "either the x or y dimensions.") + "either the x or y dimensions.", + ) def no_overlap(m, r1, r2): return [ - m.rect_x[r1] + m.rect_length[r1] / 2 <= ( - m.rect_x[r2] - m.rect_length[r2] / 2), - m.rect_y[r1] + m.rect_height[r1] / 2 <= ( - m.rect_y[r2] - m.rect_height[r2] / 2), - m.rect_x[r2] + m.rect_length[r2] / 2 <= ( - m.rect_x[r1] - m.rect_length[r1] / 2), - m.rect_y[r2] + m.rect_height[r2] / 2 <= ( - m.rect_y[r1] - m.rect_height[r1] / 2), + m.rect_x[r1] + m.rect_length[r1] / 2 + <= (m.rect_x[r2] - m.rect_length[r2] / 2), + m.rect_y[r1] + m.rect_height[r1] / 2 + <= (m.rect_y[r2] - m.rect_height[r2] / 2), + m.rect_x[r2] + m.rect_length[r2] / 2 + <= (m.rect_x[r1] - m.rect_length[r1] / 2), + m.rect_y[r2] + m.rect_height[r2] / 2 + <= (m.rect_y[r1] - m.rect_height[r1] / 2), ] @m.Disjunction(m.rectangles, doc="Each rectangle must be in a circle.") @@ -125,20 +128,20 @@ def rectangle_in_circle(m, r): return [ [ # Rectangle lower left corner in circle - (m.rect_x[r] - m.rect_length[r] / 2 - m.circle_x[c]) ** 2 + - (m.rect_y[r] + m.rect_height[r] / 2 - m.circle_y[c]) ** 2 + (m.rect_x[r] - m.rect_length[r] / 2 - m.circle_x[c]) ** 2 + + (m.rect_y[r] + m.rect_height[r] / 2 - m.circle_y[c]) ** 2 <= m.circle_r[c] ** 2, # rectangle upper left corner in circle - (m.rect_x[r] - m.rect_length[r] / 2 - m.circle_x[c]) ** 2 + - (m.rect_y[r] - m.rect_height[r] / 2 - m.circle_y[c]) ** 2 + (m.rect_x[r] - m.rect_length[r] / 2 - m.circle_x[c]) ** 2 + + (m.rect_y[r] - m.rect_height[r] / 2 - m.circle_y[c]) ** 2 <= m.circle_r[c] ** 2, # rectangle lower right corner in circle - (m.rect_x[r] + m.rect_length[r] / 2 - m.circle_x[c]) ** 2 + - (m.rect_y[r] + m.rect_height[r] / 2 - m.circle_y[c]) ** 2 + (m.rect_x[r] + m.rect_length[r] / 2 - m.circle_x[c]) ** 2 + + (m.rect_y[r] + m.rect_height[r] / 2 - m.circle_y[c]) ** 2 <= m.circle_r[c] ** 2, # rectangle upper right corner in circle - (m.rect_x[r] + m.rect_length[r] / 2 - m.circle_x[c]) ** 2 + - (m.rect_y[r] - m.rect_height[r] / 2 - m.circle_y[c]) ** 2 + (m.rect_x[r] + m.rect_length[r] / 2 - m.circle_x[c]) ** 2 + + (m.rect_y[r] - m.rect_height[r] / 2 - m.circle_y[c]) ** 2 <= m.circle_r[c] ** 2, ] for c in m.circles diff --git a/examples/gdp/disease_model.py b/examples/gdp/disease_model.py index a1f52c4d7d3..bc3e69600ec 100644 --- a/examples/gdp/disease_model.py +++ b/examples/gdp/disease_model.py @@ -21,53 +21,1619 @@ from pyomo.gdp import * import math + def build_model(): # import data - pop = [ 15.881351, 15.881339, 15.881320, 15.881294, 15.881261, 15.881223, 15.881180, 15.881132, 15.881079, 15.881022, 15.880961, 15.880898, 15.880832, 15.880764, 15.880695, 15.880624, 15.880553, 15.880480, 15.880409, 15.880340, 15.880270, 15.880203, 15.880138, 15.880076, 15.880016, 15.879960, 15.879907, 15.879852, 15.879799, 15.879746, 15.879693, 15.879638, 15.879585, 15.879531, 15.879477, 15.879423, 15.879370, 15.879315, 15.879262, 15.879209, 15.879155, 15.879101, 15.879048, 15.878994, 15.878940, 15.878886, 15.878833, 15.878778, 15.878725, 15.878672, 15.878618, 15.878564, 15.878510, 15.878457, 15.878402, 15.878349, 15.878295, 15.878242, 15.878187, 15.878134, 15.878081, 15.878026, 15.877973, 15.877919, 15.877864, 15.877811, 15.877758, 15.877704, 15.877650, 15.877596, 15.877543, 15.877488, 15.877435, 15.877381, 15.877326, 15.877273, 15.877220, 15.877166, 15.877111, 15.877058, 15.877005, 15.876950, 15.876896, 15.876843, 15.876789, 15.876735, 15.876681, 15.876628, 15.876573, 15.876520, 15.876466, 15.876411, 15.876358, 15.876304, 15.876251, 15.876196, 15.876143, 15.876089, 15.876034, 15.875981, 15.875927, 15.875872, 15.875819, 15.875765, 15.875712, 15.875657, 15.875604, 15.875550, 15.875495, 15.875442, 15.875388, 15.875335, 15.875280, 15.875226, 15.875173, 15.875118, 15.875064, 15.875011, 15.874956, 15.874902, 15.874849, 15.874795, 15.874740, 15.874687, 15.874633, 15.874578, 15.874525, 15.874471, 15.874416, 15.874363, 15.874309, 15.874256, 15.874201, 15.874147, 15.874094, 15.874039, 15.873985, 15.873931, 15.873878, 15.873823, 15.873769, 15.873716, 15.873661, 15.873607, 15.873554, 15.873499, 15.873445, 15.873391, 15.873338, 15.873283, 15.873229, 15.873175, 15.873121, 15.873067, 15.873013, 15.872960, 15.872905, 15.872851, 15.872797, 15.872742, 15.872689, 15.872635, 15.872580, 15.872526, 15.872473, 15.872419, 15.872364, 15.872310, 15.872256, 15.872202, 15.872148, 15.872094, 15.872039, 15.871985, 15.871932, 15.871878, 15.871823, 15.871769, 15.871715, 15.871660, 15.871607, 15.871553, 15.871499, 15.871444, 15.871390, 15.871337, 15.871282, 15.871228, 15.871174, 15.871119, 15.871065, 15.871012, 15.870958, 15.870903, 15.870849, 15.870795, 15.870740, 15.870686, 15.870633, 15.870577, 15.870524, 15.870470, 15.870416, 15.870361, 15.870307, 15.870253, 15.870198, 15.870144, 15.870091, 15.870037, 15.869982, 15.869928, 15.869874, 15.869819, 15.869765, 15.869711, 15.869656, 15.869602, 15.869548, 15.869495, 15.869439, 15.869386, 15.869332, 15.869277, 15.869223, 15.869169, 15.869114, 15.869060, 15.869006, 15.868952, 15.868897, 15.868843, 15.868789, 15.868734, 15.868679, 15.868618, 15.868556, 15.868489, 15.868421, 15.868351, 15.868280, 15.868208, 15.868134, 15.868063, 15.867991, 15.867921, 15.867852, 15.867785, 15.867721, 15.867659, 15.867601, 15.867549, 15.867499, 15.867455, 15.867416, 15.867383, 15.867357, 15.867338, 15.867327, 15.867321, 15.867327, 15.867338, 15.867359, 15.867386, 15.867419, 15.867459, 15.867505, 15.867555, 15.867610, 15.867671, 15.867734, 15.867801, 15.867869, 15.867941, 15.868012, 15.868087, 15.868161, 15.868236, 15.868310, 15.868384, 15.868457, 15.868527, 15.868595, 15.868661, 15.868722, 15.868780, 15.868837, 15.868892, 15.868948, 15.869005, 15.869061, 15.869116, 15.869173, 15.869229, 15.869284, 15.869341, 15.869397, 15.869452, 15.869509, 15.869565, 15.869620, 15.869677, 15.869733, 15.869788, 15.869845, 15.869901, 15.869956, 15.870012, 15.870069, 15.870124, 15.870180, 15.870237, 15.870292, 15.870348, 15.870405, 15.870461, 15.870516, 15.870572, 15.870629, 15.870684, 15.870740, 15.870796, 15.870851, 15.870908, 15.870964, 15.871019, 15.871076, 15.871132, 15.871187, 15.871243, 15.871300, 15.871355, 15.871411, 15.871467, 15.871522, 15.871579, 15.871635, 15.871691, 15.871746, 15.871802, 15.871859, 15.871914, 15.871970, 15.872026, 15.872081, 15.872138, 15.872194, 15.872249, 15.872305, 15.872361, 15.872416, 15.872473, 15.872529, 15.872584, 15.872640, 15.872696, 15.872751, 15.872807, 15.872864, 15.872919, 15.872975, 15.873031, 15.873087, 15.873142, 15.873198, 15.873255, 15.873310, 15.873366, 15.873422, 15.873477, 15.873533, 15.873589, 15.873644, 15.873700, 15.873757, 15.873811, 15.873868, 15.873924, 15.873979, 15.874035, 15.874091, 15.874146, 15.874202, 15.874258, 15.874313, 15.874369, 15.874425, 15.874481, 15.874536, 15.874592] + pop = [ + 15.881351, + 15.881339, + 15.881320, + 15.881294, + 15.881261, + 15.881223, + 15.881180, + 15.881132, + 15.881079, + 15.881022, + 15.880961, + 15.880898, + 15.880832, + 15.880764, + 15.880695, + 15.880624, + 15.880553, + 15.880480, + 15.880409, + 15.880340, + 15.880270, + 15.880203, + 15.880138, + 15.880076, + 15.880016, + 15.879960, + 15.879907, + 15.879852, + 15.879799, + 15.879746, + 15.879693, + 15.879638, + 15.879585, + 15.879531, + 15.879477, + 15.879423, + 15.879370, + 15.879315, + 15.879262, + 15.879209, + 15.879155, + 15.879101, + 15.879048, + 15.878994, + 15.878940, + 15.878886, + 15.878833, + 15.878778, + 15.878725, + 15.878672, + 15.878618, + 15.878564, + 15.878510, + 15.878457, + 15.878402, + 15.878349, + 15.878295, + 15.878242, + 15.878187, + 15.878134, + 15.878081, + 15.878026, + 15.877973, + 15.877919, + 15.877864, + 15.877811, + 15.877758, + 15.877704, + 15.877650, + 15.877596, + 15.877543, + 15.877488, + 15.877435, + 15.877381, + 15.877326, + 15.877273, + 15.877220, + 15.877166, + 15.877111, + 15.877058, + 15.877005, + 15.876950, + 15.876896, + 15.876843, + 15.876789, + 15.876735, + 15.876681, + 15.876628, + 15.876573, + 15.876520, + 15.876466, + 15.876411, + 15.876358, + 15.876304, + 15.876251, + 15.876196, + 15.876143, + 15.876089, + 15.876034, + 15.875981, + 15.875927, + 15.875872, + 15.875819, + 15.875765, + 15.875712, + 15.875657, + 15.875604, + 15.875550, + 15.875495, + 15.875442, + 15.875388, + 15.875335, + 15.875280, + 15.875226, + 15.875173, + 15.875118, + 15.875064, + 15.875011, + 15.874956, + 15.874902, + 15.874849, + 15.874795, + 15.874740, + 15.874687, + 15.874633, + 15.874578, + 15.874525, + 15.874471, + 15.874416, + 15.874363, + 15.874309, + 15.874256, + 15.874201, + 15.874147, + 15.874094, + 15.874039, + 15.873985, + 15.873931, + 15.873878, + 15.873823, + 15.873769, + 15.873716, + 15.873661, + 15.873607, + 15.873554, + 15.873499, + 15.873445, + 15.873391, + 15.873338, + 15.873283, + 15.873229, + 15.873175, + 15.873121, + 15.873067, + 15.873013, + 15.872960, + 15.872905, + 15.872851, + 15.872797, + 15.872742, + 15.872689, + 15.872635, + 15.872580, + 15.872526, + 15.872473, + 15.872419, + 15.872364, + 15.872310, + 15.872256, + 15.872202, + 15.872148, + 15.872094, + 15.872039, + 15.871985, + 15.871932, + 15.871878, + 15.871823, + 15.871769, + 15.871715, + 15.871660, + 15.871607, + 15.871553, + 15.871499, + 15.871444, + 15.871390, + 15.871337, + 15.871282, + 15.871228, + 15.871174, + 15.871119, + 15.871065, + 15.871012, + 15.870958, + 15.870903, + 15.870849, + 15.870795, + 15.870740, + 15.870686, + 15.870633, + 15.870577, + 15.870524, + 15.870470, + 15.870416, + 15.870361, + 15.870307, + 15.870253, + 15.870198, + 15.870144, + 15.870091, + 15.870037, + 15.869982, + 15.869928, + 15.869874, + 15.869819, + 15.869765, + 15.869711, + 15.869656, + 15.869602, + 15.869548, + 15.869495, + 15.869439, + 15.869386, + 15.869332, + 15.869277, + 15.869223, + 15.869169, + 15.869114, + 15.869060, + 15.869006, + 15.868952, + 15.868897, + 15.868843, + 15.868789, + 15.868734, + 15.868679, + 15.868618, + 15.868556, + 15.868489, + 15.868421, + 15.868351, + 15.868280, + 15.868208, + 15.868134, + 15.868063, + 15.867991, + 15.867921, + 15.867852, + 15.867785, + 15.867721, + 15.867659, + 15.867601, + 15.867549, + 15.867499, + 15.867455, + 15.867416, + 15.867383, + 15.867357, + 15.867338, + 15.867327, + 15.867321, + 15.867327, + 15.867338, + 15.867359, + 15.867386, + 15.867419, + 15.867459, + 15.867505, + 15.867555, + 15.867610, + 15.867671, + 15.867734, + 15.867801, + 15.867869, + 15.867941, + 15.868012, + 15.868087, + 15.868161, + 15.868236, + 15.868310, + 15.868384, + 15.868457, + 15.868527, + 15.868595, + 15.868661, + 15.868722, + 15.868780, + 15.868837, + 15.868892, + 15.868948, + 15.869005, + 15.869061, + 15.869116, + 15.869173, + 15.869229, + 15.869284, + 15.869341, + 15.869397, + 15.869452, + 15.869509, + 15.869565, + 15.869620, + 15.869677, + 15.869733, + 15.869788, + 15.869845, + 15.869901, + 15.869956, + 15.870012, + 15.870069, + 15.870124, + 15.870180, + 15.870237, + 15.870292, + 15.870348, + 15.870405, + 15.870461, + 15.870516, + 15.870572, + 15.870629, + 15.870684, + 15.870740, + 15.870796, + 15.870851, + 15.870908, + 15.870964, + 15.871019, + 15.871076, + 15.871132, + 15.871187, + 15.871243, + 15.871300, + 15.871355, + 15.871411, + 15.871467, + 15.871522, + 15.871579, + 15.871635, + 15.871691, + 15.871746, + 15.871802, + 15.871859, + 15.871914, + 15.871970, + 15.872026, + 15.872081, + 15.872138, + 15.872194, + 15.872249, + 15.872305, + 15.872361, + 15.872416, + 15.872473, + 15.872529, + 15.872584, + 15.872640, + 15.872696, + 15.872751, + 15.872807, + 15.872864, + 15.872919, + 15.872975, + 15.873031, + 15.873087, + 15.873142, + 15.873198, + 15.873255, + 15.873310, + 15.873366, + 15.873422, + 15.873477, + 15.873533, + 15.873589, + 15.873644, + 15.873700, + 15.873757, + 15.873811, + 15.873868, + 15.873924, + 15.873979, + 15.874035, + 15.874091, + 15.874146, + 15.874202, + 15.874258, + 15.874313, + 15.874369, + 15.874425, + 15.874481, + 15.874536, + 15.874592, + ] - logIstar = [7.943245, 8.269994, 8.517212, 8.814208, 9.151740, 9.478472, 9.559847, 9.664087, 9.735378, 9.852583, 9.692265, 9.498807, 9.097634, 8.388878, 7.870516, 7.012956, 6.484941, 5.825368, 5.346815, 5.548361, 5.706732, 5.712617, 5.709714, 5.696888, 5.530087, 5.826563, 6.643563, 7.004292, 7.044663, 7.190259, 7.335926, 7.516861, 7.831779, 8.188895, 8.450204, 8.801436, 8.818379, 8.787658, 8.601685, 8.258338, 7.943364, 7.425585, 7.062834, 6.658307, 6.339600, 6.526984, 6.679178, 6.988758, 7.367331, 7.746694, 8.260558, 8.676522, 9.235582, 9.607778, 9.841917, 10.081571, 10.216090, 10.350366, 10.289668, 10.248842, 10.039504, 9.846343, 9.510392, 9.190923, 8.662465, 7.743221, 7.128458, 5.967898, 5.373883, 5.097497, 4.836570, 5.203345, 5.544798, 5.443047, 5.181152, 5.508669, 6.144130, 6.413744, 6.610423, 6.748885, 6.729511, 6.789841, 6.941034, 7.093516, 7.307039, 7.541077, 7.644803, 7.769145, 7.760187, 7.708017, 7.656795, 7.664983, 7.483828, 6.887324, 6.551093, 6.457449, 6.346064, 6.486300, 6.612378, 6.778753, 6.909477, 7.360570, 8.150303, 8.549044, 8.897572, 9.239323, 9.538751, 9.876531, 10.260911, 10.613536, 10.621510, 10.661115, 10.392899, 10.065536, 9.920090, 9.933097, 9.561691, 8.807713, 8.263463, 7.252184, 6.669083, 5.877763, 5.331878, 5.356563, 5.328469, 5.631146, 6.027497, 6.250717, 6.453919, 6.718444, 7.071636, 7.348905, 7.531528, 7.798226, 8.197941, 8.578809, 8.722964, 8.901152, 8.904370, 8.889865, 8.881902, 8.958903, 8.721281, 8.211509, 7.810624, 7.164607, 6.733688, 6.268503, 5.905983, 5.900432, 5.846547, 6.245427, 6.786271, 7.088480, 7.474295, 7.650063, 7.636703, 7.830990, 8.231516, 8.584816, 8.886908, 9.225216, 9.472778, 9.765505, 9.928623, 10.153033, 10.048574, 9.892620, 9.538818, 8.896100, 8.437584, 7.819738, 7.362598, 6.505880, 5.914972, 6.264584, 6.555019, 6.589319, 6.552029, 6.809771, 7.187616, 7.513918, 8.017712, 8.224957, 8.084474, 8.079148, 8.180991, 8.274269, 8.413748, 8.559599, 8.756090, 9.017927, 9.032720, 9.047983, 8.826873, 8.366489, 8.011876, 7.500830, 7.140406, 6.812626, 6.538719, 6.552218, 6.540129, 6.659927, 6.728530, 7.179692, 7.989210, 8.399173, 8.781128, 9.122303, 9.396378, 9.698512, 9.990104, 10.276543, 10.357284, 10.465869, 10.253833, 10.018503, 9.738407, 9.484367, 9.087025, 8.526409, 8.041126, 7.147168, 6.626706, 6.209446, 5.867231, 5.697439, 5.536769, 5.421413, 5.238297, 5.470136, 5.863007, 6.183083, 6.603569, 6.906278, 7.092324, 7.326612, 7.576052, 7.823430, 7.922775, 8.041677, 8.063403, 8.073229, 8.099726, 8.168522, 8.099041, 8.011404, 7.753147, 6.945211, 6.524244, 6.557723, 6.497742, 6.256247, 5.988794, 6.268093, 6.583316, 7.106842, 8.053929, 8.508237, 8.938915, 9.311863, 9.619753, 9.931745, 10.182361, 10.420978, 10.390829, 10.389230, 10.079342, 9.741479, 9.444561, 9.237448, 8.777687, 7.976436, 7.451502, 6.742856, 6.271545, 5.782289, 5.403089, 5.341954, 5.243509, 5.522993, 5.897001, 6.047042, 6.100738, 6.361727, 6.849562, 7.112544, 7.185346, 7.309412, 7.423746, 7.532142, 7.510318, 7.480175, 7.726362, 8.061117, 8.127072, 8.206166, 8.029634, 7.592953, 7.304869, 7.005394, 6.750019, 6.461377, 6.226432, 6.287047, 6.306452, 6.783694, 7.450957, 7.861692, 8.441530, 8.739626, 8.921994, 9.168961, 9.428077, 9.711664, 10.032714, 10.349937, 10.483985, 10.647475, 10.574038, 10.522431, 10.192246, 9.756246, 9.342511, 8.872072, 8.414189, 7.606582, 7.084701, 6.149903, 5.517257, 5.839429, 6.098090, 6.268935, 6.475965, 6.560543, 6.598942, 6.693938, 6.802531, 6.934345, 7.078370, 7.267736, 7.569640, 7.872204, 8.083603, 8.331226, 8.527144, 8.773523, 8.836599, 8.894303, 8.808326, 8.641717, 8.397901, 7.849034, 7.482899, 7.050252, 6.714103, 6.900603, 7.050765, 7.322905, 7.637986, 8.024340, 8.614505, 8.933591, 9.244008, 9.427410, 9.401385, 9.457744, 9.585068, 9.699673, 9.785478, 9.884559, 9.769732, 9.655075, 9.423071, 9.210198, 8.786654, 8.061787, 7.560976, 6.855829, 6.390707, 5.904006, 5.526631, 5.712303, 5.867027, 5.768367, 5.523352, 5.909118, 6.745543, 6.859218 ] + logIstar = [ + 7.943245, + 8.269994, + 8.517212, + 8.814208, + 9.151740, + 9.478472, + 9.559847, + 9.664087, + 9.735378, + 9.852583, + 9.692265, + 9.498807, + 9.097634, + 8.388878, + 7.870516, + 7.012956, + 6.484941, + 5.825368, + 5.346815, + 5.548361, + 5.706732, + 5.712617, + 5.709714, + 5.696888, + 5.530087, + 5.826563, + 6.643563, + 7.004292, + 7.044663, + 7.190259, + 7.335926, + 7.516861, + 7.831779, + 8.188895, + 8.450204, + 8.801436, + 8.818379, + 8.787658, + 8.601685, + 8.258338, + 7.943364, + 7.425585, + 7.062834, + 6.658307, + 6.339600, + 6.526984, + 6.679178, + 6.988758, + 7.367331, + 7.746694, + 8.260558, + 8.676522, + 9.235582, + 9.607778, + 9.841917, + 10.081571, + 10.216090, + 10.350366, + 10.289668, + 10.248842, + 10.039504, + 9.846343, + 9.510392, + 9.190923, + 8.662465, + 7.743221, + 7.128458, + 5.967898, + 5.373883, + 5.097497, + 4.836570, + 5.203345, + 5.544798, + 5.443047, + 5.181152, + 5.508669, + 6.144130, + 6.413744, + 6.610423, + 6.748885, + 6.729511, + 6.789841, + 6.941034, + 7.093516, + 7.307039, + 7.541077, + 7.644803, + 7.769145, + 7.760187, + 7.708017, + 7.656795, + 7.664983, + 7.483828, + 6.887324, + 6.551093, + 6.457449, + 6.346064, + 6.486300, + 6.612378, + 6.778753, + 6.909477, + 7.360570, + 8.150303, + 8.549044, + 8.897572, + 9.239323, + 9.538751, + 9.876531, + 10.260911, + 10.613536, + 10.621510, + 10.661115, + 10.392899, + 10.065536, + 9.920090, + 9.933097, + 9.561691, + 8.807713, + 8.263463, + 7.252184, + 6.669083, + 5.877763, + 5.331878, + 5.356563, + 5.328469, + 5.631146, + 6.027497, + 6.250717, + 6.453919, + 6.718444, + 7.071636, + 7.348905, + 7.531528, + 7.798226, + 8.197941, + 8.578809, + 8.722964, + 8.901152, + 8.904370, + 8.889865, + 8.881902, + 8.958903, + 8.721281, + 8.211509, + 7.810624, + 7.164607, + 6.733688, + 6.268503, + 5.905983, + 5.900432, + 5.846547, + 6.245427, + 6.786271, + 7.088480, + 7.474295, + 7.650063, + 7.636703, + 7.830990, + 8.231516, + 8.584816, + 8.886908, + 9.225216, + 9.472778, + 9.765505, + 9.928623, + 10.153033, + 10.048574, + 9.892620, + 9.538818, + 8.896100, + 8.437584, + 7.819738, + 7.362598, + 6.505880, + 5.914972, + 6.264584, + 6.555019, + 6.589319, + 6.552029, + 6.809771, + 7.187616, + 7.513918, + 8.017712, + 8.224957, + 8.084474, + 8.079148, + 8.180991, + 8.274269, + 8.413748, + 8.559599, + 8.756090, + 9.017927, + 9.032720, + 9.047983, + 8.826873, + 8.366489, + 8.011876, + 7.500830, + 7.140406, + 6.812626, + 6.538719, + 6.552218, + 6.540129, + 6.659927, + 6.728530, + 7.179692, + 7.989210, + 8.399173, + 8.781128, + 9.122303, + 9.396378, + 9.698512, + 9.990104, + 10.276543, + 10.357284, + 10.465869, + 10.253833, + 10.018503, + 9.738407, + 9.484367, + 9.087025, + 8.526409, + 8.041126, + 7.147168, + 6.626706, + 6.209446, + 5.867231, + 5.697439, + 5.536769, + 5.421413, + 5.238297, + 5.470136, + 5.863007, + 6.183083, + 6.603569, + 6.906278, + 7.092324, + 7.326612, + 7.576052, + 7.823430, + 7.922775, + 8.041677, + 8.063403, + 8.073229, + 8.099726, + 8.168522, + 8.099041, + 8.011404, + 7.753147, + 6.945211, + 6.524244, + 6.557723, + 6.497742, + 6.256247, + 5.988794, + 6.268093, + 6.583316, + 7.106842, + 8.053929, + 8.508237, + 8.938915, + 9.311863, + 9.619753, + 9.931745, + 10.182361, + 10.420978, + 10.390829, + 10.389230, + 10.079342, + 9.741479, + 9.444561, + 9.237448, + 8.777687, + 7.976436, + 7.451502, + 6.742856, + 6.271545, + 5.782289, + 5.403089, + 5.341954, + 5.243509, + 5.522993, + 5.897001, + 6.047042, + 6.100738, + 6.361727, + 6.849562, + 7.112544, + 7.185346, + 7.309412, + 7.423746, + 7.532142, + 7.510318, + 7.480175, + 7.726362, + 8.061117, + 8.127072, + 8.206166, + 8.029634, + 7.592953, + 7.304869, + 7.005394, + 6.750019, + 6.461377, + 6.226432, + 6.287047, + 6.306452, + 6.783694, + 7.450957, + 7.861692, + 8.441530, + 8.739626, + 8.921994, + 9.168961, + 9.428077, + 9.711664, + 10.032714, + 10.349937, + 10.483985, + 10.647475, + 10.574038, + 10.522431, + 10.192246, + 9.756246, + 9.342511, + 8.872072, + 8.414189, + 7.606582, + 7.084701, + 6.149903, + 5.517257, + 5.839429, + 6.098090, + 6.268935, + 6.475965, + 6.560543, + 6.598942, + 6.693938, + 6.802531, + 6.934345, + 7.078370, + 7.267736, + 7.569640, + 7.872204, + 8.083603, + 8.331226, + 8.527144, + 8.773523, + 8.836599, + 8.894303, + 8.808326, + 8.641717, + 8.397901, + 7.849034, + 7.482899, + 7.050252, + 6.714103, + 6.900603, + 7.050765, + 7.322905, + 7.637986, + 8.024340, + 8.614505, + 8.933591, + 9.244008, + 9.427410, + 9.401385, + 9.457744, + 9.585068, + 9.699673, + 9.785478, + 9.884559, + 9.769732, + 9.655075, + 9.423071, + 9.210198, + 8.786654, + 8.061787, + 7.560976, + 6.855829, + 6.390707, + 5.904006, + 5.526631, + 5.712303, + 5.867027, + 5.768367, + 5.523352, + 5.909118, + 6.745543, + 6.859218, + ] - deltaS = [ 9916.490263 ,12014.263380 ,13019.275755 ,12296.373612 ,8870.995603 ,1797.354574 ,-6392.880771 ,-16150.825387 ,-27083.245106 ,-40130.421462 ,-50377.169958 ,-57787.717468 ,-60797.223427 ,-59274.041897 ,-55970.213230 ,-51154.650927 ,-45877.841034 ,-40278.553775 ,-34543.967175 ,-28849.633641 ,-23192.776605 ,-17531.130740 ,-11862.021829 ,-6182.456792 ,-450.481090 ,5201.184400 ,10450.773882 ,15373.018272 ,20255.699431 ,24964.431669 ,29470.745887 ,33678.079947 ,37209.808930 ,39664.432393 ,41046.735479 ,40462.982011 ,39765.070209 ,39270.815830 ,39888.077002 ,42087.276604 ,45332.012929 ,49719.128772 ,54622.190928 ,59919.718626 ,65436.341097 ,70842.911460 ,76143.747430 ,81162.358574 ,85688.102884 ,89488.917734 ,91740.108470 ,91998.787916 ,87875.986012 ,79123.877908 ,66435.611045 ,48639.250610 ,27380.282817 ,2166.538464 ,-21236.428084 ,-43490.803535 ,-60436.624080 ,-73378.401966 ,-80946.278268 ,-84831.969493 ,-84696.627286 ,-81085.365407 ,-76410.847049 ,-70874.415387 ,-65156.276464 ,-59379.086883 ,-53557.267619 ,-47784.164830 ,-42078.001172 ,-36340.061427 ,-30541.788202 ,-24805.281435 ,-19280.817165 ,-13893.690606 ,-8444.172221 ,-3098.160839 ,2270.908649 ,7594.679295 ,12780.079247 ,17801.722109 ,22543.091206 ,26897.369814 ,31051.285734 ,34933.809557 ,38842.402859 ,42875.230152 ,47024.395356 ,51161.516122 ,55657.298307 ,60958.155424 ,66545.635029 ,72202.930397 ,77934.761905 ,83588.207792 ,89160.874522 ,94606.115027 ,99935.754968 ,104701.404975 ,107581.670606 ,108768.440311 ,107905.700480 ,104062.148863 ,96620.281684 ,83588.443029 ,61415.088182 ,27124.031692 ,-7537.285321 ,-43900.451653 ,-70274.062783 ,-87573.481475 ,-101712.148408 ,-116135.719087 ,-124187.225446 ,-124725.278371 ,-122458.145590 ,-117719.918256 ,-112352.138605 ,-106546.806030 ,-100583.803012 ,-94618.253238 ,-88639.090897 ,-82725.009842 ,-76938.910669 ,-71248.957807 ,-65668.352795 ,-60272.761991 ,-55179.538428 ,-50456.021161 ,-46037.728058 ,-42183.912670 ,-39522.184006 ,-38541.255303 ,-38383.665728 ,-39423.998130 ,-40489.466130 ,-41450.406768 ,-42355.156592 ,-43837.562085 ,-43677.262972 ,-41067.896944 ,-37238.628465 ,-32230.392026 ,-26762.766062 ,-20975.163308 ,-15019.218554 ,-9053.105545 ,-3059.663132 ,2772.399618 ,8242.538397 ,13407.752291 ,18016.047539 ,22292.125752 ,26616.583347 ,30502.564253 ,33153.890890 ,34216.684448 ,33394.220786 ,29657.417791 ,23064.375405 ,12040.831532 ,-2084.921068 ,-21390.235970 ,-38176.615985 ,-51647.714482 ,-59242.564959 ,-60263.150854 ,-58599.245165 ,-54804.972560 ,-50092.112608 ,-44465.812552 ,-38533.096297 ,-32747.104307 ,-27130.082610 ,-21529.632955 ,-15894.611939 ,-10457.566933 ,-5429.042583 ,-903.757828 ,2481.947589 ,5173.789976 ,8358.768202 ,11565.584635 ,14431.147931 ,16951.619820 ,18888.807708 ,20120.884465 ,20222.141242 ,18423.168124 ,16498.668271 ,14442.624242 ,14070.038273 ,16211.370808 ,19639.815904 ,24280.360465 ,29475.380079 ,35030.793540 ,40812.325095 ,46593.082382 ,52390.906885 ,58109.310860 ,63780.896094 ,68984.456561 ,72559.442320 ,74645.487900 ,74695.219755 ,72098.143876 ,66609.929889 ,56864.971296 ,41589.295266 ,19057.032104 ,-5951.329863 ,-34608.796853 ,-56603.801584 ,-72678.838057 ,-83297.070856 ,-90127.593511 ,-92656.040614 ,-91394.995510 ,-88192.056842 ,-83148.833075 ,-77582.587173 ,-71750.440823 ,-65765.369857 ,-59716.101820 ,-53613.430067 ,-47473.832358 ,-41287.031890 ,-35139.919259 ,-29097.671507 ,-23178.836760 ,-17486.807388 ,-12046.775779 ,-6802.483422 ,-1867.556171 ,2644.380534 ,6615.829501 ,10332.557518 ,13706.737038 ,17017.991307 ,20303.136670 ,23507.386461 ,26482.194102 ,29698.585356 ,33196.305757 ,37385.914179 ,42872.996212 ,48725.617879 ,54564.488527 ,60453.841604 ,66495.146265 ,72668.620416 ,78723.644870 ,84593.136677 ,89974.936239 ,93439.798630 ,95101.207834 ,94028.126381 ,89507.925620 ,80989.846001 ,66944.274744 ,47016.422041 ,19932.783790 ,-6198.433172 ,-32320.379400 ,-49822.852084 ,-60517.553414 ,-66860.548269 ,-70849.714105 ,-71058.721556 ,-67691.947812 ,-63130.703822 ,-57687.607311 ,-51916.952488 ,-45932.054982 ,-39834.909941 ,-33714.535713 ,-27564.443333 ,-21465.186188 ,-15469.326408 ,-9522.358787 ,-3588.742161 ,2221.802073 ,7758.244339 ,13020.269708 ,18198.562827 ,23211.338588 ,28051.699645 ,32708.577247 ,37413.795242 ,42181.401920 ,46462.499633 ,49849.582315 ,53026.578940 ,55930.600705 ,59432.642178 ,64027.356857 ,69126.843653 ,74620.328837 ,80372.056070 ,86348.152766 ,92468.907239 ,98568.998246 ,104669.511588 ,110445.790143 ,115394.348973 ,119477.553152 ,121528.574511 ,121973.674087 ,121048.017786 ,118021.473181 ,112151.993711 ,102195.999157 ,85972.731130 ,61224.719621 ,31949.279603 ,-3726.022971 ,-36485.298619 ,-67336.469799 ,-87799.366129 ,-98865.713558 ,-104103.651120 ,-105068.402300 ,-103415.820781 ,-99261.356633 ,-94281.850081 ,-88568.701325 ,-82625.711921 ,-76766.776770 ,-70998.803524 ,-65303.404499 ,-59719.198305 ,-54182.230439 ,-48662.904657 ,-43206.731668 ,-37732.701095 ,-32375.478519 ,-27167.508567 ,-22197.211891 ,-17722.869502 ,-13925.135219 ,-10737.893027 ,-8455.327914 ,-7067.008358 ,-7086.991191 ,-7527.693561 ,-8378.025732 ,-8629.383998 ,-7854.586079 ,-5853.040657 ,-1973.225485 ,2699.850783 ,8006.098287 ,13651.734934 ,19139.318072 ,24476.645420 ,29463.480336 ,33899.078820 ,37364.528796 ,38380.214949 ,37326.585649 ,33428.470616 ,27441.000494 ,21761.126583 ,15368.408081 ,7224.234078 ,-2702.217396 ,-14109.682505 ,-27390.915614 ,-38569.562393 ,-47875.155339 ,-53969.121872 ,-57703.473001 ,-57993.198171 ,-54908.391840 ,-50568.410328 ,-45247.622563 ,-39563.224328 ,-33637.786521 ,-27585.345413 ,-21572.074797 ,-15597.363909 ,-9577.429076 ,-3475.770622 ,2520.378408 ,8046.881775 ,13482.345595 ] + deltaS = [ + 9916.490263, + 12014.263380, + 13019.275755, + 12296.373612, + 8870.995603, + 1797.354574, + -6392.880771, + -16150.825387, + -27083.245106, + -40130.421462, + -50377.169958, + -57787.717468, + -60797.223427, + -59274.041897, + -55970.213230, + -51154.650927, + -45877.841034, + -40278.553775, + -34543.967175, + -28849.633641, + -23192.776605, + -17531.130740, + -11862.021829, + -6182.456792, + -450.481090, + 5201.184400, + 10450.773882, + 15373.018272, + 20255.699431, + 24964.431669, + 29470.745887, + 33678.079947, + 37209.808930, + 39664.432393, + 41046.735479, + 40462.982011, + 39765.070209, + 39270.815830, + 39888.077002, + 42087.276604, + 45332.012929, + 49719.128772, + 54622.190928, + 59919.718626, + 65436.341097, + 70842.911460, + 76143.747430, + 81162.358574, + 85688.102884, + 89488.917734, + 91740.108470, + 91998.787916, + 87875.986012, + 79123.877908, + 66435.611045, + 48639.250610, + 27380.282817, + 2166.538464, + -21236.428084, + -43490.803535, + -60436.624080, + -73378.401966, + -80946.278268, + -84831.969493, + -84696.627286, + -81085.365407, + -76410.847049, + -70874.415387, + -65156.276464, + -59379.086883, + -53557.267619, + -47784.164830, + -42078.001172, + -36340.061427, + -30541.788202, + -24805.281435, + -19280.817165, + -13893.690606, + -8444.172221, + -3098.160839, + 2270.908649, + 7594.679295, + 12780.079247, + 17801.722109, + 22543.091206, + 26897.369814, + 31051.285734, + 34933.809557, + 38842.402859, + 42875.230152, + 47024.395356, + 51161.516122, + 55657.298307, + 60958.155424, + 66545.635029, + 72202.930397, + 77934.761905, + 83588.207792, + 89160.874522, + 94606.115027, + 99935.754968, + 104701.404975, + 107581.670606, + 108768.440311, + 107905.700480, + 104062.148863, + 96620.281684, + 83588.443029, + 61415.088182, + 27124.031692, + -7537.285321, + -43900.451653, + -70274.062783, + -87573.481475, + -101712.148408, + -116135.719087, + -124187.225446, + -124725.278371, + -122458.145590, + -117719.918256, + -112352.138605, + -106546.806030, + -100583.803012, + -94618.253238, + -88639.090897, + -82725.009842, + -76938.910669, + -71248.957807, + -65668.352795, + -60272.761991, + -55179.538428, + -50456.021161, + -46037.728058, + -42183.912670, + -39522.184006, + -38541.255303, + -38383.665728, + -39423.998130, + -40489.466130, + -41450.406768, + -42355.156592, + -43837.562085, + -43677.262972, + -41067.896944, + -37238.628465, + -32230.392026, + -26762.766062, + -20975.163308, + -15019.218554, + -9053.105545, + -3059.663132, + 2772.399618, + 8242.538397, + 13407.752291, + 18016.047539, + 22292.125752, + 26616.583347, + 30502.564253, + 33153.890890, + 34216.684448, + 33394.220786, + 29657.417791, + 23064.375405, + 12040.831532, + -2084.921068, + -21390.235970, + -38176.615985, + -51647.714482, + -59242.564959, + -60263.150854, + -58599.245165, + -54804.972560, + -50092.112608, + -44465.812552, + -38533.096297, + -32747.104307, + -27130.082610, + -21529.632955, + -15894.611939, + -10457.566933, + -5429.042583, + -903.757828, + 2481.947589, + 5173.789976, + 8358.768202, + 11565.584635, + 14431.147931, + 16951.619820, + 18888.807708, + 20120.884465, + 20222.141242, + 18423.168124, + 16498.668271, + 14442.624242, + 14070.038273, + 16211.370808, + 19639.815904, + 24280.360465, + 29475.380079, + 35030.793540, + 40812.325095, + 46593.082382, + 52390.906885, + 58109.310860, + 63780.896094, + 68984.456561, + 72559.442320, + 74645.487900, + 74695.219755, + 72098.143876, + 66609.929889, + 56864.971296, + 41589.295266, + 19057.032104, + -5951.329863, + -34608.796853, + -56603.801584, + -72678.838057, + -83297.070856, + -90127.593511, + -92656.040614, + -91394.995510, + -88192.056842, + -83148.833075, + -77582.587173, + -71750.440823, + -65765.369857, + -59716.101820, + -53613.430067, + -47473.832358, + -41287.031890, + -35139.919259, + -29097.671507, + -23178.836760, + -17486.807388, + -12046.775779, + -6802.483422, + -1867.556171, + 2644.380534, + 6615.829501, + 10332.557518, + 13706.737038, + 17017.991307, + 20303.136670, + 23507.386461, + 26482.194102, + 29698.585356, + 33196.305757, + 37385.914179, + 42872.996212, + 48725.617879, + 54564.488527, + 60453.841604, + 66495.146265, + 72668.620416, + 78723.644870, + 84593.136677, + 89974.936239, + 93439.798630, + 95101.207834, + 94028.126381, + 89507.925620, + 80989.846001, + 66944.274744, + 47016.422041, + 19932.783790, + -6198.433172, + -32320.379400, + -49822.852084, + -60517.553414, + -66860.548269, + -70849.714105, + -71058.721556, + -67691.947812, + -63130.703822, + -57687.607311, + -51916.952488, + -45932.054982, + -39834.909941, + -33714.535713, + -27564.443333, + -21465.186188, + -15469.326408, + -9522.358787, + -3588.742161, + 2221.802073, + 7758.244339, + 13020.269708, + 18198.562827, + 23211.338588, + 28051.699645, + 32708.577247, + 37413.795242, + 42181.401920, + 46462.499633, + 49849.582315, + 53026.578940, + 55930.600705, + 59432.642178, + 64027.356857, + 69126.843653, + 74620.328837, + 80372.056070, + 86348.152766, + 92468.907239, + 98568.998246, + 104669.511588, + 110445.790143, + 115394.348973, + 119477.553152, + 121528.574511, + 121973.674087, + 121048.017786, + 118021.473181, + 112151.993711, + 102195.999157, + 85972.731130, + 61224.719621, + 31949.279603, + -3726.022971, + -36485.298619, + -67336.469799, + -87799.366129, + -98865.713558, + -104103.651120, + -105068.402300, + -103415.820781, + -99261.356633, + -94281.850081, + -88568.701325, + -82625.711921, + -76766.776770, + -70998.803524, + -65303.404499, + -59719.198305, + -54182.230439, + -48662.904657, + -43206.731668, + -37732.701095, + -32375.478519, + -27167.508567, + -22197.211891, + -17722.869502, + -13925.135219, + -10737.893027, + -8455.327914, + -7067.008358, + -7086.991191, + -7527.693561, + -8378.025732, + -8629.383998, + -7854.586079, + -5853.040657, + -1973.225485, + 2699.850783, + 8006.098287, + 13651.734934, + 19139.318072, + 24476.645420, + 29463.480336, + 33899.078820, + 37364.528796, + 38380.214949, + 37326.585649, + 33428.470616, + 27441.000494, + 21761.126583, + 15368.408081, + 7224.234078, + -2702.217396, + -14109.682505, + -27390.915614, + -38569.562393, + -47875.155339, + -53969.121872, + -57703.473001, + -57993.198171, + -54908.391840, + -50568.410328, + -45247.622563, + -39563.224328, + -33637.786521, + -27585.345413, + -21572.074797, + -15597.363909, + -9577.429076, + -3475.770622, + 2520.378408, + 8046.881775, + 13482.345595, + ] - beta_set = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] + beta_set = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + ] - #from new_data_set import * + # from new_data_set import * # declare model name model = ConcreteModel() # declare constants - bpy = 26 # biweeks per year - years = 15 # years of data - bigM = 50.0 # big M for disjunction constraints + bpy = 26 # biweeks per year + years = 15 # years of data + bigM = 50.0 # big M for disjunction constraints # declare sets - model.S_meas = RangeSet(1,bpy*years) - model.S_meas_small = RangeSet(1,bpy*years-1) - model.S_beta = RangeSet(1,bpy) + model.S_meas = RangeSet(1, bpy * years) + model.S_meas_small = RangeSet(1, bpy * years - 1) + model.S_beta = RangeSet(1, bpy) # define variable bounds - def _gt_zero(m,i): - return (0.0,1e7) + def _gt_zero(m, i): + return (0.0, 1e7) + def _beta_bounds(m): - return (None,5.0) + return (None, 5.0) # define variables # log of estimated cases - #model.logI = Var(model.S_meas, bounds=_gt_zero) - model.logI = Var(model.S_meas, bounds=(0.001,1e7)) + # model.logI = Var(model.S_meas, bounds=_gt_zero) + model.logI = Var(model.S_meas, bounds=(0.001, 1e7)) # log of transmission parameter beta - #model.logbeta = Var(model.S_beta, bounds=_gt_zero) - model.logbeta = Var(model.S_beta, bounds=(0.0001,5)) + # model.logbeta = Var(model.S_beta, bounds=_gt_zero) + model.logbeta = Var(model.S_beta, bounds=(0.0001, 5)) # binary variable y over all betas - #model.y = Var(model.S_beta, within=Binary) + # model.y = Var(model.S_beta, within=Binary) # low value of beta - #model.logbeta_low = Var(bounds=_beta_bounds) - model.logbeta_low = Var(bounds=(0.0001,5)) + # model.logbeta_low = Var(bounds=_beta_bounds) + model.logbeta_low = Var(bounds=(0.0001, 5)) # high value of beta - #model.logbeta_high = Var(bounds=_beta_bounds) - model.logbeta_high = Var(bounds=(0.0001,5)) + # model.logbeta_high = Var(bounds=_beta_bounds) + model.logbeta_high = Var(bounds=(0.0001, 5)) # dummy variables model.p = Var(model.S_meas, bounds=_gt_zero) model.n = Var(model.S_meas, bounds=_gt_zero) @@ -79,7 +1645,7 @@ def _beta_bounds(m): # changes in susceptible population profile from susceptible reconstruction deltaS = deltaS # mean susceptibles - #meanS = 1.04e6 + # meanS = 1.04e6 meanS = 8.65e5 # log of measured population logN = pop @@ -90,36 +1656,47 @@ def _beta_bounds(m): def _obj_rule(m): expr = sum(m.p[i] + m.n[i] for i in m.S_meas) return expr + model.obj = Objective(rule=_obj_rule, sense=minimize) # define constraints - def _logSIR(m,i): - expr = m.logI[i+1] - ( m.logbeta[beta_set[i-1]] + m.logI[i] + math.log(deltaS[i-1] + meanS) - logN[i-1] ) + def _logSIR(m, i): + expr = m.logI[i + 1] - ( + m.logbeta[beta_set[i - 1]] + + m.logI[i] + + math.log(deltaS[i - 1] + meanS) + - logN[i - 1] + ) return (0.0, expr) + model.logSIR = Constraint(model.S_meas_small, rule=_logSIR) # objective function constraint - def _p_n_const(m,i): - expr = logIstar[i-1] - m.logI[i] - m.p[i] + m.n[i] + def _p_n_const(m, i): + expr = logIstar[i - 1] - m.logI[i] - m.p[i] + m.n[i] return (0.0, expr) - model.p_n_const = Constraint(model.S_meas,rule=_p_n_const) + + model.p_n_const = Constraint(model.S_meas, rule=_p_n_const) # disjuncts model.BigM = Suffix() - model.y = RangeSet(0,1) + model.y = RangeSet(0, 1) + def _high_low(disjunct, i, y): model = disjunct.model() if y: - disjunct.c = Constraint(expr=model.logbeta_high - model.logbeta[i]== 0.0) + disjunct.c = Constraint(expr=model.logbeta_high - model.logbeta[i] == 0.0) else: disjunct.c = Constraint(expr=model.logbeta[i] - model.logbeta_low == 0.0) model.BigM[disjunct.c] = bigM + model.high_low = Disjunct(model.S_beta, model.y, rule=_high_low) # disjunctions def _disj(model, i): - return [model.high_low[i,j] for j in model.y] + return [model.high_low[i, j] for j in model.y] + model.disj = Disjunction(model.S_beta, rule=_disj) return model @@ -152,5 +1729,7 @@ def lowbeta_L(m,i): if __name__ == "__main__": m = build_model() TransformationFactory('gdp.bigm').apply_to(m) - SolverFactory('gams').solve(m, solver='baron', tee=True, add_options=['option optcr=1e-6;']) + SolverFactory('gams').solve( + m, solver='baron', tee=True, add_options=['option optcr=1e-6;'] + ) m.obj.display() diff --git a/examples/gdp/eight_process/eight_proc_logical.py b/examples/gdp/eight_process/eight_proc_logical.py index 12d3399c3a8..fa18eae8904 100644 --- a/examples/gdp/eight_process/eight_proc_logical.py +++ b/examples/gdp/eight_process/eight_proc_logical.py @@ -25,10 +25,23 @@ from __future__ import division from pyomo.core.expr.logical_expr import land, lor -from pyomo.core.plugins.transform.logical_to_linear import update_boolean_vars_from_binary +from pyomo.core.plugins.transform.logical_to_linear import ( + update_boolean_vars_from_binary, +) from pyomo.environ import ( - ConcreteModel, Constraint, ConstraintList, NonNegativeReals, - Objective, Param, RangeSet, Reference, Var, exp, minimize, LogicalConstraint, ) + ConcreteModel, + Constraint, + ConstraintList, + NonNegativeReals, + Objective, + Param, + RangeSet, + Reference, + Var, + exp, + minimize, + LogicalConstraint, +) from pyomo.gdp import Disjunct, Disjunction from pyomo.opt import SolverFactory @@ -44,9 +57,9 @@ def build_eight_process_flowsheet(): no_unit_zero_flows = { 1: (2, 3), 2: (4, 5), - 3: (9, ), + 3: (9,), 4: (12, 14), - 5: (15, ), + 5: (15,), 6: (19, 20), 7: (21, 22), 8: (10, 17, 18), @@ -60,24 +73,53 @@ def build_eight_process_flowsheet(): def fixed_cost_bounds(m, unit): return (0, m.CF[unit]) + m.yCF = Var(m.units, initialize=0, bounds=fixed_cost_bounds) # VARIABLE COST COEFF FOR PROCESS UNITS - STREAMS # Format: stream #: cost - variable_cost = {3: -10, 5: -15, 9: -40, 19: 25, 21: 35, 25: -35, - 17: 80, 14: 15, 10: 15, 2: 1, 4: 1, 18: -65, 20: -60, - 22: -80} + variable_cost = { + 3: -10, + 5: -15, + 9: -40, + 19: 25, + 21: 35, + 25: -35, + 17: 80, + 14: 15, + 10: 15, + 2: 1, + 4: 1, + 18: -65, + 20: -60, + 22: -80, + } CV = m.CV = Param(m.streams, initialize=variable_cost, default=0) # initial point information for stream flows - initX = {2: 2, 3: 1.5, 6: 0.75, 7: 0.5, 8: 0.5, 9: 0.75, 11: 1.5, - 12: 1.34, 13: 2, 14: 2.5, 17: 2, 18: 0.75, 19: 2, 20: 1.5, - 23: 1.7, 24: 1.5, 25: 0.5} + initX = { + 2: 2, + 3: 1.5, + 6: 0.75, + 7: 0.5, + 8: 0.5, + 9: 0.75, + 11: 1.5, + 12: 1.34, + 13: 2, + 14: 2.5, + 17: 2, + 18: 0.75, + 19: 2, + 20: 1.5, + 23: 1.7, + 24: 1.5, + 25: 0.5, + } """Variable declarations""" # FLOWRATES OF PROCESS STREAMS - m.flow = Var(m.streams, domain=NonNegativeReals, initialize=initX, - bounds=(0, 10)) + m.flow = Var(m.streams, domain=NonNegativeReals, initialize=initX, bounds=(0, 10)) # OBJECTIVE FUNCTION CONSTANT TERM CONSTANT = m.constant = Param(initialize=122.0) @@ -113,11 +155,9 @@ def use_unit_or_not(m, unit): # Mass balance equations m.massbal1 = Constraint(expr=m.flow[13] == m.flow[19] + m.flow[21]) - m.massbal2 = Constraint( - expr=m.flow[17] == m.flow[9] + m.flow[16] + m.flow[25]) + m.massbal2 = Constraint(expr=m.flow[17] == m.flow[9] + m.flow[16] + m.flow[25]) m.massbal3 = Constraint(expr=m.flow[11] == m.flow[12] + m.flow[15]) - m.massbal4 = Constraint( - expr=m.flow[3] + m.flow[5] == m.flow[6] + m.flow[11]) + m.massbal4 = Constraint(expr=m.flow[3] + m.flow[5] == m.flow[6] + m.flow[11]) m.massbal5 = Constraint(expr=m.flow[6] == m.flow[7] + m.flow[8]) m.massbal6 = Constraint(expr=m.flow[23] == m.flow[20] + m.flow[22]) m.massbal7 = Constraint(expr=m.flow[23] == m.flow[14] + m.flow[24]) @@ -133,19 +173,20 @@ def use_unit_or_not(m, unit): # logical propositions m.use1or2 = LogicalConstraint(expr=m.Y[1].xor(m.Y[2])) m.use1or2implies345 = LogicalConstraint( - expr=lor(m.Y[1], m.Y[2]).implies(lor(m.Y[3], m.Y[4], m.Y[5]))) + expr=lor(m.Y[1], m.Y[2]).implies(lor(m.Y[3], m.Y[4], m.Y[5])) + ) m.use4implies6or7 = LogicalConstraint(expr=m.Y[4].implies(lor(m.Y[6], m.Y[7]))) m.use3implies8 = LogicalConstraint(expr=m.Y[3].implies(m.Y[8])) m.use6or7implies4 = LogicalConstraint(expr=lor(m.Y[6], m.Y[7]).implies(m.Y[4])) m.use6or7 = LogicalConstraint(expr=m.Y[6].xor(m.Y[7])) """Profit (objective) function definition""" - m.profit = Objective(expr=sum( - m.yCF[unit] - for unit in m.units) + - sum(m.flow[stream] * CV[stream] - for stream in m.streams) + CONSTANT, - sense=minimize) + m.profit = Objective( + expr=sum(m.yCF[unit] for unit in m.units) + + sum(m.flow[stream] * CV[stream] for stream in m.streams) + + CONSTANT, + sense=minimize, + ) """Bound definitions""" # x (flow) upper bounds @@ -161,6 +202,7 @@ def use_unit_or_not(m, unit): if __name__ == "__main__": m = build_eight_process_flowsheet() from pyomo.environ import TransformationFactory + TransformationFactory('core.logical_to_linear').apply_to(m) SolverFactory('gdpopt.loa').solve(m, tee=True) update_boolean_vars_from_binary(m) diff --git a/examples/gdp/eight_process/eight_proc_model.py b/examples/gdp/eight_process/eight_proc_model.py index 3053ba53de2..d4bd4dbd102 100644 --- a/examples/gdp/eight_process/eight_proc_model.py +++ b/examples/gdp/eight_process/eight_proc_model.py @@ -24,8 +24,17 @@ """ from __future__ import division -from pyomo.environ import (ConcreteModel, Constraint, NonNegativeReals, - Objective, Param, RangeSet, Var, exp, minimize) +from pyomo.environ import ( + ConcreteModel, + Constraint, + NonNegativeReals, + Objective, + Param, + RangeSet, + Var, + exp, + minimize, +) from pyomo.gdp import Disjunction @@ -45,24 +54,53 @@ def build_eight_process_flowsheet(): def fixed_cost_bounds(m, unit): return (0, m.CF[unit]) + m.yCF = Var(m.units, initialize=0, bounds=fixed_cost_bounds) # VARIABLE COST COEFF FOR PROCESS UNITS - STREAMS # Format: stream #: cost - variable_cost = {3: -10, 5: -15, 9: -40, 19: 25, 21: 35, 25: -35, - 17: 80, 14: 15, 10: 15, 2: 1, 4: 1, 18: -65, 20: -60, - 22: -80} + variable_cost = { + 3: -10, + 5: -15, + 9: -40, + 19: 25, + 21: 35, + 25: -35, + 17: 80, + 14: 15, + 10: 15, + 2: 1, + 4: 1, + 18: -65, + 20: -60, + 22: -80, + } CV = m.CV = Param(m.streams, initialize=variable_cost, default=0) # initial point information for stream flows - initX = {2: 2, 3: 1.5, 6: 0.75, 7: 0.5, 8: 0.5, 9: 0.75, 11: 1.5, - 12: 1.34, 13: 2, 14: 2.5, 17: 2, 18: 0.75, 19: 2, 20: 1.5, - 23: 1.7, 24: 1.5, 25: 0.5} + initX = { + 2: 2, + 3: 1.5, + 6: 0.75, + 7: 0.5, + 8: 0.5, + 9: 0.75, + 11: 1.5, + 12: 1.34, + 13: 2, + 14: 2.5, + 17: 2, + 18: 0.75, + 19: 2, + 20: 1.5, + 23: 1.7, + 24: 1.5, + 25: 0.5, + } """Variable declarations""" # FLOWRATES OF PROCESS STREAMS - m.flow = Var(m.streams, domain=NonNegativeReals, initialize=initX, - bounds=(0, 10)) + m.flow = Var(m.streams, domain=NonNegativeReals, initialize=initX, bounds=(0, 10)) # OBJECTIVE FUNCTION CONSTANT TERM CONSTANT = m.constant = Param(initialize=122.0) @@ -71,77 +109,82 @@ def fixed_cost_bounds(m, unit): m.use_unit_1or2 = Disjunction( expr=[ # use unit 1 disjunct - [m.yCF[1] == m.CF[1], - exp(m.flow[3]) - 1 == m.flow[2], - m.flow[4] == 0, - m.flow[5] == 0], + [ + m.yCF[1] == m.CF[1], + exp(m.flow[3]) - 1 == m.flow[2], + m.flow[4] == 0, + m.flow[5] == 0, + ], # use unit 2 disjunct - [m.yCF[2] == m.CF[2], - exp(m.flow[5] / 1.2) - 1 == m.flow[4], - m.flow[2] == 0, - m.flow[3] == 0] - ]) + [ + m.yCF[2] == m.CF[2], + exp(m.flow[5] / 1.2) - 1 == m.flow[4], + m.flow[2] == 0, + m.flow[3] == 0, + ], + ] + ) m.use_unit_3ornot = Disjunction( expr=[ # Use unit 3 disjunct - [m.yCF[3] == m.CF[3], - 1.5 * m.flow[9] + m.flow[10] == m.flow[8]], + [m.yCF[3] == m.CF[3], 1.5 * m.flow[9] + m.flow[10] == m.flow[8]], # No unit 3 disjunct - [m.flow[9] == 0, - m.flow[10] == m.flow[8]] - ]) + [m.flow[9] == 0, m.flow[10] == m.flow[8]], + ] + ) m.use_unit_4or5ornot = Disjunction( expr=[ # Use unit 4 disjunct - [m.yCF[4] == m.CF[4], - 1.25 * (m.flow[12] + m.flow[14]) == m.flow[13], - m.flow[15] == 0], + [ + m.yCF[4] == m.CF[4], + 1.25 * (m.flow[12] + m.flow[14]) == m.flow[13], + m.flow[15] == 0, + ], # Use unit 5 disjunct - [m.yCF[5] == m.CF[5], - m.flow[15] == 2 * m.flow[16], - m.flow[12] == 0, - m.flow[14] == 0], + [ + m.yCF[5] == m.CF[5], + m.flow[15] == 2 * m.flow[16], + m.flow[12] == 0, + m.flow[14] == 0, + ], # No unit 4 or 5 disjunct - [m.flow[15] == 0, - m.flow[12] == 0, - m.flow[14] == 0] - ]) + [m.flow[15] == 0, m.flow[12] == 0, m.flow[14] == 0], + ] + ) m.use_unit_6or7ornot = Disjunction( expr=[ # use unit 6 disjunct - [m.yCF[6] == m.CF[6], - exp(m.flow[20] / 1.5) - 1 == m.flow[19], - m.flow[21] == 0, - m.flow[22] == 0], - # use unit 7 disjunct - [m.yCF[7] == m.CF[7], - exp(m.flow[22]) - 1 == m.flow[21], - m.flow[19] == 0, - m.flow[20] == 0], - # No unit 6 or 7 disjunct - [m.flow[21] == 0, + [ + m.yCF[6] == m.CF[6], + exp(m.flow[20] / 1.5) - 1 == m.flow[19], + m.flow[21] == 0, m.flow[22] == 0, + ], + # use unit 7 disjunct + [ + m.yCF[7] == m.CF[7], + exp(m.flow[22]) - 1 == m.flow[21], m.flow[19] == 0, - m.flow[20] == 0] - ]) + m.flow[20] == 0, + ], + # No unit 6 or 7 disjunct + [m.flow[21] == 0, m.flow[22] == 0, m.flow[19] == 0, m.flow[20] == 0], + ] + ) m.use_unit_8ornot = Disjunction( expr=[ # use unit 8 disjunct - [m.yCF[8] == m.CF[8], - exp(m.flow[18]) - 1 == m.flow[10] + m.flow[17]], + [m.yCF[8] == m.CF[8], exp(m.flow[18]) - 1 == m.flow[10] + m.flow[17]], # no unit 8 disjunct - [m.flow[10] == 0, - m.flow[17] == 0, - m.flow[18] == 0] - ]) + [m.flow[10] == 0, m.flow[17] == 0, m.flow[18] == 0], + ] + ) # Mass balance equations m.massbal1 = Constraint(expr=m.flow[13] == m.flow[19] + m.flow[21]) - m.massbal2 = Constraint( - expr=m.flow[17] == m.flow[9] + m.flow[16] + m.flow[25]) + m.massbal2 = Constraint(expr=m.flow[17] == m.flow[9] + m.flow[16] + m.flow[25]) m.massbal3 = Constraint(expr=m.flow[11] == m.flow[12] + m.flow[15]) - m.massbal4 = Constraint( - expr=m.flow[3] + m.flow[5] == m.flow[6] + m.flow[11]) + m.massbal4 = Constraint(expr=m.flow[3] + m.flow[5] == m.flow[6] + m.flow[11]) m.massbal5 = Constraint(expr=m.flow[6] == m.flow[7] + m.flow[8]) m.massbal6 = Constraint(expr=m.flow[23] == m.flow[20] + m.flow[22]) m.massbal7 = Constraint(expr=m.flow[23] == m.flow[14] + m.flow[24]) @@ -154,20 +197,24 @@ def fixed_cost_bounds(m, unit): # pure integer constraints m.use4implies6or7 = Constraint( - expr=m.use_unit_6or7ornot.disjuncts[0].binary_indicator_var + - m.use_unit_6or7ornot.disjuncts[1].binary_indicator_var - - m.use_unit_4or5ornot.disjuncts[0].binary_indicator_var == 0) + expr=m.use_unit_6or7ornot.disjuncts[0].binary_indicator_var + + m.use_unit_6or7ornot.disjuncts[1].binary_indicator_var + - m.use_unit_4or5ornot.disjuncts[0].binary_indicator_var + == 0 + ) m.use3implies8 = Constraint( expr=m.use_unit_3ornot.disjuncts[0].binary_indicator_var - - m.use_unit_8ornot.disjuncts[0].binary_indicator_var <= 0) + - m.use_unit_8ornot.disjuncts[0].binary_indicator_var + <= 0 + ) """Profit (objective) function definition""" - m.profit = Objective(expr=sum( - m.yCF[unit] - for unit in m.units) + - sum(m.flow[stream] * CV[stream] - for stream in m.streams) + CONSTANT, - sense=minimize) + m.profit = Objective( + expr=sum(m.yCF[unit] for unit in m.units) + + sum(m.flow[stream] * CV[stream] for stream in m.streams) + + CONSTANT, + sense=minimize, + ) """Bound definitions""" # x (flow) upper bounds diff --git a/examples/gdp/eight_process/eight_proc_verbose_model.py b/examples/gdp/eight_process/eight_proc_verbose_model.py index d26d484b461..78da347e564 100644 --- a/examples/gdp/eight_process/eight_proc_verbose_model.py +++ b/examples/gdp/eight_process/eight_proc_verbose_model.py @@ -6,8 +6,17 @@ """ from __future__ import division -from pyomo.environ import (ConcreteModel, Constraint, NonNegativeReals, - Objective, Param, RangeSet, Var, exp, minimize) +from pyomo.environ import ( + ConcreteModel, + Constraint, + NonNegativeReals, + Objective, + Param, + RangeSet, + Var, + exp, + minimize, +) from pyomo.gdp import Disjunct, Disjunction @@ -27,20 +36,48 @@ def build_eight_process_flowsheet(): # VARIABLE COST COEFF FOR PROCESS UNITS - STREAMS # Format: stream #: cost - variable_cost = {3: -10, 5: -15, 9: -40, 19: 25, 21: 35, 25: -35, - 17: 80, 14: 15, 10: 15, 2: 1, 4: 1, 18: -65, 20: -60, - 22: -80} + variable_cost = { + 3: -10, + 5: -15, + 9: -40, + 19: 25, + 21: 35, + 25: -35, + 17: 80, + 14: 15, + 10: 15, + 2: 1, + 4: 1, + 18: -65, + 20: -60, + 22: -80, + } CV = m.CV = Param(m.streams, initialize=variable_cost, default=0) # initial point information for stream flows - initX = {2: 2, 3: 1.5, 6: 0.75, 7: 0.5, 8: 0.5, 9: 0.75, 11: 1.5, - 12: 1.34, 13: 2, 14: 2.5, 17: 2, 18: 0.75, 19: 2, 20: 1.5, - 23: 1.7, 24: 1.5, 25: 0.5} + initX = { + 2: 2, + 3: 1.5, + 6: 0.75, + 7: 0.5, + 8: 0.5, + 9: 0.75, + 11: 1.5, + 12: 1.34, + 13: 2, + 14: 2.5, + 17: 2, + 18: 0.75, + 19: 2, + 20: 1.5, + 23: 1.7, + 24: 1.5, + 25: 0.5, + } """Variable declarations""" # FLOWRATES OF PROCESS STREAMS - m.flow = Var(m.streams, domain=NonNegativeReals, initialize=initX, - bounds=(0, 10)) + m.flow = Var(m.streams, domain=NonNegativeReals, initialize=initX, bounds=(0, 10)) # OBJECTIVE FUNCTION CONSTANT TERM CONSTANT = m.constant = Param(initialize=122.0) @@ -51,21 +88,18 @@ def build_eight_process_flowsheet(): m.use_unit1.no_unit2_flow1 = Constraint(expr=m.flow[4] == 0) m.use_unit1.no_unit2_flow2 = Constraint(expr=m.flow[5] == 0) m.use_unit2 = Disjunct() - m.use_unit2.inout2 = Constraint( - expr=exp(m.flow[5] / 1.2) - 1 == m.flow[4]) + m.use_unit2.inout2 = Constraint(expr=exp(m.flow[5] / 1.2) - 1 == m.flow[4]) m.use_unit2.no_unit1_flow1 = Constraint(expr=m.flow[2] == 0) m.use_unit2.no_unit1_flow2 = Constraint(expr=m.flow[3] == 0) m.use_unit3 = Disjunct() - m.use_unit3.inout3 = Constraint( - expr=1.5 * m.flow[9] + m.flow[10] == m.flow[8]) + m.use_unit3.inout3 = Constraint(expr=1.5 * m.flow[9] + m.flow[10] == m.flow[8]) m.no_unit3 = Disjunct() m.no_unit3.no_unit3_flow1 = Constraint(expr=m.flow[9] == 0) m.no_unit3.flow_pass_through = Constraint(expr=m.flow[10] == m.flow[8]) m.use_unit4 = Disjunct() - m.use_unit4.inout4 = Constraint( - expr=1.25 * (m.flow[12] + m.flow[14]) == m.flow[13]) + m.use_unit4.inout4 = Constraint(expr=1.25 * (m.flow[12] + m.flow[14]) == m.flow[13]) m.use_unit4.no_unit5_flow = Constraint(expr=m.flow[15] == 0) m.use_unit5 = Disjunct() m.use_unit5.inout5 = Constraint(expr=m.flow[15] == 2 * m.flow[16]) @@ -77,8 +111,7 @@ def build_eight_process_flowsheet(): m.no_unit4or5.no_unit4_flow2 = Constraint(expr=m.flow[14] == 0) m.use_unit6 = Disjunct() - m.use_unit6.inout6 = Constraint( - expr=exp(m.flow[20] / 1.5) - 1 == m.flow[19]) + m.use_unit6.inout6 = Constraint(expr=exp(m.flow[20] / 1.5) - 1 == m.flow[19]) m.use_unit6.no_unit7_flow1 = Constraint(expr=m.flow[21] == 0) m.use_unit6.no_unit7_flow2 = Constraint(expr=m.flow[22] == 0) m.use_unit7 = Disjunct() @@ -92,8 +125,7 @@ def build_eight_process_flowsheet(): m.no_unit6or7.no_unit6_flow2 = Constraint(expr=m.flow[20] == 0) m.use_unit8 = Disjunct() - m.use_unit8.inout8 = Constraint( - expr=exp(m.flow[18]) - 1 == m.flow[10] + m.flow[17]) + m.use_unit8.inout8 = Constraint(expr=exp(m.flow[18]) - 1 == m.flow[10] + m.flow[17]) m.no_unit8 = Disjunct() m.no_unit8.no_unit8_flow1 = Constraint(expr=m.flow[10] == 0) m.no_unit8.no_unit8_flow2 = Constraint(expr=m.flow[17] == 0) @@ -101,11 +133,9 @@ def build_eight_process_flowsheet(): # Mass balance equations m.massbal1 = Constraint(expr=m.flow[13] == m.flow[19] + m.flow[21]) - m.massbal2 = Constraint( - expr=m.flow[17] == m.flow[9] + m.flow[16] + m.flow[25]) + m.massbal2 = Constraint(expr=m.flow[17] == m.flow[9] + m.flow[16] + m.flow[25]) m.massbal3 = Constraint(expr=m.flow[11] == m.flow[12] + m.flow[15]) - m.massbal4 = Constraint( - expr=m.flow[3] + m.flow[5] == m.flow[6] + m.flow[11]) + m.massbal4 = Constraint(expr=m.flow[3] + m.flow[5] == m.flow[6] + m.flow[11]) m.massbal5 = Constraint(expr=m.flow[6] == m.flow[7] + m.flow[8]) m.massbal6 = Constraint(expr=m.flow[23] == m.flow[20] + m.flow[22]) m.massbal7 = Constraint(expr=m.flow[23] == m.flow[14] + m.flow[24]) @@ -118,29 +148,36 @@ def build_eight_process_flowsheet(): # pure integer constraints m.use1or2 = Disjunction(expr=[m.use_unit1, m.use_unit2]) - m.use4or5maybe = Disjunction( - expr=[m.use_unit4, m.use_unit5, m.no_unit4or5]) + m.use4or5maybe = Disjunction(expr=[m.use_unit4, m.use_unit5, m.no_unit4or5]) m.use4or5 = Constraint( - expr=m.use_unit4.indicator_var + m.use_unit5.indicator_var <= 1) - m.use6or7maybe = Disjunction( - expr=[m.use_unit6, m.use_unit7, m.no_unit6or7]) + expr=m.use_unit4.indicator_var + m.use_unit5.indicator_var <= 1 + ) + m.use6or7maybe = Disjunction(expr=[m.use_unit6, m.use_unit7, m.no_unit6or7]) m.use4implies6or7 = Constraint( - expr=m.use_unit6.indicator_var + m.use_unit7.indicator_var - - m.use_unit4.indicator_var == 0) + expr=m.use_unit6.indicator_var + + m.use_unit7.indicator_var + - m.use_unit4.indicator_var + == 0 + ) m.use3maybe = Disjunction(expr=[m.use_unit3, m.no_unit3]) m.either3ornot = Constraint( - expr=m.use_unit3.indicator_var + m.no_unit3.indicator_var == 1) + expr=m.use_unit3.indicator_var + m.no_unit3.indicator_var == 1 + ) m.use8maybe = Disjunction(expr=[m.use_unit8, m.no_unit8]) m.use3implies8 = Constraint( - expr=m.use_unit3.indicator_var - m.use_unit8.indicator_var <= 0) + expr=m.use_unit3.indicator_var - m.use_unit8.indicator_var <= 0 + ) """Profit (objective) function definition""" - m.profit = Objective(expr=sum( - getattr(m, 'use_unit%s' % (unit,)).indicator_var * CF[unit] - for unit in m.units) + - sum(m.flow[stream] * CV[stream] - for stream in m.streams) + CONSTANT, - sense=minimize) + m.profit = Objective( + expr=sum( + getattr(m, 'use_unit%s' % (unit,)).indicator_var * CF[unit] + for unit in m.units + ) + + sum(m.flow[stream] * CV[stream] for stream in m.streams) + + CONSTANT, + sense=minimize, + ) """Bound definitions""" # x (flow) upper bounds diff --git a/examples/gdp/jobshop-nodisjuncts.py b/examples/gdp/jobshop-nodisjuncts.py index 92bb76ff860..34fd0b3fef3 100644 --- a/examples/gdp/jobshop-nodisjuncts.py +++ b/examples/gdp/jobshop-nodisjuncts.py @@ -30,12 +30,13 @@ # Aldo Vecchietti, LogMIP User's Manual, http://www.logmip.ceride.gov.ar/, 2007 # + def build_model(): model = AbstractModel() model.JOBS = Set(ordered=True) model.STAGES = Set(ordered=True) - model.I_BEFORE_K = RangeSet(0,1) + model.I_BEFORE_K = RangeSet(0, 1) # Task durations model.tau = Param(model.JOBS, model.STAGES, default=0) @@ -45,25 +46,30 @@ def build_model(): # Start time of each job def t_bounds(model, I): return (0, sum(value(model.tau[idx]) for idx in model.tau)) - model.t = Var( model.JOBS, within=NonNegativeReals, bounds=t_bounds ) + + model.t = Var(model.JOBS, within=NonNegativeReals, bounds=t_bounds) # Auto-generate the L set (potential collisions between 2 jobs at any stage. def _L_filter(model, I, K, J): - return I < K and model.tau[I,J] and model.tau[K,J] - model.L = Set( initialize=model.JOBS * model.JOBS * model.STAGES, - dimen=3, filter=_L_filter) + return I < K and model.tau[I, J] and model.tau[K, J] + + model.L = Set( + initialize=model.JOBS * model.JOBS * model.STAGES, dimen=3, filter=_L_filter + ) # Makespan is greater than the start time of every job + that job's # total duration def _feas(model, I): - return model.ms >= model.t[I] + sum(model.tau[I,M] for M in model.STAGES) + return model.ms >= model.t[I] + sum(model.tau[I, M] for M in model.STAGES) + model.Feas = Constraint(model.JOBS, rule=_feas) # Define the disjunctions: either job I occurs before K or K before I def _disj(model, I, K, J): - lhs = model.t[I] + sum([M= model.t[I] + sum(model.tau[I,M] for M in model.STAGES) + return model.ms >= model.t[I] + sum(model.tau[I, M] for M in model.STAGES) + model.Feas = Constraint(model.JOBS, rule=_feas) # Disjunctions to prevent clashes at a stage: This creates a set of @@ -64,17 +69,19 @@ def _feas(model, I): # K occurs before job I. def _NoClash(disjunct, I, K, J, IthenK): model = disjunct.model() - lhs = model.t[I] + sum([M= model.DemandLB[j,t] - model.demand_LB = Constraint(model.Products, model.TimePeriods, rule=demand_LB_rule) + return model.FlowRate[j, t] >= model.DemandLB[j, t] + model.demand_LB = Constraint(model.Products, model.TimePeriods, rule=demand_LB_rule) # FIXED PRICE CONTRACT @@ -439,25 +550,36 @@ def demand_LB_rule(model, j, t): def FP_contract_disjunct_rule(disjunct, j, t, buy): model = disjunct.model() if buy: - disjunct.c = Constraint(expr=model.AmountPurchased_FP[j,t] <= MAX_AMOUNT_FP) + disjunct.c = Constraint( + expr=model.AmountPurchased_FP[j, t] <= MAX_AMOUNT_FP + ) else: - disjunct.c = Constraint(expr=model.AmountPurchased_FP[j,t] == 0) - model.FP_contract_disjunct = Disjunct(model.RawMaterials, model.TimePeriods, - model.BuyFPContract, rule=FP_contract_disjunct_rule) + disjunct.c = Constraint(expr=model.AmountPurchased_FP[j, t] == 0) + + model.FP_contract_disjunct = Disjunct( + model.RawMaterials, + model.TimePeriods, + model.BuyFPContract, + rule=FP_contract_disjunct_rule, + ) # Fixed price disjunction def FP_contract_rule(model, j, t): - return [model.FP_contract_disjunct[j,t,buy] for buy in model.BuyFPContract] - model.FP_disjunction = Disjunction(model.RawMaterials, model.TimePeriods, - rule=FP_contract_rule) + return [model.FP_contract_disjunct[j, t, buy] for buy in model.BuyFPContract] + + model.FP_disjunction = Disjunction( + model.RawMaterials, model.TimePeriods, rule=FP_contract_rule + ) # cost constraint for fixed price contract (independent contraint) def FP_contract_cost_rule(model, j, t): - return model.Cost_FP[j,t] == model.AmountPurchased_FP[j,t] * \ - model.Prices[j,t] - model.FP_contract_cost = Constraint(model.RawMaterials, model.TimePeriods, - rule=FP_contract_cost_rule) + return ( + model.Cost_FP[j, t] == model.AmountPurchased_FP[j, t] * model.Prices[j, t] + ) + model.FP_contract_cost = Constraint( + model.RawMaterials, model.TimePeriods, rule=FP_contract_cost_rule + ) # DISCOUNT CONTRACT @@ -466,41 +588,61 @@ def discount_contract_disjunct_rule(disjunct, j, t, buy): model = disjunct.model() if buy == 'BelowMin': disjunct.belowMin = Constraint( - expr=model.AmountPurchasedBelowMin_Discount[j,t] <= \ - model.MinAmount_Discount[j,t]) + expr=model.AmountPurchasedBelowMin_Discount[j, t] + <= model.MinAmount_Discount[j, t] + ) disjunct.aboveMin = Constraint( - expr=model.AmountPurchasedAboveMin_Discount[j,t] == 0) + expr=model.AmountPurchasedAboveMin_Discount[j, t] == 0 + ) elif buy == 'AboveMin': disjunct.belowMin = Constraint( - expr=model.AmountPurchasedBelowMin_Discount[j,t] == \ - model.MinAmount_Discount[j,t]) + expr=model.AmountPurchasedBelowMin_Discount[j, t] + == model.MinAmount_Discount[j, t] + ) disjunct.aboveMin = Constraint( - expr=model.AmountPurchasedAboveMin_Discount[j,t] >= 0) + expr=model.AmountPurchasedAboveMin_Discount[j, t] >= 0 + ) elif buy == 'NotSelected': disjunct.belowMin = Constraint( - expr=model.AmountPurchasedBelowMin_Discount[j,t] == 0) + expr=model.AmountPurchasedBelowMin_Discount[j, t] == 0 + ) disjunct.aboveMin = Constraint( - expr=model.AmountPurchasedAboveMin_Discount[j,t] == 0) + expr=model.AmountPurchasedAboveMin_Discount[j, t] == 0 + ) else: raise RuntimeError("Unrecognized choice for discount contract: %s" % buy) - model.discount_contract_disjunct = Disjunct(model.RawMaterials, model.TimePeriods, - model.BuyDiscountContract, rule=discount_contract_disjunct_rule) + + model.discount_contract_disjunct = Disjunct( + model.RawMaterials, + model.TimePeriods, + model.BuyDiscountContract, + rule=discount_contract_disjunct_rule, + ) # Discount contract disjunction def discount_contract_rule(model, j, t): - return [model.discount_contract_disjunct[j,t,buy] \ - for buy in model.BuyDiscountContract] - model.discount_contract = Disjunction(model.RawMaterials, model.TimePeriods, - rule=discount_contract_rule) + return [ + model.discount_contract_disjunct[j, t, buy] + for buy in model.BuyDiscountContract + ] + + model.discount_contract = Disjunction( + model.RawMaterials, model.TimePeriods, rule=discount_contract_rule + ) # cost constraint for discount contract (independent constraint) def discount_cost_rule(model, j, t): - return model.Cost_Discount[j,t] == model.RegPrice_Discount[j,t] * \ - model.AmountPurchasedBelowMin_Discount[j,t] + \ - model.DiscountPrice_Discount[j,t] * model.AmountPurchasedAboveMin_Discount[j,t] - model.discount_cost = Constraint(model.RawMaterials, model.TimePeriods, - rule=discount_cost_rule) - + return ( + model.Cost_Discount[j, t] + == model.RegPrice_Discount[j, t] + * model.AmountPurchasedBelowMin_Discount[j, t] + + model.DiscountPrice_Discount[j, t] + * model.AmountPurchasedAboveMin_Discount[j, t] + ) + + model.discount_cost = Constraint( + model.RawMaterials, model.TimePeriods, rule=discount_cost_rule + ) # BULK CONTRACT @@ -509,98 +651,142 @@ def bulk_contract_disjunct_rule(disjunct, j, t, buy): model = disjunct.model() if buy == 'BelowMin': disjunct.amount = Constraint( - expr=model.AmountPurchased_Bulk[j,t] <= model.MinAmount_Bulk[j,t]) + expr=model.AmountPurchased_Bulk[j, t] <= model.MinAmount_Bulk[j, t] + ) disjunct.price = Constraint( - expr=model.Cost_Bulk[j,t] == model.RegPrice_Bulk[j,t] * \ - model.AmountPurchased_Bulk[j,t]) + expr=model.Cost_Bulk[j, t] + == model.RegPrice_Bulk[j, t] * model.AmountPurchased_Bulk[j, t] + ) elif buy == 'AboveMin': disjunct.amount = Constraint( - expr=model.AmountPurchased_Bulk[j,t] >= model.MinAmount_Bulk[j,t]) + expr=model.AmountPurchased_Bulk[j, t] >= model.MinAmount_Bulk[j, t] + ) disjunct.price = Constraint( - expr=model.Cost_Bulk[j,t] == model.DiscountPrice_Bulk[j,t] * \ - model.AmountPurchased_Bulk[j,t]) + expr=model.Cost_Bulk[j, t] + == model.DiscountPrice_Bulk[j, t] * model.AmountPurchased_Bulk[j, t] + ) elif buy == 'NotSelected': - disjunct.amount = Constraint(expr=model.AmountPurchased_Bulk[j,t] == 0) - disjunct.price = Constraint(expr=model.Cost_Bulk[j,t] == 0) + disjunct.amount = Constraint(expr=model.AmountPurchased_Bulk[j, t] == 0) + disjunct.price = Constraint(expr=model.Cost_Bulk[j, t] == 0) else: raise RuntimeError("Unrecognized choice for bulk contract: %s" % buy) - model.bulk_contract_disjunct = Disjunct(model.RawMaterials, model.TimePeriods, - model.BuyBulkContract, rule=bulk_contract_disjunct_rule) + + model.bulk_contract_disjunct = Disjunct( + model.RawMaterials, + model.TimePeriods, + model.BuyBulkContract, + rule=bulk_contract_disjunct_rule, + ) # Bulk contract disjunction def bulk_contract_rule(model, j, t): - return [model.bulk_contract_disjunct[j,t,buy] for buy in model.BuyBulkContract] - model.bulk_contract = Disjunction(model.RawMaterials, model.TimePeriods, - rule=bulk_contract_rule) + return [ + model.bulk_contract_disjunct[j, t, buy] for buy in model.BuyBulkContract + ] + model.bulk_contract = Disjunction( + model.RawMaterials, model.TimePeriods, rule=bulk_contract_rule + ) # FIXED DURATION CONTRACT def FD_1mo_contract(disjunct, j, t): - model = disjunct.model() - disjunct.amount1 = Constraint(expr=model.AmountPurchased_FD[j,t] >= \ - MIN_AMOUNT_FD_1MONTH) - disjunct.price1 = Constraint(expr=model.Cost_FD[j,t] == \ - model.Prices_Length[j,1,t] * model.AmountPurchased_FD[j,t]) + model = disjunct.model() + disjunct.amount1 = Constraint( + expr=model.AmountPurchased_FD[j, t] >= MIN_AMOUNT_FD_1MONTH + ) + disjunct.price1 = Constraint( + expr=model.Cost_FD[j, t] + == model.Prices_Length[j, 1, t] * model.AmountPurchased_FD[j, t] + ) + model.FD_1mo_contract = Disjunct( - model.RawMaterials, model.TimePeriods, rule=FD_1mo_contract) + model.RawMaterials, model.TimePeriods, rule=FD_1mo_contract + ) def FD_2mo_contract(disjunct, j, t): - model = disjunct.model() - disjunct.amount1 = Constraint(expr=model.AmountPurchased_FD[j,t] >= \ - model.MinAmount_Length[j,2]) - disjunct.price1 = Constraint(expr=model.Cost_FD[j,t] == \ - model.Prices_Length[j,2,t] * model.AmountPurchased_FD[j,t]) - # only enforce these if we aren't in the last time period - if t < model.TimePeriods[-1]: - disjunct.amount2 = Constraint(expr=model.AmountPurchased_FD[j, t+1] >= \ - model.MinAmount_Length[j,2]) - disjunct.price2 = Constraint(expr=model.Cost_FD[j,t+1] == \ - model.Prices_Length[j,2,t] * model.AmountPurchased_FD[j, t+1]) + model = disjunct.model() + disjunct.amount1 = Constraint( + expr=model.AmountPurchased_FD[j, t] >= model.MinAmount_Length[j, 2] + ) + disjunct.price1 = Constraint( + expr=model.Cost_FD[j, t] + == model.Prices_Length[j, 2, t] * model.AmountPurchased_FD[j, t] + ) + # only enforce these if we aren't in the last time period + if t < model.TimePeriods[-1]: + disjunct.amount2 = Constraint( + expr=model.AmountPurchased_FD[j, t + 1] >= model.MinAmount_Length[j, 2] + ) + disjunct.price2 = Constraint( + expr=model.Cost_FD[j, t + 1] + == model.Prices_Length[j, 2, t] * model.AmountPurchased_FD[j, t + 1] + ) + model.FD_2mo_contract = Disjunct( - model.RawMaterials, model.TimePeriods, rule=FD_2mo_contract) + model.RawMaterials, model.TimePeriods, rule=FD_2mo_contract + ) def FD_3mo_contract(disjunct, j, t): - model = disjunct.model() - # NOTE: I think there is a mistake in the GAMS file in line 327. - # they use the bulk minamount rather than the length one. - #I am doing the same here for validation purposes. - disjunct.amount1 = Constraint(expr=model.AmountPurchased_FD[j,t] >= \ - model.MinAmount_Bulk[j,3]) - disjunct.cost1 = Constraint(expr=model.Cost_FD[j,t] == \ - model.Prices_Length[j,3,t] * model.AmountPurchased_FD[j,t]) - # check we aren't in one of the last two time periods - if t < model.TimePeriods[-1]: - disjunct.amount2 = Constraint(expr=model.AmountPurchased_FD[j,t+1] >= \ - model.MinAmount_Length[j,3]) - disjunct.cost2 = Constraint(expr=model.Cost_FD[j,t+1] == \ - model.Prices_Length[j,3,t] * model.AmountPurchased_FD[j,t+1]) - if t < model.TimePeriods[-2]: - disjunct.amount3 = Constraint(expr=model.AmountPurchased_FD[j,t+2] >= \ - model.MinAmount_Length[j,3]) - disjunct.cost3 = Constraint(expr=model.Cost_FD[j,t+2] == \ - model.Prices_Length[j,3,t] * model.AmountPurchased_FD[j,t+2]) + model = disjunct.model() + # NOTE: I think there is a mistake in the GAMS file in line 327. + # they use the bulk minamount rather than the length one. + # I am doing the same here for validation purposes. + disjunct.amount1 = Constraint( + expr=model.AmountPurchased_FD[j, t] >= model.MinAmount_Bulk[j, 3] + ) + disjunct.cost1 = Constraint( + expr=model.Cost_FD[j, t] + == model.Prices_Length[j, 3, t] * model.AmountPurchased_FD[j, t] + ) + # check we aren't in one of the last two time periods + if t < model.TimePeriods[-1]: + disjunct.amount2 = Constraint( + expr=model.AmountPurchased_FD[j, t + 1] >= model.MinAmount_Length[j, 3] + ) + disjunct.cost2 = Constraint( + expr=model.Cost_FD[j, t + 1] + == model.Prices_Length[j, 3, t] * model.AmountPurchased_FD[j, t + 1] + ) + if t < model.TimePeriods[-2]: + disjunct.amount3 = Constraint( + expr=model.AmountPurchased_FD[j, t + 2] >= model.MinAmount_Length[j, 3] + ) + disjunct.cost3 = Constraint( + expr=model.Cost_FD[j, t + 2] + == model.Prices_Length[j, 3, t] * model.AmountPurchased_FD[j, t + 2] + ) + model.FD_3mo_contract = Disjunct( - model.RawMaterials, model.TimePeriods, rule=FD_3mo_contract) + model.RawMaterials, model.TimePeriods, rule=FD_3mo_contract + ) def FD_no_contract(disjunct, j, t): model = disjunct.model() - disjunct.amount1 = Constraint(expr=model.AmountPurchased_FD[j,t] == 0) - disjunct.cost1 = Constraint(expr=model.Cost_FD[j,t] == 0) + disjunct.amount1 = Constraint(expr=model.AmountPurchased_FD[j, t] == 0) + disjunct.cost1 = Constraint(expr=model.Cost_FD[j, t] == 0) if t < model.TimePeriods[-1]: - disjunct.amount2 = Constraint(expr=model.AmountPurchased_FD[j,t+1] == 0) - disjunct.cost2 = Constraint(expr=model.Cost_FD[j,t+1] == 0) + disjunct.amount2 = Constraint(expr=model.AmountPurchased_FD[j, t + 1] == 0) + disjunct.cost2 = Constraint(expr=model.Cost_FD[j, t + 1] == 0) if t < model.TimePeriods[-2]: - disjunct.amount3 = Constraint(expr=model.AmountPurchased_FD[j,t+2] == 0) - disjunct.cost3 = Constraint(expr=model.Cost_FD[j,t+2] == 0) + disjunct.amount3 = Constraint(expr=model.AmountPurchased_FD[j, t + 2] == 0) + disjunct.cost3 = Constraint(expr=model.Cost_FD[j, t + 2] == 0) + model.FD_no_contract = Disjunct( - model.RawMaterials, model.TimePeriods, rule=FD_no_contract) + model.RawMaterials, model.TimePeriods, rule=FD_no_contract + ) def FD_contract(model, j, t): - return [ model.FD_1mo_contract[j,t], model.FD_2mo_contract[j,t], - model.FD_3mo_contract[j,t], model.FD_no_contract[j,t], ] - model.FD_contract = Disjunction(model.RawMaterials, model.TimePeriods, - rule=FD_contract) + return [ + model.FD_1mo_contract[j, t], + model.FD_2mo_contract[j, t], + model.FD_3mo_contract[j, t], + model.FD_no_contract[j, t], + ] + + model.FD_contract = Disjunction( + model.RawMaterials, model.TimePeriods, rule=FD_contract + ) return model @@ -608,5 +794,7 @@ def FD_contract(model, j, t): if __name__ == "__main__": m = build_model().create_instance('medTermPurchasing_Literal_Hull.dat') TransformationFactory('gdp.bigm').apply_to(m) - SolverFactory('gams').solve(m, solver='baron', tee=True, add_options=['option optcr=1e-6;']) + SolverFactory('gams').solve( + m, solver='baron', tee=True, add_options=['option optcr=1e-6;'] + ) m.profit.display() diff --git a/examples/gdp/nine_process/small_process.py b/examples/gdp/nine_process/small_process.py index 38b45a7de41..7f96f32c65c 100644 --- a/examples/gdp/nine_process/small_process.py +++ b/examples/gdp/nine_process/small_process.py @@ -19,60 +19,78 @@ def build_model(): m.x = Var(m.streams, bounds=(0, 50), initialize=5) m.stage1_split = Constraint(expr=m.x[1] == m.x[2] + m.x[4]) - m.first_stage = Disjunction(expr=[ - [ - # Unit 1 - m.x[2] == exp(m.x[3]) - 1, - m.x[4] == 0, m.x[5] == 0 - ], - [ - # Unit 2 - m.x[5] == log(m.x[4] + 1), - m.x[2] == 0, m.x[3] == 0 + m.first_stage = Disjunction( + expr=[ + [ + # Unit 1 + m.x[2] == exp(m.x[3]) - 1, + m.x[4] == 0, + m.x[5] == 0, + ], + [ + # Unit 2 + m.x[5] == log(m.x[4] + 1), + m.x[2] == 0, + m.x[3] == 0, + ], ] - ]) + ) m.stage1_mix = Constraint(expr=m.x[3] + m.x[5] == m.x[6]) m.stage2_split = Constraint(expr=m.x[6] == sum(m.x[i] for i in (7, 9, 11, 13))) - m.second_stage = Disjunction(expr=[ - [ - # Unit 3 - m.x[8] == 2 * log(m.x[7]) + 3, - m.x[7] >= 0.2, - ] + [m.x[i] == 0 for i in (9, 10, 11, 12, 14, 15)], - [ - # Unit 4 - m.x[10] == 1.8 * log(m.x[9] + 4), - ] + [m.x[i] == 0 for i in (7, 8, 11, 12, 14, 15)], - [ - # Unit 5 - m.x[12] == 1.2 * log(m.x[11]) + 2, - m.x[11] >= 0.001, - ] + [m.x[i] == 0 for i in (7, 8, 9, 10, 14, 15)], - [ - # Unit 6 - m.x[15] == sqrt(m.x[14] - 3) * m.x[23] + 1, - m.x[14] >= 5, m.x[14] <= 20, - ] + [m.x[i] == 0 for i in (7, 8, 9, 10, 11, 12)] - ]) + m.second_stage = Disjunction( + expr=[ + [ + # Unit 3 + m.x[8] == 2 * log(m.x[7]) + 3, + m.x[7] >= 0.2, + ] + + [m.x[i] == 0 for i in (9, 10, 11, 12, 14, 15)], + [ + # Unit 4 + m.x[10] + == 1.8 * log(m.x[9] + 4) + ] + + [m.x[i] == 0 for i in (7, 8, 11, 12, 14, 15)], + [ + # Unit 5 + m.x[12] == 1.2 * log(m.x[11]) + 2, + m.x[11] >= 0.001, + ] + + [m.x[i] == 0 for i in (7, 8, 9, 10, 14, 15)], + [ + # Unit 6 + m.x[15] == sqrt(m.x[14] - 3) * m.x[23] + 1, + m.x[14] >= 5, + m.x[14] <= 20, + ] + + [m.x[i] == 0 for i in (7, 8, 9, 10, 11, 12)], + ] + ) m.stage2_special_mix = Constraint(expr=m.x[14] == m.x[13] + m.x[23]) m.stage2_mix = Constraint(expr=sum(m.x[i] for i in (8, 10, 12, 15)) == m.x[16]) m.stage3_split = Constraint(expr=m.x[16] == sum(m.x[i] for i in (17, 19, 21))) - m.third_stage = Disjunction(expr=[ - [ - # Unit 7 - m.x[18] == m.x[17] * 0.9, - ] + [m.x[i] == 0 for i in (19, 20, 21, 22)], - [ - # Unit 8 - m.x[20] == log(m.x[19] ** 1.5) + 2, - m.x[19] >= 1, - ] + [m.x[i] == 0 for i in (17, 18, 21, 22)], - [ - # Unit 9 - m.x[22] == log(m.x[21] + sqrt(m.x[21])) + 1, - m.x[21] >= 4, - ] + [m.x[i] == 0 for i in (17, 18, 19, 20)] - ]) + m.third_stage = Disjunction( + expr=[ + [ + # Unit 7 + m.x[18] + == m.x[17] * 0.9 + ] + + [m.x[i] == 0 for i in (19, 20, 21, 22)], + [ + # Unit 8 + m.x[20] == log(m.x[19] ** 1.5) + 2, + m.x[19] >= 1, + ] + + [m.x[i] == 0 for i in (17, 18, 21, 22)], + [ + # Unit 9 + m.x[22] == log(m.x[21] + sqrt(m.x[21])) + 1, + m.x[21] >= 4, + ] + + [m.x[i] == 0 for i in (17, 18, 19, 20)], + ] + ) m.stage3_special_split = Constraint(expr=m.x[22] == m.x[23] + m.x[24]) m.stage3_mix = Constraint(expr=m.x[25] == sum(m.x[i] for i in (18, 20, 24))) @@ -87,106 +105,138 @@ def build_nonexclusive_model(): m.x = Var(m.streams, bounds=(0, 50), initialize=5) m.stage1_split = Constraint(expr=m.x[1] == m.x[2] + m.x[4]) - m.unit1 = Disjunction(expr=[ - [ - # Unit 1 - m.x[2] == exp(m.x[3]) - 1, - ], - [ - # No Unit 1 - m.x[2] == 0, m.x[3] == 0 + m.unit1 = Disjunction( + expr=[ + [ + # Unit 1 + m.x[2] + == exp(m.x[3]) - 1 + ], + [ + # No Unit 1 + m.x[2] == 0, + m.x[3] == 0, + ], ] - ]) - m.unit2 = Disjunction(expr=[ - [ - # Unit 2 - m.x[5] == log(m.x[4] + 1), - ], - [ - # No Unit 2 - m.x[4] == 0, m.x[5] == 0 + ) + m.unit2 = Disjunction( + expr=[ + [ + # Unit 2 + m.x[5] + == log(m.x[4] + 1) + ], + [ + # No Unit 2 + m.x[4] == 0, + m.x[5] == 0, + ], ] - ]) + ) m.stage1_mix = Constraint(expr=m.x[3] + m.x[5] == m.x[6]) m.stage2_split = Constraint(expr=m.x[6] == sum(m.x[i] for i in (7, 9, 11, 13))) - m.unit3 = Disjunction(expr=[ - [ - # Unit 3 - m.x[8] == 2 * log(m.x[7]) + 3, - m.x[7] >= 0.2, - ], - [ - # No Unit 3 - m.x[7] == 0, m.x[8] == 0 + m.unit3 = Disjunction( + expr=[ + [ + # Unit 3 + m.x[8] == 2 * log(m.x[7]) + 3, + m.x[7] >= 0.2, + ], + [ + # No Unit 3 + m.x[7] == 0, + m.x[8] == 0, + ], ] - ]) - m.unit4 = Disjunction(expr=[ - [ - # Unit 4 - m.x[10] == 1.8 * log(m.x[9] + 4), - ], - [ - # No Unit 4 - m.x[9] == 0, m.x[10] == 0 + ) + m.unit4 = Disjunction( + expr=[ + [ + # Unit 4 + m.x[10] + == 1.8 * log(m.x[9] + 4) + ], + [ + # No Unit 4 + m.x[9] == 0, + m.x[10] == 0, + ], ] - ]) - m.unit5 = Disjunction(expr=[ - [ - # Unit 5 - m.x[12] == 1.2 * log(m.x[11]) + 2, - m.x[11] >= 0.001, - ], - [ - # No Unit 5 - m.x[11] == 0, m.x[12] == 0 + ) + m.unit5 = Disjunction( + expr=[ + [ + # Unit 5 + m.x[12] == 1.2 * log(m.x[11]) + 2, + m.x[11] >= 0.001, + ], + [ + # No Unit 5 + m.x[11] == 0, + m.x[12] == 0, + ], ] - ]) - m.unit6 = Disjunction(expr=[ - [ - # Unit 6 - m.x[15] == sqrt(m.x[14] - 3) * m.x[23] + 1, - m.x[14] >= 5, m.x[14] <= 20, - ], - [ - # No Unit 6 - m.x[14] == 0, m.x[15] == 0 + ) + m.unit6 = Disjunction( + expr=[ + [ + # Unit 6 + m.x[15] == sqrt(m.x[14] - 3) * m.x[23] + 1, + m.x[14] >= 5, + m.x[14] <= 20, + ], + [ + # No Unit 6 + m.x[14] == 0, + m.x[15] == 0, + ], ] - ]) + ) m.stage2_special_mix = Constraint(expr=m.x[14] == m.x[13] + m.x[23]) m.stage2_mix = Constraint(expr=sum(m.x[i] for i in (8, 10, 12, 15)) == m.x[16]) m.stage3_split = Constraint(expr=m.x[16] == sum(m.x[i] for i in (17, 19, 21))) - m.unit7 = Disjunction(expr=[ - [ - # Unit 7 - m.x[18] == m.x[17] * 0.9, - ], - [ - # No Unit 7 - m.x[17] == 0, m.x[18] == 0 + m.unit7 = Disjunction( + expr=[ + [ + # Unit 7 + m.x[18] + == m.x[17] * 0.9 + ], + [ + # No Unit 7 + m.x[17] == 0, + m.x[18] == 0, + ], ] - ]) - m.unit8 = Disjunction(expr=[ - [ - # Unit 8 - m.x[20] == log(m.x[19] ** 1.5) + 2, - m.x[19] >= 1, - ], - [ - # No Unit 8 - m.x[19] == 0, m.x[20] == 0 + ) + m.unit8 = Disjunction( + expr=[ + [ + # Unit 8 + m.x[20] == log(m.x[19] ** 1.5) + 2, + m.x[19] >= 1, + ], + [ + # No Unit 8 + m.x[19] == 0, + m.x[20] == 0, + ], ] - ]) - m.unit9 = Disjunction(expr=[ - [ - # Unit 9 - m.x[22] == log(m.x[21] + sqrt(m.x[21])) + 1, - m.x[21] >= 4, - ], - [ - # No Unit 9 - m.x[21] == 0, m.x[22] == 0 + ) + m.unit9 = Disjunction( + expr=[ + [ + # Unit 9 + m.x[22] == log(m.x[21] + sqrt(m.x[21])) + 1, + m.x[21] >= 4, + ], + [ + # No Unit 9 + m.x[21] == 0, + m.x[22] == 0, + ], ] - ]) + ) m.stage3_special_split = Constraint(expr=m.x[22] == m.x[23] + m.x[24]) m.stage3_mix = Constraint(expr=m.x[25] == sum(m.x[i] for i in (18, 20, 24))) @@ -197,9 +247,11 @@ def build_nonexclusive_model(): if __name__ == '__main__': from pyomo.environ import SolverFactory + m = build_model() result = SolverFactory('gdpopt.gloa').solve( - m, tee=True, + m, + tee=True, mip_solver='gams', nlp_solver='gams', nlp_solver_args=dict(add_options=['option optcr=0.01;']), @@ -212,7 +264,8 @@ def build_nonexclusive_model(): m = build_nonexclusive_model() result = SolverFactory('gdpopt.gloa').solve( - m, tee=True, + m, + tee=True, mip_solver='gams', nlp_solver='gams', nlp_solver_args=dict(add_options=['option optcr=0.01;']), diff --git a/examples/gdp/simple1.py b/examples/gdp/simple1.py index 2073a5bc4f3..08a079898b5 100644 --- a/examples/gdp/simple1.py +++ b/examples/gdp/simple1.py @@ -1,4 +1,4 @@ -# Example: modeling a complementarity condition as a +# Example: modeling a complementarity condition as a # disjunction # # This model does not work with existing transformations. @@ -7,13 +7,14 @@ from pyomo.core import * from pyomo.gdp import * + def build_model(): model = ConcreteModel() # x >= 0 _|_ y>=0 - model.x = Var(bounds=(0,None)) - model.y = Var(bounds=(0,None)) + model.x = Var(bounds=(0, None)) + model.y = Var(bounds=(0, None)) # Two conditions def _d(disjunct, flag): @@ -24,14 +25,16 @@ def _d(disjunct, flag): else: # y == 0 disjunct.c = Constraint(expr=model.y == 0) - model.d = Disjunct([0,1], rule=_d) + + model.d = Disjunct([0, 1], rule=_d) # Define the disjunction def _c(model): return [model.d[0], model.d[1]] + model.c = Disjunction(rule=_c) - model.C = Constraint(expr=model.x+model.y <= 1) + model.C = Constraint(expr=model.x + model.y <= 1) - model.o = Objective(expr=2*model.x+3*model.y, sense=maximize) + model.o = Objective(expr=2 * model.x + 3 * model.y, sense=maximize) return model diff --git a/examples/gdp/simple2.py b/examples/gdp/simple2.py index fbb3ffa190c..6bcc7bbf747 100644 --- a/examples/gdp/simple2.py +++ b/examples/gdp/simple2.py @@ -1,4 +1,4 @@ -# Example: modeling a complementarity condition as a +# Example: modeling a complementarity condition as a # disjunction # # Specifying variable bounds @@ -6,12 +6,13 @@ from pyomo.core import * from pyomo.gdp import * + def build_model(): model = ConcreteModel() # x >= 0 _|_ y>=0 - model.x = Var(bounds=(0,100)) - model.y = Var(bounds=(0,100)) + model.x = Var(bounds=(0, 100)) + model.y = Var(bounds=(0, 100)) # Two conditions def _d(disjunct, flag): @@ -22,14 +23,16 @@ def _d(disjunct, flag): else: # y == 0 disjunct.c = Constraint(expr=model.y == 0) - model.d = Disjunct([0,1], rule=_d) + + model.d = Disjunct([0, 1], rule=_d) # Define the disjunction def _c(model): return [model.d[0], model.d[1]] + model.c = Disjunction(rule=_c) - model.C = Constraint(expr=model.x+model.y <= 1) + model.C = Constraint(expr=model.x + model.y <= 1) - model.o = Objective(expr=2*model.x+3*model.y, sense=maximize) - return model \ No newline at end of file + model.o = Objective(expr=2 * model.x + 3 * model.y, sense=maximize) + return model diff --git a/examples/gdp/simple3.py b/examples/gdp/simple3.py index 73dc27be6a2..6b3d6ec46c4 100644 --- a/examples/gdp/simple3.py +++ b/examples/gdp/simple3.py @@ -1,4 +1,4 @@ -# Example: modeling a complementarity condition as a +# Example: modeling a complementarity condition as a # disjunction # # Specifying BigM suffix values for the gdp.bigm transformation @@ -6,12 +6,13 @@ from pyomo.core import * from pyomo.gdp import * + def build_model(): model = ConcreteModel() # x >= 0 _|_ y>=0 - model.x = Var(bounds=(0,None)) - model.y = Var(bounds=(0,None)) + model.x = Var(bounds=(0, None)) + model.y = Var(bounds=(0, None)) # Two conditions def _d(disjunct, flag): @@ -24,15 +25,17 @@ def _d(disjunct, flag): disjunct.c = Constraint(expr=model.y == 0) disjunct.BigM = Suffix() disjunct.BigM[disjunct.c] = 1 - model.d = Disjunct([0,1], rule=_d) + + model.d = Disjunct([0, 1], rule=_d) # Define the disjunction def _c(model): return [model.d[0], model.d[1]] + model.c = Disjunction(rule=_c) - model.C = Constraint(expr=model.x+model.y <= 1) + model.C = Constraint(expr=model.x + model.y <= 1) - model.o = Objective(expr=2*model.x+3*model.y, sense=maximize) + model.o = Objective(expr=2 * model.x + 3 * model.y, sense=maximize) return model diff --git a/examples/gdp/small_lit/basic_step.py b/examples/gdp/small_lit/basic_step.py index 89cf0ffc0b0..2fd7a22d953 100644 --- a/examples/gdp/small_lit/basic_step.py +++ b/examples/gdp/small_lit/basic_step.py @@ -13,37 +13,51 @@ from pyomo.gdp import * from pyomo.gdp.basic_step import apply_basic_step + def build_gdp_model(): model = ConcreteModel() - model.x1 = Var(bounds=(-1,6), initialize=0) - model.x2 = Var(bounds=( 0,7), initialize=3.5) - - model.objective = Objective(expr=0.2*model.x1 + model.x2) - model.disjunction_set = RangeSet(1,3) - - model.disjuncts = Disjunct([1,2,3],[1,2]) - model.disjuncts[1,1].c = Constraint(expr=model.x1**2 + (1/4)*(model.x2 - 5)**2 <= 1) - model.disjuncts[2,1].c = Constraint(expr=model.x1**2 + (1/4)*(model.x2 - 2)**2 <= 1) - model.disjuncts[3,1].c = Constraint(expr=model.x1**2 + (1/4)*(model.x2 - 3.5)**2 <= 1) - - model.disjuncts[1,2].c = Constraint(expr=(model.x1 - 5)**2 + (1/4)*(model.x2 - 2)**2 <= 1) - model.disjuncts[2,2].c = Constraint(expr=(model.x1 - 5)**2 + (1/4)*(model.x2 - 5)**2 <= 1) - model.disjuncts[3,2].c = Constraint(expr=(model.x1 - 5)**2 + (1/4)*(model.x2 - 3.5)**2 <= 1) + model.x1 = Var(bounds=(-1, 6), initialize=0) + model.x2 = Var(bounds=(0, 7), initialize=3.5) + + model.objective = Objective(expr=0.2 * model.x1 + model.x2) + model.disjunction_set = RangeSet(1, 3) + + model.disjuncts = Disjunct([1, 2, 3], [1, 2]) + model.disjuncts[1, 1].c = Constraint( + expr=model.x1**2 + (1 / 4) * (model.x2 - 5) ** 2 <= 1 + ) + model.disjuncts[2, 1].c = Constraint( + expr=model.x1**2 + (1 / 4) * (model.x2 - 2) ** 2 <= 1 + ) + model.disjuncts[3, 1].c = Constraint( + expr=model.x1**2 + (1 / 4) * (model.x2 - 3.5) ** 2 <= 1 + ) + + model.disjuncts[1, 2].c = Constraint( + expr=(model.x1 - 5) ** 2 + (1 / 4) * (model.x2 - 2) ** 2 <= 1 + ) + model.disjuncts[2, 2].c = Constraint( + expr=(model.x1 - 5) ** 2 + (1 / 4) * (model.x2 - 5) ** 2 <= 1 + ) + model.disjuncts[3, 2].c = Constraint( + expr=(model.x1 - 5) ** 2 + (1 / 4) * (model.x2 - 3.5) ** 2 <= 1 + ) @model.Disjunction(model.disjunction_set, xor=True) - def disjunctions(model,i): - return [model.disjuncts[i,1], model.disjuncts[i,2]] + def disjunctions(model, i): + return [model.disjuncts[i, 1], model.disjuncts[i, 2]] return model + def solve_base_model(): m_base = build_gdp_model() m_hull = TransformationFactory('gdp.hull').create_using(m_base) - #m_bigm = TransformationFactory('gdp.bigm').create_using(m_base, bigM=100) + # m_bigm = TransformationFactory('gdp.bigm').create_using(m_base, bigM=100) solver = SolverFactory('gams') solver.solve(m_hull, solver='baron') - #m_hull.pprint() + # m_hull.pprint() m_hull.objective.display() m_hull.x1.display() m_hull.x2.display() @@ -51,13 +65,13 @@ def solve_base_model(): def solve_basic_step_model(): m_base = build_gdp_model() - m_base.BS = apply_basic_step([m_base.disjunctions[1],m_base.disjunctions[2]]) + m_base.BS = apply_basic_step([m_base.disjunctions[1], m_base.disjunctions[2]]) # crux to pprint component - #with open('pprint.log','w') as outputfile: + # with open('pprint.log','w') as outputfile: # m_base.disjunctions.pprint(outputfile) - #m_bs_hull = TransformationFactory('gdp.hull').create_using(m_base) + # m_bs_hull = TransformationFactory('gdp.hull').create_using(m_base) m_bigm = TransformationFactory('gdp.bigm').create_using(m_base, bigM=100) m_bigm.pprint() @@ -68,6 +82,7 @@ def solve_basic_step_model(): m_bigm.x1.display() m_bigm.x2.display() + if __name__ == '__main__': print('################################') print('[1] Sanity check: solving base model') diff --git a/examples/gdp/small_lit/contracts_problem.py b/examples/gdp/small_lit/contracts_problem.py index 3c80f4915c1..500fe15cb2a 100644 --- a/examples/gdp/small_lit/contracts_problem.py +++ b/examples/gdp/small_lit/contracts_problem.py @@ -13,9 +13,20 @@ from pyomo.core.expr.logical_expr import lor from pyomo.environ import ( - ConcreteModel, Constraint, Set, RangeSet, Param, - Objective, Var, NonNegativeReals, Block, - TransformationFactory, SolverFactory, LogicalConstraint, BooleanVar) + ConcreteModel, + Constraint, + Set, + RangeSet, + Param, + Objective, + Var, + NonNegativeReals, + Block, + TransformationFactory, + SolverFactory, + LogicalConstraint, + BooleanVar, +) from pyomo.gdp import Disjunct @@ -35,33 +46,45 @@ def build_model(): m.max_q_idx = RangeSet(m.T_max) # Randomly generated parameters - m.D = Param(m.T, doc='demand', - initialize=dict((t, randint(50, 100)) for t in m.T)) - m.alpha = Param(m.T, doc='storage cost', - initialize=dict((t, randint(5, 20)) for t in m.T)) - m.gamma = Param(m.T, doc='base buying cost', - initialize=dict((t, randint(10, 30)) for t in m.T)) - m.beta_B = Param(m.T, doc='bulk discount', - initialize=dict((t, randint(50, 500)/1000) for t in m.T)) - - m.F_B_lo = Param(m.T, doc='bulk minimum purchase amount', - initialize=dict((t, randint(50, 100)) for t in m.T)) - - m.beta_L = Param(m.T, m.max_q_idx, - initialize=dict(((t, q), randint(10, 999)/1000) - for t in m.T for q in m.max_q_idx), - doc='long-term discount') - m.F_L_lo = Param(m.T, m.max_q_idx, - initialize=dict(((t, q), randint(50, 100)) - for t in m.T for q in m.max_q_idx), - doc='long-term minimum purchase amount') + m.D = Param(m.T, doc='demand', initialize=dict((t, randint(50, 100)) for t in m.T)) + m.alpha = Param( + m.T, doc='storage cost', initialize=dict((t, randint(5, 20)) for t in m.T) + ) + m.gamma = Param( + m.T, doc='base buying cost', initialize=dict((t, randint(10, 30)) for t in m.T) + ) + m.beta_B = Param( + m.T, + doc='bulk discount', + initialize=dict((t, randint(50, 500) / 1000) for t in m.T), + ) + + m.F_B_lo = Param( + m.T, + doc='bulk minimum purchase amount', + initialize=dict((t, randint(50, 100)) for t in m.T), + ) + + m.beta_L = Param( + m.T, + m.max_q_idx, + initialize=dict( + ((t, q), randint(10, 999) / 1000) for t in m.T for q in m.max_q_idx + ), + doc='long-term discount', + ) + m.F_L_lo = Param( + m.T, + m.max_q_idx, + initialize=dict(((t, q), randint(50, 100)) for t in m.T for q in m.max_q_idx), + doc='long-term minimum purchase amount', + ) # Contract choices 'standard', 'bulk' and long term contracts '0','1',... time_time_choices = [(t1, str(t2)) for t1, t2 in m.T * m.T if t2 <= m.T_max - t1] time_special_choices = [(t, s) for t in m.T for s in {'S', 'B', '0'}] m.contract_time_choices = Set(initialize=time_time_choices + time_special_choices) - m.disjunct_choices = Set( - initialize=['S', 'B', *[str(t) for t in range(m.T_max)]]) + m.disjunct_choices = Set(initialize=['S', 'B', *[str(t) for t in range(m.T_max)]]) m.disjuncts = Disjunct(m.contract_time_choices) m.Y = BooleanVar(m.contract_time_choices) for t, c in m.contract_time_choices: @@ -69,45 +92,57 @@ def build_model(): # Create disjuncts for contracts in each timeset for t in m.T: - m.disjuncts[t, 'S'].cost = Constraint(expr=m.c[t] == m.gamma[t]*m.x[t]) + m.disjuncts[t, 'S'].cost = Constraint(expr=m.c[t] == m.gamma[t] * m.x[t]) m.disjuncts[t, 'B'].cost = Constraint( - expr=m.c[t] == (1-m.beta_B[t])*m.gamma[t]*m.x[t]) - m.disjuncts[t, 'B'].amount = Constraint( - expr=m.x[t] >= m.F_B_lo[t]) + expr=m.c[t] == (1 - m.beta_B[t]) * m.gamma[t] * m.x[t] + ) + m.disjuncts[t, 'B'].amount = Constraint(expr=m.x[t] >= m.F_B_lo[t]) m.disjuncts[t, '0'].c = Constraint(expr=0 <= m.c[t]) - for q in range(1, m.T_max-t+1): - m.disjuncts[t, str(q)].t_idx = RangeSet(t, t+q) + for q in range(1, m.T_max - t + 1): + m.disjuncts[t, str(q)].t_idx = RangeSet(t, t + q) m.disjuncts[t, str(q)].cost = Constraint(m.disjuncts[t, str(q)].t_idx) m.disjuncts[t, str(q)].amount = Constraint(m.disjuncts[t, str(q)].t_idx) for t_ in m.disjuncts[t, str(q)].t_idx: - m.disjuncts[t, str(q)].cost[t_] =\ - m.c[t_] == (1-m.beta_L[t, q])*m.gamma[t]*m.x[t_] - m.disjuncts[t, str(q)].amount[t_] =\ - m.x[t_] >= m.F_L_lo[t, q] + m.disjuncts[t, str(q)].cost[t_] = ( + m.c[t_] == (1 - m.beta_L[t, q]) * m.gamma[t] * m.x[t_] + ) + m.disjuncts[t, str(q)].amount[t_] = m.x[t_] >= m.F_L_lo[t, q] # Create disjunctions @m.Disjunction(m.T, xor=True) def disjunctions(m, t): - return [m.disjuncts[t, 'S'], m.disjuncts[t, 'B'], m.disjuncts[t, '0'], - *[m.disjuncts[t, str(q)] for q in range(1, m.T_max-t+1)]] + return [ + m.disjuncts[t, 'S'], + m.disjuncts[t, 'B'], + m.disjuncts[t, '0'], + *[m.disjuncts[t, str(q)] for q in range(1, m.T_max - t + 1)], + ] # Connect the disjuncts indicator variables using logical expressions - m.logical_blocks = Block(range(1, m.T_max+1)) + m.logical_blocks = Block(range(1, m.T_max + 1)) # Enforce absence of existing long-term contract - m.logical_blocks[1].not_y_1_0 = LogicalConstraint(expr=~m.Y[1, '0'], doc="no pre-existing long-term contract") + m.logical_blocks[1].not_y_1_0 = LogicalConstraint( + expr=~m.Y[1, '0'], doc="no pre-existing long-term contract" + ) # Long-term contract implies '0'-disjunct in following timesteps - for t in range(2, m.T_max+1): + for t in range(2, m.T_max + 1): m.logical_blocks[t].equiv = LogicalConstraint( - expr=m.Y[t, '0'].equivalent_to(lor(m.Y[t_, str(q)] for t_ in range(1, t) for q in range(t - t_, m.T_max - t_ + 1))) + expr=m.Y[t, '0'].equivalent_to( + lor( + m.Y[t_, str(q)] + for t_ in range(1, t) + for q in range(t - t_, m.T_max - t_ + 1) + ) + ) ) # Objective function - m.objective = Objective(expr=sum(m.alpha[t]*m.s[t]+m.c[t] for t in m.T)) + m.objective = Objective(expr=sum(m.alpha[t] * m.s[t] + m.c[t] for t in m.T)) # Global constraints m.demand_satisfaction = Constraint(m.T) @@ -116,7 +151,7 @@ def disjunctions(m, t): m.material_balance = Constraint(m.T) for t in m.T: - m.material_balance[t]=m.s[t] == (m.s[t-1] if t>1 else 0) + m.x[t] - m.f[t] + m.material_balance[t] = m.s[t] == (m.s[t - 1] if t > 1 else 0) + m.x[t] - m.f[t] return m @@ -137,13 +172,28 @@ def pprint_result(model): # Find activated disjunct/contract in each timestep choice = filter( lambda y: model.disjuncts[t, y].indicator_var.value == 1.0, - model.disjunct_choices) + model.disjunct_choices, + ) choices.append(next(iter(choice))) try: from pandas import DataFrame + df = DataFrame( - columns=['choice', 'base_cost', 'reduction', 'reduced_cost', 'spending', 'stock', 'storage_cost', 'min_purchase', 'purchased', 'feed', 'demand']) + columns=[ + 'choice', + 'base_cost', + 'reduction', + 'reduced_cost', + 'spending', + 'stock', + 'storage_cost', + 'min_purchase', + 'purchased', + 'feed', + 'demand', + ] + ) df.choice = choices df.stock = [model.s[t].value for t in model.T] df.storage_cost = [model.alpha[t] for t in model.T] @@ -162,22 +212,24 @@ def pprint_result(model): df.loc[t, 'min_purchase'] = 0 df.loc[t, 'reduced_cost'] = model.gamma[t] df.loc[t, 'base_cost'] = model.gamma[t] - t = t+1 + t = t + 1 elif df.loc[t, 'choice'] == 'B': df.loc[t, 'reduction'] = model.beta_B[t] df.loc[t, 'min_purchase'] = model.F_B_lo[t] - df.loc[t, 'reduced_cost'] = (1-model.beta_B[t])*model.gamma[t] + df.loc[t, 'reduced_cost'] = (1 - model.beta_B[t]) * model.gamma[t] df.loc[t, 'base_cost'] = model.gamma[t] - t = t+1 + t = t + 1 elif int(df.loc[t, 'choice']) == 0: - t = t+1 + t = t + 1 else: q = int(df.loc[t, 'choice']) t_contract = t - for t_ in range(t, t+q+1): + for t_ in range(t, t + q + 1): df.loc[t_, 'reduction'] = model.beta_L[t_contract, q] df.loc[t_, 'min_purchase'] = model.F_L_lo[t_contract, q] - df.loc[t_, 'reduced_cost'] = (1-model.beta_L[t_contract, q])*model.gamma[t_contract] + df.loc[t_, 'reduced_cost'] = ( + 1 - model.beta_L[t_contract, q] + ) * model.gamma[t_contract] df.loc[t_, 'base_cost'] = model.gamma[t_contract] t = t + q + 1 print(df) diff --git a/examples/gdp/small_lit/ex1_Lee.py b/examples/gdp/small_lit/ex1_Lee.py index 2aae500b299..ddd2e1c3d2f 100644 --- a/examples/gdp/small_lit/ex1_Lee.py +++ b/examples/gdp/small_lit/ex1_Lee.py @@ -6,8 +6,15 @@ """ -from pyomo.environ import (ConcreteModel, Constraint, NonNegativeReals, - Objective, SolverFactory, Var, minimize) +from pyomo.environ import ( + ConcreteModel, + Constraint, + NonNegativeReals, + Objective, + SolverFactory, + Var, + minimize, +) from pyomo.gdp import Disjunct, Disjunction @@ -22,18 +29,18 @@ def build_model(): m.y3 = Disjunct() m.y1.constr1 = Constraint(expr=m.x1**2 + m.x2**2 - 1 <= 0) m.y1.constr2 = Constraint(expr=m.c == 2) - m.y2.constr1 = Constraint(expr=(m.x1 - 4)**2 + (m.x2 - 1)**2 - 1 <= 0) + m.y2.constr1 = Constraint(expr=(m.x1 - 4) ** 2 + (m.x2 - 1) ** 2 - 1 <= 0) m.y2.constr2 = Constraint(expr=m.c == 1) - m.y3.constr1 = Constraint(expr=(m.x1 - 2)**2 + (m.x2 - 4)**2 - 1 <= 0) + m.y3.constr1 = Constraint(expr=(m.x1 - 2) ** 2 + (m.x2 - 4) ** 2 - 1 <= 0) m.y3.constr2 = Constraint(expr=m.c == 3) m.GPD123 = Disjunction(expr=[m.y1, m.y2, m.y3]) - m.obj = Objective(expr=(m.x1 - 3)**2 + (m.x2 - 2)**2 + m.c, sense=minimize) + m.obj = Objective(expr=(m.x1 - 3) ** 2 + (m.x2 - 2) ** 2 + m.c, sense=minimize) return m + if __name__ == "__main__": model = build_model() results = SolverFactory('gdpopt.loa').solve(model, tee=True) print(results) - diff --git a/examples/gdp/small_lit/ex_633_trespalacios.py b/examples/gdp/small_lit/ex_633_trespalacios.py index fc62111bbf3..b281e009d1f 100644 --- a/examples/gdp/small_lit/ex_633_trespalacios.py +++ b/examples/gdp/small_lit/ex_633_trespalacios.py @@ -29,22 +29,34 @@ def build_simple_nonconvex_gdp(): m.x2 = Var(bounds=(0, 3), doc="variable x2") m.obj = Objective(expr=5 + 0.2 * m.x1 - m.x2, doc="Minimize objective") - m.disjunction1 = Disjunction(expr=[ - [m.x2 <= 0.4*exp(m.x1/2.0), - m.x2 <= 0.5*(m.x1 - 2.5)**2 + 0.3, - m.x2 <= 6.5/(m.x1/0.3 + 2.0) + 1.0], - [m.x2 <= 0.3*exp(m.x1/1.8), - m.x2 <= 0.7*(m.x1/1.2 - 2.1)**2 + 0.3, - m.x2 <= 6.5/(m.x1/0.8 + 1.1)] - ]) - m.disjunction2 = Disjunction(expr=[ - [m.x2 <= 0.9*exp(m.x1/2.1), - m.x2 <= 1.3*(m.x1/1.5 - 1.8)**2 + 0.3, - m.x2 <= 6.5/(m.x1/0.8 + 1.1)], - [m.x2 <= 0.4*exp(m.x1/1.5), - m.x2 <= 1.2*(m.x1 - 2.5)**2 + 0.3, - m.x2 <= 6.0/(m.x1/0.6 + 1.0) + 0.5] - ]) + m.disjunction1 = Disjunction( + expr=[ + [ + m.x2 <= 0.4 * exp(m.x1 / 2.0), + m.x2 <= 0.5 * (m.x1 - 2.5) ** 2 + 0.3, + m.x2 <= 6.5 / (m.x1 / 0.3 + 2.0) + 1.0, + ], + [ + m.x2 <= 0.3 * exp(m.x1 / 1.8), + m.x2 <= 0.7 * (m.x1 / 1.2 - 2.1) ** 2 + 0.3, + m.x2 <= 6.5 / (m.x1 / 0.8 + 1.1), + ], + ] + ) + m.disjunction2 = Disjunction( + expr=[ + [ + m.x2 <= 0.9 * exp(m.x1 / 2.1), + m.x2 <= 1.3 * (m.x1 / 1.5 - 1.8) ** 2 + 0.3, + m.x2 <= 6.5 / (m.x1 / 0.8 + 1.1), + ], + [ + m.x2 <= 0.4 * exp(m.x1 / 1.5), + m.x2 <= 1.2 * (m.x1 - 2.5) ** 2 + 0.3, + m.x2 <= 6.0 / (m.x1 / 0.6 + 1.0) + 0.5, + ], + ] + ) return m diff --git a/examples/gdp/small_lit/nonconvex_HEN.py b/examples/gdp/small_lit/nonconvex_HEN.py index 193bb475f4f..38962a23d00 100644 --- a/examples/gdp/small_lit/nonconvex_HEN.py +++ b/examples/gdp/small_lit/nonconvex_HEN.py @@ -8,65 +8,94 @@ """ -from pyomo.environ import (ConcreteModel, Constraint, NonNegativeReals, - Objective, RangeSet, SolverFactory, - TransformationFactory, Var) +from pyomo.environ import ( + ConcreteModel, + Constraint, + NonNegativeReals, + Objective, + RangeSet, + SolverFactory, + TransformationFactory, + Var, +) def build_gdp_model(): # PARAMETERS - T1_lo, T1_up = 350., 400. - T2_lo, T2_up = 450., 500. + T1_lo, T1_up = 350.0, 400.0 + T2_lo, T2_up = 450.0, 500.0 - U = {'1':1.5, '2':0.5, '3':1} - FCP = {'hot':10.0, 'cold':7.5} - T_in = {'hot':500., 'cold':350., 'cooling':300., 'steam':600.} - T_out = {'hot':340., 'cold':560., 'cooling':320., 'steam':600.} - Cost = {'cooling':20., 'steam':80.} + U = {'1': 1.5, '2': 0.5, '3': 1} + FCP = {'hot': 10.0, 'cold': 7.5} + T_in = {'hot': 500.0, 'cold': 350.0, 'cooling': 300.0, 'steam': 600.0} + T_out = {'hot': 340.0, 'cold': 560.0, 'cooling': 320.0, 'steam': 600.0} + Cost = {'cooling': 20.0, 'steam': 80.0} # VARIABLES m = ConcreteModel() m.T1 = Var(domain=NonNegativeReals, bounds=(T1_lo, T1_up)) m.T2 = Var(domain=NonNegativeReals, bounds=(T2_lo, T2_up)) - m.exchangers = RangeSet(1,3) - m.A = Var(m.exchangers, domain=NonNegativeReals, bounds=(1e-4,50)) - m.CP = Var(m.exchangers, domain=NonNegativeReals, bounds=(0,600*(50**0.6)+2*46500)) + m.exchangers = RangeSet(1, 3) + m.A = Var(m.exchangers, domain=NonNegativeReals, bounds=(1e-4, 50)) + m.CP = Var( + m.exchangers, domain=NonNegativeReals, bounds=(0, 600 * (50**0.6) + 2 * 46500) + ) # Note that A_lo=0 leads to an exception in MC++ if using gdpopt with strategy 'GLOA' # The exception occurs when constructing McCormick relaxations # OBJECTIVE m.objective = Objective( - expr=(sum(m.CP[i] for i in m.exchangers) - + FCP['hot']*(m.T1-T_out['hot'])*Cost['cooling'] - + FCP['cold']*(T_out['cold']-m.T2)*Cost['steam']) + expr=( + sum(m.CP[i] for i in m.exchangers) + + FCP['hot'] * (m.T1 - T_out['hot']) * Cost['cooling'] + + FCP['cold'] * (T_out['cold'] - m.T2) * Cost['steam'] + ) ) # GLOBAL CONSTRAINTS m.constr1 = Constraint( - expr=FCP['hot']*(T_in['hot']-m.T1) == m.A[1]*U['1']*((T_in['hot']-m.T2)+(m.T1-T_in['cold']))/2. + expr=FCP['hot'] * (T_in['hot'] - m.T1) + == m.A[1] * U['1'] * ((T_in['hot'] - m.T2) + (m.T1 - T_in['cold'])) / 2.0 ) - m.constr2 = Constraint( # Note the error in the paper in constraint 2 - expr=FCP['hot']*(m.T1-T_out['hot']) == m.A[2]*U['2']*((T_out['hot']-T_in['cooling'])+(m.T1-T_out['cooling']))/2. + m.constr2 = Constraint( # Note the error in the paper in constraint 2 + expr=FCP['hot'] * (m.T1 - T_out['hot']) + == m.A[2] + * U['2'] + * ((T_out['hot'] - T_in['cooling']) + (m.T1 - T_out['cooling'])) + / 2.0 ) m.constr3 = Constraint( - expr=FCP['cold']*(T_out['cold']-m.T2) == m.A[3]*U['3']*((T_out['steam']-m.T2)+(T_in['steam']-T_out['cold']))/2. + expr=FCP['cold'] * (T_out['cold'] - m.T2) + == m.A[3] + * U['3'] + * ((T_out['steam'] - m.T2) + (T_in['steam'] - T_out['cold'])) + / 2.0 ) m.constr4 = Constraint( - expr=FCP['hot']*(T_in['hot']-m.T1) == FCP['cold']*(m.T2-T_in['cold']) + expr=FCP['hot'] * (T_in['hot'] - m.T1) == FCP['cold'] * (m.T2 - T_in['cold']) ) # DISJUNCTIONS @m.Disjunction(m.exchangers) def exchanger_disjunction(m, disjctn): return [ - [m.CP[disjctn] == 2750*(m.A[disjctn]**0.6)+3000, - 0. <= m.A[disjctn], m.A[disjctn] <= 10.], - [m.CP[disjctn] == 1500*(m.A[disjctn]**0.6)+15000, - 10. <= m.A[disjctn], m.A[disjctn] <= 25.], - [m.CP[disjctn] == 600*(m.A[disjctn]**0.6)+46500, - 25. <= m.A[disjctn], m.A[disjctn] <= 50.] + [ + m.CP[disjctn] == 2750 * (m.A[disjctn] ** 0.6) + 3000, + 0.0 <= m.A[disjctn], + m.A[disjctn] <= 10.0, + ], + [ + m.CP[disjctn] == 1500 * (m.A[disjctn] ** 0.6) + 15000, + 10.0 <= m.A[disjctn], + m.A[disjctn] <= 25.0, + ], + [ + m.CP[disjctn] == 600 * (m.A[disjctn] ** 0.6) + 46500, + 25.0 <= m.A[disjctn], + m.A[disjctn] <= 50.0, + ], ] return m @@ -83,10 +112,18 @@ def exchanger_disjunction(m, disjctn): if reformulation: if reformulation_method == 'bigm': - TransformationFactory('gdp.bigm').apply_to(model,bigM=600*(50**0.6)+2*46500) + TransformationFactory('gdp.bigm').apply_to( + model, bigM=600 * (50**0.6) + 2 * 46500 + ) elif reformulation_method == 'hull': TransformationFactory('gdp.hull').apply_to(model) - res = SolverFactory('gams').solve(model, tee=True, solver='baron', add_options=['option optcr = 0;'], keepfiles=True) + res = SolverFactory('gams').solve( + model, + tee=True, + solver='baron', + add_options=['option optcr = 0;'], + keepfiles=True, + ) else: # Note: MC++ needs to be properly installed to use strategy GLOA res = SolverFactory('gdpopt.gloa').solve(model, tee=True) diff --git a/examples/gdp/stickies.py b/examples/gdp/stickies.py index e050da57b7d..1211c1d0c18 100644 --- a/examples/gdp/stickies.py +++ b/examples/gdp/stickies.py @@ -21,14 +21,13 @@ def build_model(): model = AbstractModel() - model.BigM = Suffix(direction=Suffix.LOCAL) model.BigM[None] = 1000 DATFILE = "stickies1.dat" ####################### - #Sets + # Sets ####################### # J @@ -44,13 +43,17 @@ def build_model(): def screen_node_filter(model, s, n): return s != n - model.ScreenNodePairs = Set(initialize=model.Screens * model.Nodes, dimen=2, - filter=screen_node_filter) + + model.ScreenNodePairs = Set( + initialize=model.Screens * model.Nodes, dimen=2, filter=screen_node_filter + ) def screen_filter(model, s, sprime): return s != sprime - model.ScreenPairs = Set(initialize = model.Screens * model.Screens, dimen=2, - filter=screen_filter) + + model.ScreenPairs = Set( + initialize=model.Screens * model.Screens, dimen=2, filter=screen_filter + ) ###################### # Parameters @@ -76,22 +79,25 @@ def screen_filter(model, s, sprime): model.StickiesWeight = Param() model.CostWeight = Param() - ## Bounds on variables # F_s^{in, lo} and F_s^{in, up} (f_in_up(s), f_in_lo(s)) def flow_ub_rule(model, s): return sum(model.InitialComponentFlow[k] for k in model.Components) + model.ScreenFlowLB = Param(model.Screens) model.ScreenFlowUB = Param(model.Screens, initialize=flow_ub_rule) # m_in_lo(ss, k): lower bound of individual flow into nodes. model.InletComponentFlowLB = Param(model.Components, model.Nodes, default=0) + def component_flow_ub_rule(model, k, n): return model.InitialComponentFlow[k] + # m_in_up(ss, k) - model.InletComponentFlowUB = Param(model.Components, model.Nodes, - initialize=component_flow_ub_rule) + model.InletComponentFlowUB = Param( + model.Components, model.Nodes, initialize=component_flow_ub_rule + ) # r_lo(s) model.RejectRateLB = Param(model.Screens) @@ -99,134 +105,185 @@ def component_flow_ub_rule(model, k, n): model.RejectRateUB = Param(model.Screens) # m_rej_lo(s, k) - model.RejectedComponentFlowLB = Param(model.Components, model.Screens, - default=0) + model.RejectedComponentFlowLB = Param(model.Components, model.Screens, default=0) + def rejected_component_flow_bound(model, k, s): - return model.InitialComponentFlow[k]*(model.RejectRateUB[s]**\ - model.AcceptanceFactor[s, k]) + return model.InitialComponentFlow[k] * ( + model.RejectRateUB[s] ** model.AcceptanceFactor[s, k] + ) + # m_rej_up(s, k) - model.RejectedComponentFlowUB = Param(model.Components, model.Screens, - initialize=rejected_component_flow_bound) + model.RejectedComponentFlowUB = Param( + model.Components, model.Screens, initialize=rejected_component_flow_bound + ) # m_acc_lo(s, k): lower bound of accepted individual flow - model.AcceptedComponentFlowLB = Param(model.Components, model.Screens, - default=0) + model.AcceptedComponentFlowLB = Param(model.Components, model.Screens, default=0) + def accepted_component_flow_bound(model, k, s): - return model.InitialComponentFlow[k]*(1 - model.RejectRateLB[s]**\ - model.AcceptanceFactor[s, k]) + return model.InitialComponentFlow[k] * ( + 1 - model.RejectRateLB[s] ** model.AcceptanceFactor[s, k] + ) + # m_acc_up(s, k) - model.AcceptedComponentFlowUB = Param(model.Components, model.Screens, - initialize=accepted_component_flow_bound) + model.AcceptedComponentFlowUB = Param( + model.Components, model.Screens, initialize=accepted_component_flow_bound + ) ###################### # Variables ###################### # c_s, C(s), cost of selecting screen - model.screenCost = Var(model.Screens, within=NonNegativeReals)#, bounds=get_screen_cost_bounds) + model.screenCost = Var( + model.Screens, within=NonNegativeReals + ) # , bounds=get_screen_cost_bounds) # total inlet flow into screen s (f_s, F_IN(s)) # NOTE: the upper bound is enforced globally. The lower bound is enforced in # the first disjunction (to match GAMS) def get_inlet_flow_bounds(model, s): return (0, model.ScreenFlowUB[s]) - model.inletScreenFlow = Var(model.Screens, within=NonNegativeReals, - bounds=get_inlet_flow_bounds) + + model.inletScreenFlow = Var( + model.Screens, within=NonNegativeReals, bounds=get_inlet_flow_bounds + ) # inlet flow of component j into node n, (f_{n,j}^I, M_IN) def get_inlet_component_flow_bounds(model, j, n): return (model.InletComponentFlowLB[j, n], model.InletComponentFlowUB[j, n]) - model.inletComponentFlow = Var(model.Components, model.Nodes, - within=NonNegativeReals, - bounds=get_inlet_component_flow_bounds) + + model.inletComponentFlow = Var( + model.Components, + model.Nodes, + within=NonNegativeReals, + bounds=get_inlet_component_flow_bounds, + ) # accepted flow of component j from screen s (f_{s, j}^A) def get_accepted_component_flow_bounds(model, j, s): - return (model.AcceptedComponentFlowLB[j, s], - model.AcceptedComponentFlowUB[j, s]) - model.acceptedComponentFlow = Var(model.Components, model.Screens, - within=NonNegativeReals, - bounds=get_accepted_component_flow_bounds) + return ( + model.AcceptedComponentFlowLB[j, s], + model.AcceptedComponentFlowUB[j, s], + ) + + model.acceptedComponentFlow = Var( + model.Components, + model.Screens, + within=NonNegativeReals, + bounds=get_accepted_component_flow_bounds, + ) # rejected flow of component j from screen s (f_{s,j}^R) def rej_component_flow_bounds(model, k, s): - return (model.RejectedComponentFlowLB[k, s], - model.RejectedComponentFlowUB[k, s]) - model.rejectedComponentFlow = Var(model.Components, model.Screens, - within=NonNegativeReals, - bounds=rej_component_flow_bounds) + return ( + model.RejectedComponentFlowLB[k, s], + model.RejectedComponentFlowUB[k, s], + ) + + model.rejectedComponentFlow = Var( + model.Components, + model.Screens, + within=NonNegativeReals, + bounds=rej_component_flow_bounds, + ) # accepted flow of component j from screen s to node n (m_{s,n,j}^A) def get_accepted_node_flow_bounds(model, j, s, n): return (0, model.AcceptedComponentFlowUB[j, s]) - model.acceptedNodeFlow = Var(model.Components, model.Screens, model.Nodes, - within=NonNegativeReals, - bounds=get_accepted_node_flow_bounds) + + model.acceptedNodeFlow = Var( + model.Components, + model.Screens, + model.Nodes, + within=NonNegativeReals, + bounds=get_accepted_node_flow_bounds, + ) # rejected flow of component j from screen s to node n (m_{s,n,j}^R) def get_rejected_node_flow_bounds(model, j, s, n): return (0, model.RejectedComponentFlowUB[j, s]) - model.rejectedNodeFlow = Var(model.Components, model.Screens, model.Nodes, - within=NonNegativeReals, - bounds=get_rejected_node_flow_bounds) + + model.rejectedNodeFlow = Var( + model.Components, + model.Screens, + model.Nodes, + within=NonNegativeReals, + bounds=get_rejected_node_flow_bounds, + ) # flow of component j from source to node n (m_{s,j}^0) def get_src_flow_bounds(model, j, n): return (0, model.InitialComponentFlow[j]) - model.flowFromSource = Var(model.Components, model.Nodes, - within=NonNegativeReals) + + model.flowFromSource = Var(model.Components, model.Nodes, within=NonNegativeReals) # reject rate of screen s (r_s) def get_rej_rate_bounds(model, s): return (model.RejectRateLB[s], model.RejectRateUB[s]) - model.rejectRate = Var(model.Screens, within=NonNegativeReals, - bounds=get_rej_rate_bounds) + model.rejectRate = Var( + model.Screens, within=NonNegativeReals, bounds=get_rej_rate_bounds + ) ###################### # Objective ###################### def calc_cost_rule(model): - lostFiberCost = model.FiberWeight * sum(model.inletComponentFlow[j,'SNK'] \ - for j in model.GoodComponents) - stickiesCost = model.StickiesWeight * sum(model.inletComponentFlow[j,'PRD']\ - for j in model.BadComponents) - screenCost = model.CostWeight * sum(model.screenCost[s] \ - for s in model.Screens) + lostFiberCost = model.FiberWeight * sum( + model.inletComponentFlow[j, 'SNK'] for j in model.GoodComponents + ) + stickiesCost = model.StickiesWeight * sum( + model.inletComponentFlow[j, 'PRD'] for j in model.BadComponents + ) + screenCost = model.CostWeight * sum(model.screenCost[s] for s in model.Screens) return lostFiberCost + stickiesCost + screenCost - model.min_cost = Objective(rule=calc_cost_rule) + model.min_cost = Objective(rule=calc_cost_rule) ###################### # Constraints ###################### def stickies_bound_rule(model, j): - return sum(model.inletComponentFlow[j,'PRD'] for j in model.BadComponents) \ + return ( + sum(model.inletComponentFlow[j, 'PRD'] for j in model.BadComponents) <= model.AcceptedLeftover[j] * model.InitialComponentFlow[j] + ) + model.stickies_bound = Constraint(model.BadComponents, rule=stickies_bound_rule) def inlet_flow_rule(model, s, j): - return model.inletComponentFlow[j,s] == model.acceptedComponentFlow[j,s] + \ - model.rejectedComponentFlow[j, s] - model.inlet_flow = Constraint(model.Screens, model.Components, - rule=inlet_flow_rule) + return ( + model.inletComponentFlow[j, s] + == model.acceptedComponentFlow[j, s] + model.rejectedComponentFlow[j, s] + ) + + model.inlet_flow = Constraint(model.Screens, model.Components, rule=inlet_flow_rule) def total_inlet_flow_rule(model, s): - return model.inletScreenFlow[s] == sum(model.inletComponentFlow[j, s] \ - for j in model.Components) + return model.inletScreenFlow[s] == sum( + model.inletComponentFlow[j, s] for j in model.Components + ) + model.total_inlet_flow = Constraint(model.Screens, rule=total_inlet_flow_rule) def inlet_flow_balance_rule(model, n, j): - return model.inletComponentFlow[j, n] == model.flowFromSource[j, n] + \ - sum(model.acceptedNodeFlow[j, s, n] + model.rejectedNodeFlow[j, s, n] \ - for s in model.Screens if s != n) - model.inlet_flow_balance = Constraint(model.Nodes, model.Components, - rule=inlet_flow_balance_rule) + return model.inletComponentFlow[j, n] == model.flowFromSource[j, n] + sum( + model.acceptedNodeFlow[j, s, n] + model.rejectedNodeFlow[j, s, n] + for s in model.Screens + if s != n + ) + + model.inlet_flow_balance = Constraint( + model.Nodes, model.Components, rule=inlet_flow_balance_rule + ) def source_flow_rule(model, j): - return model.InitialComponentFlow[j] == sum(model.flowFromSource[j, n] \ - for n in model.Nodes) + return model.InitialComponentFlow[j] == sum( + model.flowFromSource[j, n] for n in model.Nodes + ) + model.source_flow = Constraint(model.Components, rule=source_flow_rule) ################# @@ -235,108 +292,130 @@ def source_flow_rule(model, j): def screen_disjunct_rule(disjunct, selectScreen, s): model = disjunct.model() + def rejected_flow_rule(disjunct, j): - return model.rejectedComponentFlow[j,s] == \ - model.inletComponentFlow[j,s]* \ - (model.rejectRate[s]**model.AcceptanceFactor[s, j]) + return model.rejectedComponentFlow[j, s] == model.inletComponentFlow[ + j, s + ] * (model.rejectRate[s] ** model.AcceptanceFactor[s, j]) if selectScreen: - disjunct.inlet_flow_bounds = Constraint(expr=model.ScreenFlowLB[s] <= \ - model.inletScreenFlow[s])# <= \ - #model.ScreenFlowUB[s]) - disjunct.rejected_flow = Constraint(model.Components, - rule=rejected_flow_rule) - disjunct.screen_cost = Constraint(expr=model.screenCost[s] == \ - model.ScreenCostCoeff1[s]* \ - (model.inletScreenFlow[s]** \ - model.ExpScreenCostCoeff[s]) + \ - model.ScreenCostCoeff2[s]* \ - (1 - model.rejectRate[s])) + disjunct.inlet_flow_bounds = Constraint( + expr=model.ScreenFlowLB[s] <= model.inletScreenFlow[s] + ) # <= \ + # model.ScreenFlowUB[s]) + disjunct.rejected_flow = Constraint( + model.Components, rule=rejected_flow_rule + ) + disjunct.screen_cost = Constraint( + expr=model.screenCost[s] + == model.ScreenCostCoeff1[s] + * (model.inletScreenFlow[s] ** model.ExpScreenCostCoeff[s]) + + model.ScreenCostCoeff2[s] * (1 - model.rejectRate[s]) + ) else: disjunct.no_flow = Constraint(expr=model.inletScreenFlow[s] == 0) disjunct.no_cost = Constraint(expr=model.screenCost[s] == 0) - model.screen_selection_disjunct = Disjunct([0,1], model.Screens, - rule=screen_disjunct_rule) + + model.screen_selection_disjunct = Disjunct( + [0, 1], model.Screens, rule=screen_disjunct_rule + ) def screen_disjunction_rule(model, s): - return [model.screen_selection_disjunct[selectScreen, s] \ - for selectScreen in [0,1]] - model.screen_disjunction = Disjunction(model.Screens, - rule=screen_disjunction_rule) + return [ + model.screen_selection_disjunct[selectScreen, s] for selectScreen in [0, 1] + ] + model.screen_disjunction = Disjunction(model.Screens, rule=screen_disjunction_rule) def accepted_flow_disjunct_rule(disjunct, s, n, acceptFlow): model = disjunct.model() + def flow_balance_rule(disjunct, j): - return model.acceptedNodeFlow[j, s, n] == \ - model.acceptedComponentFlow[j, s] + return model.acceptedNodeFlow[j, s, n] == model.acceptedComponentFlow[j, s] + def no_flow_rule(disjunct, j): return model.acceptedNodeFlow[j, s, n] == 0 if acceptFlow: - disjunct.flow_balance = Constraint(model.Components, - rule=flow_balance_rule) + disjunct.flow_balance = Constraint(model.Components, rule=flow_balance_rule) else: disjunct.no_flow = Constraint(model.Components, rule=no_flow_rule) - model.flow_acceptance_disjunct = Disjunct(model.ScreenNodePairs, [0,1], - rule=accepted_flow_disjunct_rule) + + model.flow_acceptance_disjunct = Disjunct( + model.ScreenNodePairs, [0, 1], rule=accepted_flow_disjunct_rule + ) def flow_acceptance_disjunction_rule(model, s, n): - return [model.flow_acceptance_disjunct[s, n, acceptFlow] \ - for acceptFlow in [0,1]] - model.flow_acceptance_disjunction = Disjunction(model.ScreenNodePairs, - rule=flow_acceptance_disjunction_rule) + return [ + model.flow_acceptance_disjunct[s, n, acceptFlow] for acceptFlow in [0, 1] + ] + model.flow_acceptance_disjunction = Disjunction( + model.ScreenNodePairs, rule=flow_acceptance_disjunction_rule + ) def rejected_flow_disjunct_rule(disjunct, s, n, rejectFlow): model = disjunct.model() + def flow_balance_rule(disjunct, j): - return model.rejectedNodeFlow[j, s, n] == \ - model.rejectedComponentFlow[j, s] + return model.rejectedNodeFlow[j, s, n] == model.rejectedComponentFlow[j, s] + def no_reject_rule(disjunct, j): return model.rejectedNodeFlow[j, s, n] == 0 if rejectFlow: - disjunct.flow_balance = Constraint(model.Components, - rule=flow_balance_rule) + disjunct.flow_balance = Constraint(model.Components, rule=flow_balance_rule) else: disjunct.no_reject = Constraint(model.Components, rule=no_reject_rule) - model.flow_rejection_disjunct = Disjunct(model.ScreenNodePairs, [0,1], - rule=rejected_flow_disjunct_rule) + + model.flow_rejection_disjunct = Disjunct( + model.ScreenNodePairs, [0, 1], rule=rejected_flow_disjunct_rule + ) def rejected_flow_disjunction_rule(model, s, n): - return [model.flow_rejection_disjunct[s, n, rejectFlow] \ - for rejectFlow in [0,1]] - model.flow_rejection_disjunction = Disjunction(model.ScreenNodePairs, - rule=rejected_flow_disjunction_rule) + return [ + model.flow_rejection_disjunct[s, n, rejectFlow] for rejectFlow in [0, 1] + ] + model.flow_rejection_disjunction = Disjunction( + model.ScreenNodePairs, rule=rejected_flow_disjunction_rule + ) def flow_from_source_disjunct_rule(disjunct, n): model = disjunct.model() + def sourceFlow_balance_rule1(disjunct, j): # this doesn't match the formulation, but it matches GAMS: return model.flowFromSource[j, n] >= model.InitialComponentFlowLB[j] # this would be the formulation version: - #return model.flowFromSource[j, n] == model.InitialComponentFlow[j] + # return model.flowFromSource[j, n] == model.InitialComponentFlow[j] + def sourceFlow_balance_rule2(disjunct, j): return model.flowFromSource[j, n] <= model.InitialComponentFlow[j] + def no_sourceFlow_rule(disjunct, j, nprime): return model.flowFromSource[j, nprime] == 0 - disjunct.flow_balance1 = Constraint(model.Components, - rule=sourceFlow_balance_rule1) - disjunct.flow_balance2 = Constraint(model.Components, - rule=sourceFlow_balance_rule2) - disjunct.no_flow = Constraint(model.Components, model.Nodes - [n], - rule=no_sourceFlow_rule) - model.flow_from_source_disjunct = Disjunct(model.Nodes, - rule=flow_from_source_disjunct_rule) + disjunct.flow_balance1 = Constraint( + model.Components, rule=sourceFlow_balance_rule1 + ) + disjunct.flow_balance2 = Constraint( + model.Components, rule=sourceFlow_balance_rule2 + ) + disjunct.no_flow = Constraint( + model.Components, model.Nodes - [n], rule=no_sourceFlow_rule + ) + + model.flow_from_source_disjunct = Disjunct( + model.Nodes, rule=flow_from_source_disjunct_rule + ) def flow_from_source_disjunction_rule(model): return [model.flow_from_source_disjunct[n] for n in model.Nodes] - model.flow_from_source_disjunction = Disjunction( - rule=flow_from_source_disjunction_rule) + model.flow_from_source_disjunction = Disjunction( + rule=flow_from_source_disjunction_rule + ) ###################### # Boolean Constraints @@ -348,47 +427,75 @@ def flow_from_source_disjunction_rule(model): # These are the GAMS versions of the logical constraints, which is not # what appears in the formulation: def log1_rule(model, s): - return model.screen_selection_disjunct[1, s].binary_indicator_var == \ - sum(model.flow_acceptance_disjunct[s, n, 1].binary_indicator_var \ - for n in model.Nodes if s != n) + return model.screen_selection_disjunct[1, s].binary_indicator_var == sum( + model.flow_acceptance_disjunct[s, n, 1].binary_indicator_var + for n in model.Nodes + if s != n + ) + model.log1 = Constraint(model.Screens, rule=log1_rule) def log2_rule(model, s): - return model.screen_selection_disjunct[1, s].binary_indicator_var == \ - sum(model.flow_rejection_disjunct[s, n, 1].binary_indicator_var \ - for n in model.Nodes if s != n) + return model.screen_selection_disjunct[1, s].binary_indicator_var == sum( + model.flow_rejection_disjunct[s, n, 1].binary_indicator_var + for n in model.Nodes + if s != n + ) + model.log2 = Constraint(model.Screens, rule=log2_rule) def log3_rule(model, s): - return model.screen_selection_disjunct[1, s].binary_indicator_var >= \ - sum(model.flow_acceptance_disjunct[s, sprime, 1].binary_indicator_var \ - for sprime in model.Screens if s != sprime) + return model.screen_selection_disjunct[1, s].binary_indicator_var >= sum( + model.flow_acceptance_disjunct[s, sprime, 1].binary_indicator_var + for sprime in model.Screens + if s != sprime + ) + model.log3 = Constraint(model.Screens, rule=log3_rule) def log4_rule(model, s): - return model.screen_selection_disjunct[1, s].binary_indicator_var >= \ - sum(model.flow_rejection_disjunct[s, sprime, 1].binary_indicator_var \ - for sprime in model.Screens if s != sprime) + return model.screen_selection_disjunct[1, s].binary_indicator_var >= sum( + model.flow_rejection_disjunct[s, sprime, 1].binary_indicator_var + for sprime in model.Screens + if s != sprime + ) + model.log4 = Constraint(model.Screens, rule=log4_rule) def log6_rule(model, s, sprime): - return model.flow_acceptance_disjunct[s, sprime, 1].binary_indicator_var + \ - model.flow_acceptance_disjunct[sprime, s, 1].binary_indicator_var <= 1 + return ( + model.flow_acceptance_disjunct[s, sprime, 1].binary_indicator_var + + model.flow_acceptance_disjunct[sprime, s, 1].binary_indicator_var + <= 1 + ) + model.log6 = Constraint(model.ScreenPairs, rule=log6_rule) def log7_rule(model, s, sprime): - return model.flow_rejection_disjunct[s, sprime, 1].binary_indicator_var + \ - model.flow_rejection_disjunct[sprime, s, 1].binary_indicator_var <= 1 + return ( + model.flow_rejection_disjunct[s, sprime, 1].binary_indicator_var + + model.flow_rejection_disjunct[sprime, s, 1].binary_indicator_var + <= 1 + ) + model.log7 = Constraint(model.ScreenPairs, rule=log7_rule) def log8_rule(model, s, n): - return model.flow_acceptance_disjunct[s, n, 1].binary_indicator_var + \ - model.flow_rejection_disjunct[s, n, 1].binary_indicator_var <= 1 + return ( + model.flow_acceptance_disjunct[s, n, 1].binary_indicator_var + + model.flow_rejection_disjunct[s, n, 1].binary_indicator_var + <= 1 + ) + model.log8 = Constraint(model.ScreenNodePairs, rule=log8_rule) def log9_rule(model, s, sprime): - return model.flow_acceptance_disjunct[s, sprime, 1].binary_indicator_var + \ - model.flow_rejection_disjunct[sprime, s, 1].binary_indicator_var <= 1 + return ( + model.flow_acceptance_disjunct[s, sprime, 1].binary_indicator_var + + model.flow_rejection_disjunct[sprime, s, 1].binary_indicator_var + <= 1 + ) + model.log9 = Constraint(model.ScreenPairs, rule=log9_rule) # These are the above logical constraints implemented correctly (I think) @@ -408,7 +515,6 @@ def log9_rule(model, s, sprime): # model.flow_existence2 = Constraint(model.ScreenNodePairs, # rule=flow_existence_rule2) - # # YA_{s,s'} v YR_{s',s} implies Y_s # def screen_flow_existence_rule1(model, s, sprime): # return model.screen_selection_disjunct[1, s].indicator_var >= \ @@ -422,7 +528,6 @@ def log9_rule(model, s, sprime): # model.screen_flow_existence2 = Constraint(model.ScreenPairs, # rule=screen_flow_existence_rule2) - # # YA_{s', s} XOR YA_{s, s'} # def accept_rule1(model, s, sprime): # return 1 <= model.flow_acceptance_disjunct[s, sprime, 1].indicator_var + \ @@ -444,7 +549,6 @@ def log9_rule(model, s, sprime): # model.flow_acceptance_disjunct[s, sprime, 1].indicator_var # model.accept4 = Constraint(model.ScreenPairs, rule=accept_rule4) - # # YR_{s', s} XOR YR_{s, s'} # def reject_rule1(model, s, sprime): # return 1 <= model.flow_rejection_disjunct[s, sprime, 1].indicator_var + \ @@ -466,7 +570,6 @@ def log9_rule(model, s, sprime): # model.flow_rejection_disjunct[s, sprime, 1].indicator_var # model.reject4 = Constraint(model.ScreenPairs, rule=reject_rule4) - # # YA_{s,n} XOR YR_{s,n} # def accept_or_reject_rule1(model, s, n): # return 1 <= model.flow_acceptance_disjunct[s, n, 1].indicator_var + \ @@ -496,8 +599,8 @@ def log9_rule(model, s, sprime): # fix the variables they fix in GAMS for s in instance.Screens: - instance.flow_acceptance_disjunct[s,'SNK',1].indicator_var.fix(False) - instance.flow_rejection_disjunct[s,'PRD',1].indicator_var.fix(False) + instance.flow_acceptance_disjunct[s, 'SNK', 1].indicator_var.fix(False) + instance.flow_rejection_disjunct[s, 'PRD', 1].indicator_var.fix(False) ################################################################################## ## for validation: Fix all the indicator variables to see if we get same objective @@ -511,7 +614,6 @@ def log9_rule(model, s, sprime): # instance.screen_selection_disjunct[1,'S5'].indicator_var.fix(0) # instance.screen_selection_disjunct[1,'S6'].indicator_var.fix(0) - # instance.flow_acceptance_disjunct['S1','S2',1].indicator_var.fix(0) # instance.flow_acceptance_disjunct['S1','S3',1].indicator_var.fix(0) # instance.flow_acceptance_disjunct['S1','S4',1].indicator_var.fix(0) diff --git a/examples/gdp/strip_packing/stripPacking.py b/examples/gdp/strip_packing/stripPacking.py index a55e012a7ac..abf86d58063 100644 --- a/examples/gdp/strip_packing/stripPacking.py +++ b/examples/gdp/strip_packing/stripPacking.py @@ -20,6 +20,8 @@ # upperbound on length (default is sum of lengths of rectangles) def sumLengths(model): return sum(model.Lengths[i] for i in model.RECTANGLES) + + model.LengthUB = Param(initialize=sumLengths) # rectangle relations @@ -35,24 +37,34 @@ def sumLengths(model): # generate the list of possible rectangle conflicts (which are any pair) def rec_pairs_filter(model, i, j): return i < j -model.RectanglePairs = Set(initialize=model.RECTANGLES * model.RECTANGLES, - dimen=2, filter=rec_pairs_filter) + + +model.RectanglePairs = Set( + initialize=model.RECTANGLES * model.RECTANGLES, dimen=2, filter=rec_pairs_filter +) # strip length constraint def strip_ends_after_last_rec_rule(model, i): return model.Lt >= model.x[i] + model.Lengths[i] -model.strip_ends_after_last_rec = Constraint(model.RECTANGLES, - rule=strip_ends_after_last_rec_rule) + + +model.strip_ends_after_last_rec = Constraint( + model.RECTANGLES, rule=strip_ends_after_last_rec_rule +) # constraints to prevent rectangles from going off strip def no_recs_off_end_rule(model, i): return inequality(0, model.x[i], model.LengthUB - model.Lengths[i]) + + model.no_recs_off_end = Constraint(model.RECTANGLES, rule=no_recs_off_end_rule) + def no_recs_off_bottom_rule(model, i): return inequality(model.Heights[i], model.y[i], model.StripWidth) -model.no_recs_off_bottom = Constraint(model.RECTANGLES, - rule=no_recs_off_bottom_rule) + + +model.no_recs_off_bottom = Constraint(model.RECTANGLES, rule=no_recs_off_bottom_rule) # Disjunctions to prevent overlap between rectangles def no_overlap_disjunct_rule(disjunct, i, j, recRelation): @@ -70,14 +82,20 @@ def no_overlap_disjunct_rule(disjunct, i, j, recRelation): elif recRelation == 'Below': disjunct.c = Constraint(expr=model.y[j] - model.Heights[j] >= model.y[i]) else: - raise RuntimeError("Unrecognized rectangle relationship: %s" - % recRelation) -model.no_overlap_disjunct = Disjunct(model.RectanglePairs, model.RecRelations, - rule=no_overlap_disjunct_rule) + raise RuntimeError("Unrecognized rectangle relationship: %s" % recRelation) + + +model.no_overlap_disjunct = Disjunct( + model.RectanglePairs, model.RecRelations, rule=no_overlap_disjunct_rule +) + def no_overlap(model, i, j): - return [model.no_overlap_disjunct[i, j, direction] \ - for direction in model.RecRelations] + return [ + model.no_overlap_disjunct[i, j, direction] for direction in model.RecRelations + ] + + model.disj = Disjunction(model.RectanglePairs, rule=no_overlap) # minimize length diff --git a/examples/gdp/strip_packing/strip_packing_8rect.py b/examples/gdp/strip_packing/strip_packing_8rect.py index 9fb96500f03..eba3c82dc05 100644 --- a/examples/gdp/strip_packing/strip_packing_8rect.py +++ b/examples/gdp/strip_packing/strip_packing_8rect.py @@ -13,8 +13,16 @@ from __future__ import division -from pyomo.environ import (ConcreteModel, NonNegativeReals, Objective, Param, - Set, SolverFactory, TransformationFactory, Var) +from pyomo.environ import ( + ConcreteModel, + NonNegativeReals, + Objective, + Param, + Set, + SolverFactory, + TransformationFactory, + Var, +) # x and y are flipped from article @@ -26,55 +34,62 @@ def build_rect_strip_packing_model(): # Width and Length of each rectangle model.rect_width = Param( - model.rectangles, initialize={0: 3, 1: 3, 2: 2, 3: 2, 4: 3, 5: 5, - 6: 7, 7: 7}) + model.rectangles, initialize={0: 3, 1: 3, 2: 2, 3: 2, 4: 3, 5: 5, 6: 7, 7: 7} + ) # parameter indexed by each rectangle # same as height? model.rect_length = Param( - model.rectangles, initialize={0: 4, 1: 3, 2: 2, 3: 2, 4: 3, 5: 3, - 6: 4, 7: 4}) + model.rectangles, initialize={0: 4, 1: 3, 2: 2, 3: 2, 4: 3, 5: 3, 6: 4, 7: 4} + ) - model.strip_width = Param( - initialize=10, doc="Available width of the strip") + model.strip_width = Param(initialize=10, doc="Available width of the strip") # upperbound on length (default is sum of lengths of rectangles) model.max_length = Param( initialize=sum(model.rect_length[i] for i in model.rectangles), doc="maximum length of the strip (if all rectangles were arranged " - "lengthwise)") + "lengthwise)", + ) # x (length) and y (width) coordinates of each of the rectangles - model.x = Var(model.rectangles, - bounds=(0, model.max_length), - doc="rectangle corner x-position (position across length)") + model.x = Var( + model.rectangles, + bounds=(0, model.max_length), + doc="rectangle corner x-position (position across length)", + ) def w_bounds(m, i): return (0, m.strip_width - m.rect_width[i]) - model.y = Var(model.rectangles, - bounds=w_bounds, - doc="rectangle corner y-position (position down width)") - model.strip_length = Var( - within=NonNegativeReals, doc="Length of strip required.") + model.y = Var( + model.rectangles, + bounds=w_bounds, + doc="rectangle corner y-position (position down width)", + ) + + model.strip_length = Var(within=NonNegativeReals, doc="Length of strip required.") def rec_pairs_filter(model, i, j): return i < j + model.overlap_pairs = Set( initialize=model.rectangles * model.rectangles, - dimen=2, filter=rec_pairs_filter, - doc="set of possible rectangle conflicts") + dimen=2, + filter=rec_pairs_filter, + doc="set of possible rectangle conflicts", + ) @model.Constraint(model.rectangles) def strip_ends_after_last_rec(model, i): return model.strip_length >= model.x[i] + model.rect_length[i] - model.total_length = Objective(expr=model.strip_length, - doc="Minimize length") + model.total_length = Objective(expr=model.strip_length, doc="Minimize length") @model.Disjunction( model.overlap_pairs, doc="Make sure that none of the rectangles on the strip overlap in " - "either the x or y dimensions.") + "either the x or y dimensions.", + ) def no_overlap(m, i, j): return [ m.x[i] + m.rect_length[i] <= m.x[j], diff --git a/examples/gdp/strip_packing/strip_packing_concrete.py b/examples/gdp/strip_packing/strip_packing_concrete.py index b83c45cd40c..4fa6172a8d1 100644 --- a/examples/gdp/strip_packing/strip_packing_concrete.py +++ b/examples/gdp/strip_packing/strip_packing_concrete.py @@ -11,8 +11,7 @@ """ from __future__ import division -from pyomo.environ import (ConcreteModel, NonNegativeReals, Objective, Param, - Set, Var) +from pyomo.environ import ConcreteModel, NonNegativeReals, Objective, Param, Set, Var def build_rect_strip_packing_model(): @@ -21,58 +20,63 @@ def build_rect_strip_packing_model(): model.rectangles = Set(ordered=True, initialize=[0, 1, 2, 3]) # Width and Length of each rectangle - model.rect_width = Param( - model.rectangles, initialize={0: 6, 1: 3, 2: 4, 3: 2}) - model.rect_length = Param( - model.rectangles, initialize={0: 6, 1: 8, 2: 5, 3: 3}) + model.rect_width = Param(model.rectangles, initialize={0: 6, 1: 3, 2: 4, 3: 2}) + model.rect_length = Param(model.rectangles, initialize={0: 6, 1: 8, 2: 5, 3: 3}) - model.strip_width = Param( - initialize=10, doc="Available width of the strip") + model.strip_width = Param(initialize=10, doc="Available width of the strip") # upperbound on length (default is sum of lengths of rectangles) model.max_length = Param( initialize=sum(model.rect_length[i] for i in model.rectangles), doc="maximum length of the strip (if all rectangles were arranged " - "lengthwise)") + "lengthwise)", + ) # x (length) and y (width) coordinates of each of the rectangles - model.x = Var(model.rectangles, - bounds=(0, model.max_length), - doc="rectangle corner x-position (position down length)") + model.x = Var( + model.rectangles, + bounds=(0, model.max_length), + doc="rectangle corner x-position (position down length)", + ) def w_bounds(m, i): return (0, m.strip_width - m.rect_width[i]) - model.y = Var(model.rectangles, - bounds=w_bounds, - doc="rectangle corner y-position (position across width)") - model.strip_length = Var( - within=NonNegativeReals, doc="Length of strip required.") + model.y = Var( + model.rectangles, + bounds=w_bounds, + doc="rectangle corner y-position (position across width)", + ) + + model.strip_length = Var(within=NonNegativeReals, doc="Length of strip required.") def rec_pairs_filter(model, i, j): return i < j + model.overlap_pairs = Set( initialize=model.rectangles * model.rectangles, - dimen=2, filter=rec_pairs_filter, - doc="set of possible rectangle conflicts") + dimen=2, + filter=rec_pairs_filter, + doc="set of possible rectangle conflicts", + ) @model.Constraint(model.rectangles) def strip_ends_after_last_rec(model, i): return model.strip_length >= model.x[i] + model.rect_length[i] - model.total_length = Objective(expr=model.strip_length, - doc="Minimize length") + model.total_length = Objective(expr=model.strip_length, doc="Minimize length") @model.Disjunction( model.overlap_pairs, doc="Make sure that none of the rectangles on the strip overlap in " - "either the x or y dimensions.") + "either the x or y dimensions.", + ) def no_overlap(m, i, j): return [ - m.x[i] + m.rect_length[i] <= m.x[j],# i left of j - m.x[j] + m.rect_length[j] <= m.x[i],# i right of j - m.y[i] + m.rect_width[i] <= m.y[j],# i below j - m.y[j] + m.rect_width[j] <= m.y[i],#i above j + m.x[i] + m.rect_length[i] <= m.x[j], # i left of j + m.x[j] + m.rect_length[j] <= m.x[i], # i right of j + m.y[i] + m.rect_width[i] <= m.y[j], # i below j + m.y[j] + m.rect_width[j] <= m.y[i], # i above j ] return model diff --git a/examples/gdp/two_rxn_lee/two_rxn_model.py b/examples/gdp/two_rxn_lee/two_rxn_model.py index a3ab0d1f0c3..9057ef8c006 100644 --- a/examples/gdp/two_rxn_lee/two_rxn_model.py +++ b/examples/gdp/two_rxn_lee/two_rxn_model.py @@ -1,8 +1,8 @@ """Two reactor model from literature. See README.md.""" from __future__ import division -from pyomo.core import (ConcreteModel, Constraint, Objective, Param, Var, - maximize) +from pyomo.core import ConcreteModel, Constraint, Objective, Param, Var, maximize + # from pyomo.environ import * # NOQA from pyomo.gdp import Disjunction @@ -13,47 +13,68 @@ def build_model(use_mccormick=False): m.F = Var(bounds=(0, 8), doc="Flow into reactor") m.X = Var(bounds=(0, 1), doc="Reactor conversion") m.d = Param(initialize=2, doc="Max product demand") - m.c = Param([1, 2, 'I', 'II'], doc="Costs", initialize={ - 1: 2, # Value of product - 2: 0.2, # Cost of raw material - 'I': 2.5, # Cost of reactor I - 'II': 1.5 # Cost of reactor II - }) - m.alpha = Param(['I', 'II'], doc="Reactor coefficient", - initialize={'I': -8, 'II': -10}) - m.beta = Param(['I', 'II'], doc="Reactor coefficient", - initialize={'I': 9, 'II': 15}) - m.X_LB = Param(['I', 'II'], doc="Reactor conversion lower bound", - initialize={'I': 0.2, 'II': 0.7}) - m.X_UB = Param(['I', 'II'], doc="Reactor conversion upper bound", - initialize={'I': 0.95, 'II': 0.99}) + m.c = Param( + [1, 2, 'I', 'II'], + doc="Costs", + initialize={ + 1: 2, # Value of product + 2: 0.2, # Cost of raw material + 'I': 2.5, # Cost of reactor I + 'II': 1.5, # Cost of reactor II + }, + ) + m.alpha = Param( + ['I', 'II'], doc="Reactor coefficient", initialize={'I': -8, 'II': -10} + ) + m.beta = Param( + ['I', 'II'], doc="Reactor coefficient", initialize={'I': 9, 'II': 15} + ) + m.X_LB = Param( + ['I', 'II'], + doc="Reactor conversion lower bound", + initialize={'I': 0.2, 'II': 0.7}, + ) + m.X_UB = Param( + ['I', 'II'], + doc="Reactor conversion upper bound", + initialize={'I': 0.95, 'II': 0.99}, + ) m.C_rxn = Var(bounds=(1.5, 2.5), doc="Cost of reactor") - m.reactor_choice = Disjunction(expr=[ - # Disjunct 1: Choose reactor I - [m.F == m.alpha['I'] * m.X + m.beta['I'], - m.X_LB['I'] <= m.X, - m.X <= m.X_UB['I'], - m.C_rxn == m.c['I']], - # Disjunct 2: Choose reactor II - [m.F == m.alpha['II'] * m.X + m.beta['II'], - m.X_LB['II'] <= m.X, - m.X <= m.X_UB['II'], - m.C_rxn == m.c['II']] - ], xor=True) + m.reactor_choice = Disjunction( + expr=[ + # Disjunct 1: Choose reactor I + [ + m.F == m.alpha['I'] * m.X + m.beta['I'], + m.X_LB['I'] <= m.X, + m.X <= m.X_UB['I'], + m.C_rxn == m.c['I'], + ], + # Disjunct 2: Choose reactor II + [ + m.F == m.alpha['II'] * m.X + m.beta['II'], + m.X_LB['II'] <= m.X, + m.X <= m.X_UB['II'], + m.C_rxn == m.c['II'], + ], + ], + xor=True, + ) if use_mccormick: m.P = Var(bounds=(0, 8), doc="McCormick approximation of F*X") m.mccormick_1 = Constraint( expr=m.P <= m.F.lb * m.X + m.F * m.X.ub - m.F.lb * m.X.ub, - doc="McCormick overestimator") + doc="McCormick overestimator", + ) m.mccormick_2 = Constraint( expr=m.P <= m.F.ub * m.X + m.F * m.X.lb - m.F.ub * m.X.lb, - doc="McCormick underestimator") + doc="McCormick underestimator", + ) m.max_demand = Constraint(expr=m.P <= m.d, doc="product demand") - m.profit = Objective( - expr=m.c[1] * m.P - m.c[2] * m.F - m.C_rxn, sense=maximize) + m.profit = Objective(expr=m.c[1] * m.P - m.c[2] * m.F - m.C_rxn, sense=maximize) else: m.max_demand = Constraint(expr=m.F * m.X <= m.d, doc="product demand") m.profit = Objective( - expr=m.c[1] * m.F * m.X - m.c[2] * m.F - m.C_rxn, sense=maximize) + expr=m.c[1] * m.F * m.X - m.c[2] * m.F - m.C_rxn, sense=maximize + ) return m diff --git a/examples/kernel/blocks.py b/examples/kernel/blocks.py index 3420d239a6b..7036981dcc8 100644 --- a/examples/kernel/blocks.py +++ b/examples/kernel/blocks.py @@ -7,50 +7,47 @@ # define a simple optimization model b = pmo.block() b.x = pmo.variable() -b.c = pmo.constraint(expr= b.x >= 1) -b.o = pmo.objective(expr= b.x) +b.c = pmo.constraint(expr=b.x >= 1) +b.o = pmo.objective(expr=b.x) # define an optimization model with indexed containers b = pmo.block() b.p = pmo.parameter() -b.plist = pmo.parameter_list(pmo.parameter() - for i in range(10)) -b.pdict = pmo.parameter_dict(((i,j), pmo.parameter()) - for i in range(10) - for j in range(10)) +b.plist = pmo.parameter_list(pmo.parameter() for i in range(10)) +b.pdict = pmo.parameter_dict( + ((i, j), pmo.parameter()) for i in range(10) for j in range(10) +) b.x = pmo.variable() -b.xlist = pmo.variable_list(pmo.variable() - for i in range(10)) -b.xdict = pmo.variable_dict(((i,j), pmo.variable()) - for i in range(10) - for j in range(10)) +b.xlist = pmo.variable_list(pmo.variable() for i in range(10)) +b.xdict = pmo.variable_dict( + ((i, j), pmo.variable()) for i in range(10) for j in range(10) +) b.c = pmo.constraint(b.x >= 1) -b.clist = pmo.constraint_list( - pmo.constraint(b.xlist[i] >= i) - for i in range(10)) +b.clist = pmo.constraint_list(pmo.constraint(b.xlist[i] >= i) for i in range(10)) b.cdict = pmo.constraint_dict( - ((i,j), pmo.constraint(b.xdict[i,j] >= i * j)) + ((i, j), pmo.constraint(b.xdict[i, j] >= i * j)) for i in range(10) - for j in range(10)) + for j in range(10) +) -b.o = pmo.objective( - b.x + sum(b.xlist) + sum(b.xdict.values())) +b.o = pmo.objective(b.x + sum(b.xlist) + sum(b.xdict.values())) # # Define a custom block # + class Widget(pmo.block): def __init__(self, p, input=None): super(Widget, self).__init__() self.p = pmo.parameter(value=p) self.input = pmo.expression(expr=input) self.output = pmo.variable() - self.c = pmo.constraint( - self.output == self.input**2 / self.p) + self.c = pmo.constraint(self.output == self.input**2 / self.p) + b = pmo.block() b.x = pmo.variable() diff --git a/examples/kernel/conic.py b/examples/kernel/conic.py index 9de5c106a0f..a2a787794a4 100644 --- a/examples/kernel/conic.py +++ b/examples/kernel/conic.py @@ -4,27 +4,23 @@ # Specialized Conic Constraints # -c = pmo.conic.quadratic( - r=pmo.variable(lb=0), - x=[pmo.variable(), pmo.variable()]) +c = pmo.conic.quadratic(r=pmo.variable(lb=0), x=[pmo.variable(), pmo.variable()]) assert not c.has_lb() assert c.has_ub() and (c.ub == 0) assert c.check_convexity_conditions() print(c.body) c = pmo.conic.rotated_quadratic( - r1=pmo.variable(lb=0), - r2=pmo.variable(lb=0), - x=[pmo.variable(), pmo.variable()]) + r1=pmo.variable(lb=0), r2=pmo.variable(lb=0), x=[pmo.variable(), pmo.variable()] +) assert not c.has_lb() assert c.has_ub() and (c.ub == 0) assert c.check_convexity_conditions() print(c.body) c = pmo.conic.primal_exponential( - r=pmo.variable(lb=0), - x1=pmo.variable(lb=0), - x2=pmo.variable()) + r=pmo.variable(lb=0), x1=pmo.variable(lb=0), x2=pmo.variable() +) assert not c.has_lb() assert c.has_ub() and (c.ub == 0) assert c.check_convexity_conditions() @@ -34,16 +30,16 @@ r1=pmo.variable(lb=0), r2=pmo.variable(lb=0), x=[pmo.variable(), pmo.variable()], - alpha=0.5) + alpha=0.5, +) assert not c.has_lb() assert c.has_ub() and (c.ub == 0) assert c.check_convexity_conditions() print(c.body) c = pmo.conic.dual_exponential( - r=pmo.variable(lb=0), - x1=pmo.variable(), - x2=pmo.variable(ub=0)) + r=pmo.variable(lb=0), x1=pmo.variable(), x2=pmo.variable(ub=0) +) assert not c.has_lb() assert c.has_ub() and (c.ub == 0) assert c.check_convexity_conditions() @@ -53,7 +49,8 @@ r1=pmo.variable(lb=0), r2=pmo.variable(lb=0), x=[pmo.variable(), pmo.variable()], - alpha=0.5) + alpha=0.5, +) assert not c.has_lb() assert c.has_ub() and (c.ub == 0) assert c.check_convexity_conditions() @@ -67,8 +64,8 @@ # b = pmo.conic.quadratic.as_domain( - r=0.5*pmo.variable(lb=0), - x=[pmo.variable() + 1, 1.5, None, None]) + r=0.5 * pmo.variable(lb=0), x=[pmo.variable() + 1, 1.5, None, None] +) assert type(b.q) is pmo.conic.quadratic assert type(b.c) is pmo.constraint_tuple assert len(b.c) == 3 diff --git a/examples/kernel/constraints.py b/examples/kernel/constraints.py index 809efa4f690..6495ad12f63 100644 --- a/examples/kernel/constraints.py +++ b/examples/kernel/constraints.py @@ -8,7 +8,7 @@ c = pmo.constraint(v == 1) -c = pmo.constraint(expr= v == 1) +c = pmo.constraint(expr=v == 1) c = pmo.constraint(body=v, rhs=1) @@ -22,7 +22,7 @@ c = pmo.constraint(v <= 1) -c = pmo.constraint(expr= v <= 1) +c = pmo.constraint(expr=v <= 1) c = pmo.constraint(body=v, ub=1) @@ -32,7 +32,7 @@ c = pmo.constraint(v >= 1) -c = pmo.constraint(expr= v >= 1) +c = pmo.constraint(expr=v >= 1) c = pmo.constraint(body=v, lb=1) @@ -46,7 +46,7 @@ c = pmo.constraint((0, v, 1)) -c = pmo.constraint(expr= (0, v, 1)) +c = pmo.constraint(expr=(0, v, 1)) c = pmo.constraint(lb=0, body=v, ub=1) diff --git a/examples/kernel/containers.py b/examples/kernel/containers.py index f15c41b4e19..9b525e87af6 100644 --- a/examples/kernel/containers.py +++ b/examples/kernel/containers.py @@ -4,14 +4,13 @@ # List containers # -vl = pmo.variable_list( - pmo.variable() for i in range(10)) +vl = pmo.variable_list(pmo.variable() for i in range(10)) cl = pmo.constraint_list() for i in range(10): cl.append(pmo.constraint(vl[-1] == 1)) -cl.insert(0, pmo.constraint(vl[0]**2 >= 1)) +cl.insert(0, pmo.constraint(vl[0] ** 2 >= 1)) del cl[0] @@ -19,18 +18,16 @@ # Dict containers # -vd = pmo.variable_dict( - ((str(i), pmo.variable()) for i in range(10))) +vd = pmo.variable_dict(((str(i), pmo.variable()) for i in range(10))) -cd = pmo.constraint_dict( - (i, pmo.constraint(v == 1)) for i,v in vd.items()) +cd = pmo.constraint_dict((i, pmo.constraint(v == 1)) for i, v in vd.items()) cd = pmo.constraint_dict() for i, v in vd.items(): cd[i] = pmo.constraint(v == 1) cd = pmo.constraint_dict() -cd.update((i, pmo.constraint()) for i,v in vd.items()) +cd.update((i, pmo.constraint()) for i, v in vd.items()) cd[None] = pmo.constraint() diff --git a/examples/kernel/expressions.py b/examples/kernel/expressions.py index be083b82208..1756e5d3fd4 100644 --- a/examples/kernel/expressions.py +++ b/examples/kernel/expressions.py @@ -10,7 +10,7 @@ assert e() == None assert e.expr == None -e = pmo.expression(expr= v**2 + 1) +e = pmo.expression(expr=v**2 + 1) assert e() == 5 assert pmo.value(e) == 5 assert pmo.value(e.expr) == 5 @@ -19,8 +19,8 @@ e.expr = v - 1 assert pmo.value(e) == 1 -esub = pmo.expression(expr= v + 1) -e = pmo.expression(expr= esub + 1) +esub = pmo.expression(expr=v + 1) +e = pmo.expression(expr=esub + 1) assert pmo.value(esub) == 3 assert pmo.value(e) == 4 @@ -47,6 +47,6 @@ assert pmo.value(c.lb) == 0 # the following will result in an error -#e = pmo.expression() -#c = pmo.constraint() -#c.lb = e +# e = pmo.expression() +# c = pmo.constraint() +# c.lb = e diff --git a/examples/kernel/mosek/geometric1.py b/examples/kernel/mosek/geometric1.py index b75f0ed5da3..729df680976 100644 --- a/examples/kernel/mosek/geometric1.py +++ b/examples/kernel/mosek/geometric1.py @@ -2,6 +2,7 @@ import pyomo.kernel as pmo + def solve_nonlinear(Aw, Af, alpha, beta, gamma, delta): m = pmo.block() @@ -10,31 +11,27 @@ def solve_nonlinear(Aw, Af, alpha, beta, gamma, delta): m.w = pmo.variable(lb=0) m.d = pmo.variable(lb=0) - m.c = pmo.constraint_tuple([ - pmo.constraint(body=2*(m.h*m.w + m.h*m.d), ub=Aw), - pmo.constraint(body=m.w*m.d, - ub=Af), - pmo.constraint(lb=alpha, - body=m.h/m.w, - ub=beta), - pmo.constraint(lb=gamma, - body=m.d/m.w, - ub=delta)]) - - m.o = pmo.objective(m.h * m.w * m.d, - sense=pmo.maximize) - - m.h.value, m.w.value, m.d.value = (1,1,1) + m.c = pmo.constraint_tuple( + [ + pmo.constraint(body=2 * (m.h * m.w + m.h * m.d), ub=Aw), + pmo.constraint(body=m.w * m.d, ub=Af), + pmo.constraint(lb=alpha, body=m.h / m.w, ub=beta), + pmo.constraint(lb=gamma, body=m.d / m.w, ub=delta), + ] + ) + + m.o = pmo.objective(m.h * m.w * m.d, sense=pmo.maximize) + + m.h.value, m.w.value, m.d.value = (1, 1, 1) ipopt = pmo.SolverFactory("ipopt") result = ipopt.solve(m) assert str(result.solver.termination_condition) == "optimal" print("nonlinear solution:") - print("h: {0:.4f}, w: {1:.4f}, d: {2:.4f}".\ - format(m.h(), m.w(), m.d())) - print("volume: {0: .5f}".\ - format(m.o())) + print("h: {0:.4f}, w: {1:.4f}, d: {2:.4f}".format(m.h(), m.w(), m.d())) + print("volume: {0: .5f}".format(m.o())) print("") + def solve_conic(Aw, Af, alpha, beta, gamma, delta): m = pmo.block() @@ -43,43 +40,39 @@ def solve_conic(Aw, Af, alpha, beta, gamma, delta): m.y = pmo.variable() m.z = pmo.variable() - m.k = pmo.block_tuple([ - pmo.conic.primal_exponential.\ - as_domain(r=None, - x1=1, - x2=m.x + m.y + pmo.log(2.0/Aw)), - pmo.conic.primal_exponential.\ - as_domain(r=None, - x1=1, - x2=m.x + m.z + pmo.log(2.0/Aw))]) - - m.c = pmo.constraint_tuple([ - pmo.constraint(body=m.k[0].r + m.k[1].r, - ub=1), - pmo.constraint(body=m.y + m.z, ub=pmo.log(Af)), - pmo.constraint(lb=pmo.log(alpha), - body=m.x - m.y, - ub=pmo.log(beta)), - pmo.constraint(lb=pmo.log(gamma), - body=m.z - m.y, - ub=pmo.log(delta))]) - - m.o = pmo.objective(m.x + m.y + m.z, - sense=pmo.maximize) + m.k = pmo.block_tuple( + [ + pmo.conic.primal_exponential.as_domain( + r=None, x1=1, x2=m.x + m.y + pmo.log(2.0 / Aw) + ), + pmo.conic.primal_exponential.as_domain( + r=None, x1=1, x2=m.x + m.z + pmo.log(2.0 / Aw) + ), + ] + ) + + m.c = pmo.constraint_tuple( + [ + pmo.constraint(body=m.k[0].r + m.k[1].r, ub=1), + pmo.constraint(body=m.y + m.z, ub=pmo.log(Af)), + pmo.constraint(lb=pmo.log(alpha), body=m.x - m.y, ub=pmo.log(beta)), + pmo.constraint(lb=pmo.log(gamma), body=m.z - m.y, ub=pmo.log(delta)), + ] + ) + + m.o = pmo.objective(m.x + m.y + m.z, sense=pmo.maximize) mosek = pmo.SolverFactory("mosek_direct") result = mosek.solve(m) assert str(result.solver.termination_condition) == "optimal" h, w, d = pmo.exp(m.x()), pmo.exp(m.y()), pmo.exp(m.z()) print("conic solution:") - print("h: {0:.4f}, w: {1:.4f}, d: {2:.4f}".\ - format(h, w, d)) - print("volume: {0: .5f}".\ - format(h*w*d)) + print("h: {0:.4f}, w: {1:.4f}, d: {2:.4f}".format(h, w, d)) + print("volume: {0: .5f}".format(h * w * d)) print("") + if __name__ == "__main__": - Aw, Af, alpha, beta, gamma, delta = \ - 200.0, 50.0, 2.0, 10.0, 2.0, 10.0 + Aw, Af, alpha, beta, gamma, delta = 200.0, 50.0, 2.0, 10.0, 2.0, 10.0 solve_nonlinear(Aw, Af, alpha, beta, gamma, delta) solve_conic(Aw, Af, alpha, beta, gamma, delta) diff --git a/examples/kernel/mosek/geometric2.py b/examples/kernel/mosek/geometric2.py index 8a6d5074ce3..048cb9ff193 100644 --- a/examples/kernel/mosek/geometric2.py +++ b/examples/kernel/mosek/geometric2.py @@ -3,6 +3,7 @@ import pyomo.kernel as pmo + def solve_nonlinear(): m = pmo.block() @@ -11,26 +12,25 @@ def solve_nonlinear(): m.y = pmo.variable() m.z = pmo.variable() - m.c = pmo.constraint_tuple([ - pmo.constraint(body=0.1*pmo.sqrt(m.x) + (2.0/m.y), - ub=1), - pmo.constraint(body=(1.0/m.z) + (m.y/(m.x**2)), - ub=1)]) + m.c = pmo.constraint_tuple( + [ + pmo.constraint(body=0.1 * pmo.sqrt(m.x) + (2.0 / m.y), ub=1), + pmo.constraint(body=(1.0 / m.z) + (m.y / (m.x**2)), ub=1), + ] + ) - m.o = pmo.objective(m.x + (m.y**2)*m.z, - sense=pmo.minimize) + m.o = pmo.objective(m.x + (m.y**2) * m.z, sense=pmo.minimize) - m.x.value, m.y.value, m.z.value = (1,1,1) + m.x.value, m.y.value, m.z.value = (1, 1, 1) ipopt = pmo.SolverFactory("ipopt") result = ipopt.solve(m) assert str(result.solver.termination_condition) == "optimal" print("nonlinear solution:") - print("x: {0:.4f}, y: {1:.4f}, z: {2:.4f}".\ - format(m.x(), m.y(), m.z())) - print("objective: {0: .5f}".\ - format(m.o())) + print("x: {0:.4f}, y: {1:.4f}, z: {2:.4f}".format(m.x(), m.y(), m.z())) + print("objective: {0: .5f}".format(m.o())) print("") + def solve_conic(): m = pmo.block() @@ -40,57 +40,44 @@ def solve_conic(): m.v = pmo.variable() m.w = pmo.variable() - m.k = pmo.block_tuple([ - # exp(u-t) + exp(2v + w - t) <= 1 - pmo.conic.primal_exponential.\ - as_domain(r=None, - x1=1, - x2=m.u - m.t), - pmo.conic.primal_exponential.\ - as_domain(r=None, - x1=1, - x2=2*m.v + m.w - m.t), - # exp(0.5u + log(0.1)) + exp(-v + log(2)) <= 1 - pmo.conic.primal_exponential.\ - as_domain(r=None, - x1=1, - x2=0.5*m.u + pmo.log(0.1)), - pmo.conic.primal_exponential.\ - as_domain(r=None, - x1=1, - x2=-m.v + pmo.log(2)), - # exp(-w) + exp(v-2u) <= 1 - pmo.conic.primal_exponential.\ - as_domain(r=None, - x1=1, - x2=-m.w), - pmo.conic.primal_exponential.\ - as_domain(r=None, - x1=1, - x2=m.v - 2*m.u)]) - - m.c = pmo.constraint_tuple([ - pmo.constraint(body=m.k[0].r + m.k[1].r, - ub=1), - pmo.constraint(body=m.k[2].r + m.k[3].r, - ub=1), - pmo.constraint(body=m.k[4].r + m.k[5].r, - ub=1)]) - - m.o = pmo.objective(m.t, - sense=pmo.minimize) + m.k = pmo.block_tuple( + [ + # exp(u-t) + exp(2v + w - t) <= 1 + pmo.conic.primal_exponential.as_domain(r=None, x1=1, x2=m.u - m.t), + pmo.conic.primal_exponential.as_domain( + r=None, x1=1, x2=2 * m.v + m.w - m.t + ), + # exp(0.5u + log(0.1)) + exp(-v + log(2)) <= 1 + pmo.conic.primal_exponential.as_domain( + r=None, x1=1, x2=0.5 * m.u + pmo.log(0.1) + ), + pmo.conic.primal_exponential.as_domain(r=None, x1=1, x2=-m.v + pmo.log(2)), + # exp(-w) + exp(v-2u) <= 1 + pmo.conic.primal_exponential.as_domain(r=None, x1=1, x2=-m.w), + pmo.conic.primal_exponential.as_domain(r=None, x1=1, x2=m.v - 2 * m.u), + ] + ) + + m.c = pmo.constraint_tuple( + [ + pmo.constraint(body=m.k[0].r + m.k[1].r, ub=1), + pmo.constraint(body=m.k[2].r + m.k[3].r, ub=1), + pmo.constraint(body=m.k[4].r + m.k[5].r, ub=1), + ] + ) + + m.o = pmo.objective(m.t, sense=pmo.minimize) mosek = pmo.SolverFactory("mosek_direct") result = mosek.solve(m) assert str(result.solver.termination_condition) == "optimal" x, y, z = pmo.exp(m.u()), pmo.exp(m.v()), pmo.exp(m.w()) print("conic solution:") - print("x: {0:.4f}, y: {1:.4f}, z: {2:.4f}".\ - format(x, y, z)) - print("objective: {0: .5f}".\ - format(x + (y**2)*z)) + print("x: {0:.4f}, y: {1:.4f}, z: {2:.4f}".format(x, y, z)) + print("objective: {0: .5f}".format(x + (y**2) * z)) print("") + if __name__ == "__main__": solve_nonlinear() solve_conic() diff --git a/examples/kernel/mosek/maximum_volume_cuboid.py b/examples/kernel/mosek/maximum_volume_cuboid.py index 080ef3a9886..92e210cf400 100644 --- a/examples/kernel/mosek/maximum_volume_cuboid.py +++ b/examples/kernel/mosek/maximum_volume_cuboid.py @@ -8,34 +8,42 @@ import pyomo.kernel as pmo # Vertices of a regular icosahedron with edge length 2 -f = (1+np.sqrt(5))/2 -icosahedron = np.array([[0, 1, f], - [0, -1, f], - [0, 1, -f], - [0, -1, -f], - [1, f, 0], - [1, -f, 0], - [-1, f, 0], - [-1, -f, 0], - [f, 0, 1], - [-f, 0, 1], - [f, 0, -1], - [-f, 0, -1]]) +f = (1 + np.sqrt(5)) / 2 +icosahedron = np.array( + [ + [0, 1, f], + [0, -1, f], + [0, 1, -f], + [0, -1, -f], + [1, f, 0], + [1, -f, 0], + [-1, f, 0], + [-1, -f, 0], + [f, 0, 1], + [-f, 0, 1], + [f, 0, -1], + [-f, 0, -1], + ] +) print(f"Volume of the icosahedron = {2.18169699*8}") def convex_hull_constraint(model, p_v, c_v, v_index): - A = np.vstack((np.eye(len(model.p)), # p-variable coefficients - np.diag(c_v), # x-variable coefficients - p_v)) # u-variable coefficients + A = np.vstack( + ( + np.eye(len(model.p)), # p-variable coefficients + np.diag(c_v), # x-variable coefficients + p_v, + ) + ) # u-variable coefficients A = np.transpose(A) # Sum(u_i) = 1 - row = [0]*len(list(model.p)+list(model.x)) + [1]*len(model.u[v_index]) + row = [0] * len(list(model.p) + list(model.x)) + [1] * len(model.u[v_index]) A = np.vstack([A, row]) # x var_vector = list(model.p) + list(model.x) + list(model.u[v_index]) # b - b = np.array([0]*A.shape[0]) + b = np.array([0] * A.shape[0]) b[-1] = 1 # Matrix constraint ( Ax = b ) @@ -53,8 +61,9 @@ def pyomo_maxVolCuboid(vertices): model.p = pmo.variable_list(pmo.variable() for i in range(n)) model.t = pmo.variable() - model.u = pmo.variable_list(pmo.variable_list( - pmo.variable(lb=0.0) for j in range(m)) for i in range(2**n)) + model.u = pmo.variable_list( + pmo.variable_list(pmo.variable(lb=0.0) for j in range(m)) for i in range(2**n) + ) # Maximize: (volume_of_cuboid)**1/n model.cuboid_volume = pmo.objective(model.t, sense=-1) @@ -64,15 +73,16 @@ def pyomo_maxVolCuboid(vertices): # K : Convex hull formed by the vertices of the polyhedron model.conv_hull = pmo.constraint_list() for i in range(2**n): - model.conv_hull.append(convex_hull_constraint( - model, vertices, model.cuboid_vertices[i], i)) + model.conv_hull.append( + convex_hull_constraint(model, vertices, model.cuboid_vertices[i], i) + ) opt = pmo.SolverFactory("mosek") result = opt.solve(model, tee=True) _x = np.array([x.value for x in model.x]) _p = np.array([p.value for p in model.p]) - cuboid_vertices = np.array([_p + e*_x for e in model.cuboid_vertices]) + cuboid_vertices = np.array([_p + e * _x for e in model.cuboid_vertices]) return cuboid_vertices @@ -93,8 +103,9 @@ def inscribed_cuboid_plot(icosahedron, cuboid): tri.set_alpha(0.3) tri.set_facecolor('red') ax.add_collection3d(tri) - ax.scatter(icosahedron[:, 0], icosahedron[:, 1], - icosahedron[:, 2], color='darkred') + ax.scatter( + icosahedron[:, 0], icosahedron[:, 1], icosahedron[:, 2], color='darkred' + ) cub_hull = ConvexHull(cuboid) for s in cub_hull.simplices: diff --git a/examples/kernel/mosek/power1.py b/examples/kernel/mosek/power1.py index acbf2633f54..6ef723595a8 100644 --- a/examples/kernel/mosek/power1.py +++ b/examples/kernel/mosek/power1.py @@ -2,6 +2,7 @@ import pyomo.kernel as pmo + def solve_nonlinear(): m = pmo.block() @@ -10,23 +11,22 @@ def solve_nonlinear(): m.y = pmo.variable(lb=0) m.z = pmo.variable(lb=0) - m.c = pmo.constraint(body=m.x + m.y + 0.5*m.z, - rhs=2) + m.c = pmo.constraint(body=m.x + m.y + 0.5 * m.z, rhs=2) - m.o = pmo.objective((m.x**0.2)*(m.y**0.8) + (m.z**0.4) - m.x, - sense=pmo.maximize) + m.o = pmo.objective( + (m.x**0.2) * (m.y**0.8) + (m.z**0.4) - m.x, sense=pmo.maximize + ) - m.x.value, m.y.value, m.z.value = (1,1,1) + m.x.value, m.y.value, m.z.value = (1, 1, 1) ipopt = pmo.SolverFactory("ipopt") result = ipopt.solve(m) assert str(result.solver.termination_condition) == "optimal" print("nonlinear solution:") - print("x: {0:.4f}, y: {1:.4f}, z: {2:.4f}".\ - format(m.x(), m.y(), m.z())) - print("objective: {0: .5f}".\ - format(m.o())) + print("x: {0:.4f}, y: {1:.4f}, z: {2:.4f}".format(m.x(), m.y(), m.z())) + print("objective: {0: .5f}".format(m.o())) print("") + def solve_conic(): m = pmo.block() @@ -39,32 +39,26 @@ def solve_conic(): m.q = pmo.variable() m.r = pmo.variable(lb=0) - m.k = pmo.block_tuple([ - pmo.conic.primal_power.as_domain(r1=m.x, - r2=m.y, - x=[None], - alpha=0.2), - pmo.conic.primal_power.as_domain(r1=m.z, - r2=1, - x=[None], - alpha=0.4)]) + m.k = pmo.block_tuple( + [ + pmo.conic.primal_power.as_domain(r1=m.x, r2=m.y, x=[None], alpha=0.2), + pmo.conic.primal_power.as_domain(r1=m.z, r2=1, x=[None], alpha=0.4), + ] + ) - m.c = pmo.constraint(body=m.x + m.y + 0.5*m.z, - rhs=2) + m.c = pmo.constraint(body=m.x + m.y + 0.5 * m.z, rhs=2) - m.o = pmo.objective(m.k[0].x[0] + m.k[1].x[0] - m.x, - sense=pmo.maximize) + m.o = pmo.objective(m.k[0].x[0] + m.k[1].x[0] - m.x, sense=pmo.maximize) mosek = pmo.SolverFactory("mosek_direct") result = mosek.solve(m) assert str(result.solver.termination_condition) == "optimal" print("conic solution:") - print("x: {0:.4f}, y: {1:.4f}, z: {2:.4f}".\ - format(m.x(), m.y(), m.z())) - print("objective: {0: .5f}".\ - format(m.o())) + print("x: {0:.4f}, y: {1:.4f}, z: {2:.4f}".format(m.x(), m.y(), m.z())) + print("objective: {0: .5f}".format(m.o())) print("") + if __name__ == "__main__": solve_nonlinear() solve_conic() diff --git a/examples/kernel/mosek/semidefinite.py b/examples/kernel/mosek/semidefinite.py index a48efcc6854..44ab7c95a68 100644 --- a/examples/kernel/mosek/semidefinite.py +++ b/examples/kernel/mosek/semidefinite.py @@ -20,7 +20,7 @@ def primal_sdo1(): # Problem data d = 3 - n = int(d*(d+1)/2) + n = int(d * (d + 1) / 2) # PSD matrices # NOTE: As the matrices are symmetric (required) @@ -38,26 +38,32 @@ def primal_sdo1(): # CONSTRAINTS # Linear - model.c1 = pmo.constraint(sum_product( - barA1, model.X, index=list(range(n))) + model.x[0] == 1) - model.c2 = pmo.constraint(sum_product( - barA2, model.X, index=list(range(n))) + model.x[1] + model.x[2] == 0.5) + model.c1 = pmo.constraint( + sum_product(barA1, model.X, index=list(range(n))) + model.x[0] == 1 + ) + model.c2 = pmo.constraint( + sum_product(barA2, model.X, index=list(range(n))) + model.x[1] + model.x[2] + == 0.5 + ) # Conic model.quad_cone = pmo.conic.quadratic(r=model.x[0], x=model.x[1:]) # Off-diagonal elements need to be scaled by sqrt(2) in SVEC_PSD domain scale = [1, np.sqrt(2), np.sqrt(2), 1, np.sqrt(2), 1] model.psd_cone = pmo.conic.svec_psdcone.as_domain( - x=[model.X[i]*scale[i] for i in range(n)]) + x=[model.X[i] * scale[i] for i in range(n)] + ) # OBJECTIVE - model.obj = pmo.objective(sum_product( - barC, model.X, index=list(range(n))) + model.x[0]) + model.obj = pmo.objective( + sum_product(barC, model.X, index=list(range(n))) + model.x[0] + ) msk = pmo.SolverFactory('mosek') results = msk.solve(model, tee=True) return results + # GENERAL SDP (DUAL FORM) # # max. b*y @@ -70,12 +76,10 @@ def primal_sdo1(): def dual_sdo1(): # Problem data d = 3 - n = int(d*(d+1)/2) + n = int(d * (d + 1) / 2) c = [1, 0, 0] - a_T = [[1, 0], - [0, 1], - [0, 1]] + a_T = [[1, 0], [0, 1], [0, 1]] # PSD matrices barC = [2, np.sqrt(2), 0, 2, np.sqrt(2), 2] @@ -88,16 +92,20 @@ def dual_sdo1(): model.y = pmo.variable_list(pmo.variable() for i in range(2)) # CONSTRAINTS - e1 = pmo.expression_list(pmo.expression( - barC[i] - model.y[0]*barA1[i] - model.y[1]*barA2[i]) for i in range(n)) + e1 = pmo.expression_list( + pmo.expression(barC[i] - model.y[0] * barA1[i] - model.y[1] * barA2[i]) + for i in range(n) + ) model.psd_cone = pmo.conic.svec_psdcone.as_domain(x=e1) - e2 = pmo.expression_list(pmo.expression( - c[i] - sum_product(a_T[i], model.y, index=[0, 1])) for i in range(3)) + e2 = pmo.expression_list( + pmo.expression(c[i] - sum_product(a_T[i], model.y, index=[0, 1])) + for i in range(3) + ) model.quad_cone = pmo.conic.quadratic.as_domain(r=e2[0], x=e2[1:]) # OBJECTIVE - model.obj = pmo.objective(model.y[0] + 0.5*model.y[1], sense=-1) + model.obj = pmo.objective(model.y[0] + 0.5 * model.y[1], sense=-1) msk = pmo.SolverFactory('mosek') results = msk.solve(model, tee=True) diff --git a/examples/kernel/objectives.py b/examples/kernel/objectives.py index 4eb97a2c317..7d87671ef8d 100644 --- a/examples/kernel/objectives.py +++ b/examples/kernel/objectives.py @@ -10,7 +10,7 @@ assert o() == None assert o.expr == None -o = pmo.objective(expr= v**2 + 1) +o = pmo.objective(expr=v**2 + 1) assert o() == 5 assert pmo.value(o) == 5 assert pmo.value(o.expr) == 5 @@ -19,8 +19,8 @@ o.expr = v - 1 assert pmo.value(o) == 1 -osub = pmo.objective(expr= v + 1) -o = pmo.objective(expr= osub + 1) +osub = pmo.objective(expr=v + 1) +o = pmo.objective(expr=osub + 1) assert pmo.value(osub) == 3 assert pmo.value(o) == 4 diff --git a/examples/kernel/parameters.py b/examples/kernel/parameters.py index 09f98c638b5..55b230add6b 100644 --- a/examples/kernel/parameters.py +++ b/examples/kernel/parameters.py @@ -16,7 +16,7 @@ assert pmo.value(p - 1) == 3 v = pmo.variable() -c = pmo.constraint((p-1, v, p+1)) +c = pmo.constraint((p - 1, v, p + 1)) assert pmo.value(c.lb) == 3 assert pmo.value(c.ub) == 5 diff --git a/examples/kernel/piecewise_functions.py b/examples/kernel/piecewise_functions.py index 2cfe80019f5..528d4c16791 100644 --- a/examples/kernel/piecewise_functions.py +++ b/examples/kernel/piecewise_functions.py @@ -4,17 +4,12 @@ # Piecewise linear constraints # -breakpoints = [1,2,3,4] -values = [1,2,1,2] +breakpoints = [1, 2, 3, 4] +values = [1, 2, 1, 2] x = pmo.variable(lb=1, ub=4) y = pmo.variable() -p = pmo.piecewise(breakpoints, - values, - input=x, - output=y, - repn='sos2', - bound='eq') +p = pmo.piecewise(breakpoints, values, input=x, output=y, repn='sos2', bound='eq') # change the input and output variables z = pmo.variable(lb=1, ub=4) @@ -35,21 +30,16 @@ assert p(2.5) == 1.5 assert p(4) == 2 -breakpoints = [pmo.parameter(1), - pmo.parameter(2), - pmo.parameter(3), - pmo.parameter(None)] -values = [pmo.parameter(1), - pmo.parameter(2), - pmo.parameter(1), - pmo.parameter(None)] -p = pmo.piecewise(breakpoints, - values, - input=x, - output=y, - repn='sos2', - bound='eq', - validate=False) +breakpoints = [ + pmo.parameter(1), + pmo.parameter(2), + pmo.parameter(3), + pmo.parameter(None), +] +values = [pmo.parameter(1), pmo.parameter(2), pmo.parameter(1), pmo.parameter(None)] +p = pmo.piecewise( + breakpoints, values, input=x, output=y, repn='sos2', bound='eq', validate=False +) # change the function parameters and # validate that the inputs are correct @@ -79,8 +69,4 @@ m.o = pmo.objective(m.y) -m.pw = pmo.piecewise(breakpoints, - function_points, - input=m.x, - output=m.y, - repn='inc') +m.pw = pmo.piecewise(breakpoints, function_points, input=m.x, output=m.y, repn='inc') diff --git a/examples/kernel/piecewise_nd_functions.py b/examples/kernel/piecewise_nd_functions.py index 639a065b53b..d9d32d9d6aa 100644 --- a/examples/kernel/piecewise_nd_functions.py +++ b/examples/kernel/piecewise_nd_functions.py @@ -12,16 +12,19 @@ # Set to True to show 3d plots show_plots = False + def f(x, y, package=pmo): - return (-20 * package.exp( - -2.0 * package.sqrt(0.5 * (x**2 + y**2))) - - package.exp( - 0.5 * (package.cos(2*np.pi*x) + \ - package.cos(2*np.pi*y))) + \ - np.e + 20.0) + return ( + -20 * package.exp(-2.0 * package.sqrt(0.5 * (x**2 + y**2))) + - package.exp(0.5 * (package.cos(2 * np.pi * x) + package.cos(2 * np.pi * y))) + + np.e + + 20.0 + ) + def g(x, y, package=pmo): - return (x-3)**2 + (y-1)**2 + return (x - 3) ** 2 + (y - 1) ** 2 + m = pmo.block() m.x = pmo.variable(lb=-5, ub=5) @@ -43,19 +46,11 @@ def g(x, y, package=pmo): pw_xarray, pw_yarray = np.transpose(tri.points) fvals = f(pw_xarray, pw_yarray, package=np) -pw_f = pmo.piecewise_nd(tri, - fvals, - input=[m.x,m.y], - output=m.z, - bound='lb') +pw_f = pmo.piecewise_nd(tri, fvals, input=[m.x, m.y], output=m.z, bound='lb') m.approx.pw_f = pw_f gvals = g(pw_xarray, pw_yarray, package=np) -pw_g = pmo.piecewise_nd(tri, - gvals, - input=[m.x,m.y], - output=m.z, - bound='eq') +pw_g = pmo.piecewise_nd(tri, gvals, input=[m.x, m.y], output=m.z, bound='eq') m.approx.pw_g = pw_g # @@ -70,14 +65,10 @@ def g(x, y, package=pmo): assert str(status.solver.status) == "ok" assert str(status.solver.termination_condition) == "optimal" -print("Approximate f value at MIP solution: %s" - % (pw_f((m.x.value, m.y.value)))) -print("Approximate g value at MIP solution: %s" - % (pw_g((m.x.value, m.y.value)))) -print("Real f value at MIP solution: %s" - % (f(m.x.value, m.y.value))) -print("Real g value at MIP solution: %s" - % (g(m.x.value, m.y.value))) +print("Approximate f value at MIP solution: %s" % (pw_f((m.x.value, m.y.value)))) +print("Approximate g value at MIP solution: %s" % (pw_g((m.x.value, m.y.value)))) +print("Real f value at MIP solution: %s" % (f(m.x.value, m.y.value))) +print("Real g value at MIP solution: %s" % (g(m.x.value, m.y.value))) # # Solve the real nonlinear model using a local solver @@ -89,10 +80,8 @@ def g(x, y, package=pmo): status = ipopt.solve(m) assert str(status.solver.status) == "ok" assert str(status.solver.termination_condition) == "optimal" -print("Real f value at NL solution: %s" - % (f(m.x.value, m.y.value))) -print("Real g value at NL solution: %s" - % (f(m.x.value, m.y.value))) +print("Real f value at NL solution: %s" % (f(m.x.value, m.y.value))) +print("Real g value at NL solution: %s" % (f(m.x.value, m.y.value))) if show_plots: @@ -105,8 +94,7 @@ def g(x, y, package=pmo): fig = plt.figure() ax = fig.gca(projection='3d') - ax.plot_trisurf(pw_xarray, pw_yarray, fvals, - color='yellow', alpha=0.5) + ax.plot_trisurf(pw_xarray, pw_yarray, fvals, color='yellow', alpha=0.5) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') @@ -118,8 +106,7 @@ def g(x, y, package=pmo): fig = plt.figure() ax = fig.gca(projection='3d') - ax.plot_trisurf(pw_xarray, pw_yarray, gvals, - color='blue', alpha=0.5) + ax.plot_trisurf(pw_xarray, pw_yarray, gvals, color='blue', alpha=0.5) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') @@ -137,18 +124,13 @@ def g(x, y, package=pmo): fig = plt.figure() ax = fig.gca(projection='3d') - ax.scatter(m.x.value, m.y.value, f(m.x.value, m.y.value), - color='black', s=2**6) - ax.plot_surface(xarray, yarray, fvals, - linewidth=0, cmap=plt.cm.jet, - alpha=0.6) + ax.scatter(m.x.value, m.y.value, f(m.x.value, m.y.value), color='black', s=2**6) + ax.plot_surface(xarray, yarray, fvals, linewidth=0, cmap=plt.cm.jet, alpha=0.6) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') - ax.plot_surface(xarray, yarray, gvals, - linewidth=0, cmap=plt.cm.jet, - alpha=0.6) + ax.plot_surface(xarray, yarray, gvals, linewidth=0, cmap=plt.cm.jet, alpha=0.6) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') diff --git a/examples/kernel/special_ordered_sets.py b/examples/kernel/special_ordered_sets.py index 5bf5ed5ac15..92f7d466bfa 100644 --- a/examples/kernel/special_ordered_sets.py +++ b/examples/kernel/special_ordered_sets.py @@ -8,23 +8,23 @@ # Special Ordered Sets (Type 1) # -s = pmo.sos([v1,v2]) +s = pmo.sos([v1, v2]) assert s.level == 1 -assert s.weights == (1,2) +assert s.weights == (1, 2) assert len(s.variables) == 2 assert v1 in s assert v2 in s -s = pmo.sos([v1,v2], level=1) +s = pmo.sos([v1, v2], level=1) assert s.level == 1 -assert s.weights == (1,2) +assert s.weights == (1, 2) assert len(s.variables) == 2 assert v1 in s assert v2 in s -s = pmo.sos1([v1,v2]) +s = pmo.sos1([v1, v2]) assert s.level == 1 -assert s.weights == (1,2) +assert s.weights == (1, 2) assert len(s.variables) == 2 assert v1 in s assert v2 in s @@ -33,16 +33,16 @@ # Special Ordered Sets (Type 2) # -s = pmo.sos([v1,v2], level=2) +s = pmo.sos([v1, v2], level=2) assert s.level == 2 -assert s.weights == (1,2) +assert s.weights == (1, 2) assert len(s.variables) == 2 assert v1 in s assert v2 in s -s = pmo.sos2([v1,v2]) +s = pmo.sos2([v1, v2]) assert s.level == 2 -assert s.weights == (1,2) +assert s.weights == (1, 2) assert len(s.variables) == 2 assert v1 in s assert v2 in s @@ -51,9 +51,9 @@ # Special Ordered Sets (Type n) # -s = pmo.sos([v1,v2,v3], level=3) +s = pmo.sos([v1, v2, v3], level=3) assert s.level == 3 -assert s.weights == (1,2,3) +assert s.weights == (1, 2, 3) assert len(s.variables) == 3 assert v1 in s assert v2 in s @@ -64,22 +64,20 @@ # # using known values -s = pmo.sos([v1,v2], weights=[1.2,2.5]) -assert s.weights == (1.2,2.5) +s = pmo.sos([v1, v2], weights=[1.2, 2.5]) +assert s.weights == (1.2, 2.5) # using paramters -p = pmo.parameter_list( - pmo.parameter() for i in range(2)) -s = pmo.sos([v1,v2], weights=[p[0]**2, p[1]**2]) +p = pmo.parameter_list(pmo.parameter() for i in range(2)) +s = pmo.sos([v1, v2], weights=[p[0] ** 2, p[1] ** 2]) assert len(s.weights) == 2 p[0].value = 1 p[1].value = 2 assert tuple(pmo.value(w) for w in s.weights) == (1, 4) # using data expressions -d = pmo.expression_list( - pmo.data_expression() for i in range(2)) -s = pmo.sos([v1,v2], weights=d) +d = pmo.expression_list(pmo.data_expression() for i in range(2)) +s = pmo.sos([v1, v2], weights=d) assert len(s.weights) == 2 d[0].expr = p[0] + 1 d[1].expr = p[0] + p[1] @@ -93,15 +91,11 @@ m = pmo.block() -m.z = pmo.variable_list( - pmo.variable(lb=0) - for i in range(len(domain))) +m.z = pmo.variable_list(pmo.variable(lb=0) for i in range(len(domain))) m.y = pmo.variable() m.o = pmo.objective(m.y, sense=pmo.maximize) -m.c1 = pmo.constraint( - m.y == sum(v*z for v,z in zip(m.z, domain))) -m.c2 = pmo.constraint( - sum(m.z) == 1) +m.c1 = pmo.constraint(m.y == sum(v * z for v, z in zip(m.z, domain))) +m.c2 = pmo.constraint(sum(m.z) == 1) m.s = pmo.sos1(m.z) diff --git a/examples/kernel/suffixes.py b/examples/kernel/suffixes.py index 480d2d11863..39caa5b8652 100644 --- a/examples/kernel/suffixes.py +++ b/examples/kernel/suffixes.py @@ -7,8 +7,8 @@ # collect dual information when the model is solved b = pmo.block() b.x = pmo.variable() -b.c = pmo.constraint(expr= b.x >= 1) -b.o = pmo.objective(expr= b.x) +b.c = pmo.constraint(expr=b.x >= 1) +b.o = pmo.objective(expr=b.x) b.dual = pmo.suffix(direction=pmo.suffix.IMPORT) # suffixes behave as dictionaries that map diff --git a/examples/kernel/variables.py b/examples/kernel/variables.py index f67ffd99482..7ab571245a1 100644 --- a/examples/kernel/variables.py +++ b/examples/kernel/variables.py @@ -8,14 +8,12 @@ v = pmo.variable(domain=pmo.Reals) -v = pmo.variable(domain=pmo.NonNegativeReals, - ub=10) +v = pmo.variable(domain=pmo.NonNegativeReals, ub=10) -v = pmo.variable(domain_type=pmo.RealSet, - lb=1) +v = pmo.variable(domain_type=pmo.RealSet, lb=1) # error (because domain lower bound is finite) -#v = pmo.variable(domain=pmo.NonNegativeReals, +# v = pmo.variable(domain=pmo.NonNegativeReals, # lb=1) # @@ -26,14 +24,12 @@ v = pmo.variable(domain=pmo.Integers) -v = pmo.variable(domain=pmo.NonNegativeIntegers, - ub=10) +v = pmo.variable(domain=pmo.NonNegativeIntegers, ub=10) -v = pmo.variable(domain_type=pmo.IntegerSet, - lb=1) +v = pmo.variable(domain_type=pmo.IntegerSet, lb=1) # error (because domain upper bound is finite) -#v = pmo.variable(domain=pmo.NegativeIntegers, +# v = pmo.variable(domain=pmo.NegativeIntegers, # ub=10) # diff --git a/examples/mpec/bard1.py b/examples/mpec/bard1.py index 7ff231fe77d..dbe666a7004 100644 --- a/examples/mpec/bard1.py +++ b/examples/mpec/bard1.py @@ -17,13 +17,21 @@ model.y = Var(within=NonNegativeReals) # ... multipliers -model.l = Var([1,2,3]) - -model.f = Objective(expr=(model.x - 5)**2 + (2*model.y + 1)**2) - -model.KKT = Constraint(expr=2*(model.y-1) - 1.5*model.x + model.l[1] - model.l[2]*0.5 + model.l[3] == 0) - -model.lin_1 = Complementarity(expr=complements(0 <= 3*model.x - model.y - 3, model.l[1] >= 0)) -model.lin_2 = Complementarity(expr=complements(0 <= - model.x + 0.5*model.y + 4, model.l[2] >= 0)) -model.lin_3 = Complementarity(expr=complements(0 <= - model.x - model.y + 7, model.l[3] >= 0)) - +model.l = Var([1, 2, 3]) + +model.f = Objective(expr=(model.x - 5) ** 2 + (2 * model.y + 1) ** 2) + +model.KKT = Constraint( + expr=2 * (model.y - 1) - 1.5 * model.x + model.l[1] - model.l[2] * 0.5 + model.l[3] + == 0 +) + +model.lin_1 = Complementarity( + expr=complements(0 <= 3 * model.x - model.y - 3, model.l[1] >= 0) +) +model.lin_2 = Complementarity( + expr=complements(0 <= -model.x + 0.5 * model.y + 4, model.l[2] >= 0) +) +model.lin_3 = Complementarity( + expr=complements(0 <= -model.x - model.y + 7, model.l[3] >= 0) +) diff --git a/examples/mpec/df.py b/examples/mpec/df.py index dd6f8f4e1c0..41984992bdd 100644 --- a/examples/mpec/df.py +++ b/examples/mpec/df.py @@ -24,12 +24,12 @@ from pyomo.mpec import * M = ConcreteModel() -M.x = Var(bounds=(-1,2)) +M.x = Var(bounds=(-1, 2)) M.y = Var() -M.o = Objective(expr=(M.x - 1 - M.y)**2) +M.o = Objective(expr=(M.x - 1 - M.y) ** 2) M.c1 = Constraint(expr=M.x**2 <= 2) -M.c2 = Constraint(expr=(M.x - 1)**2 + (M.y - 1)**2 <= 3) +M.c2 = Constraint(expr=(M.x - 1) ** 2 + (M.y - 1) ** 2 <= 3) M.c3 = Complementarity(expr=complements(M.y - M.x**2 + 1 >= 0, M.y >= 0)) model = M diff --git a/examples/mpec/indexed.py b/examples/mpec/indexed.py index a96b93bda88..b69d5093477 100644 --- a/examples/mpec/indexed.py +++ b/examples/mpec/indexed.py @@ -17,12 +17,13 @@ model = ConcreteModel() -model.x = Var(RangeSet(1,n)) +model.x = Var(RangeSet(1, n)) + +model.f = Objective(expr=sum(i * (model.x[i] - 1) ** 2 for i in range(1, n + 1))) -model.f = Objective(expr=sum(i*(model.x[i]-1)**2 - for i in range(1,n+1))) def compl_(model, i): - return complements(model.x[i] >= 0, model.x[i+1] >= 0) -model.compl = Complementarity(RangeSet(1,n-1), rule=compl_) + return complements(model.x[i] >= 0, model.x[i + 1] >= 0) + +model.compl = Complementarity(RangeSet(1, n - 1), rule=compl_) diff --git a/examples/mpec/linear1.py b/examples/mpec/linear1.py index fd9c37c007d..eba04759ae3 100644 --- a/examples/mpec/linear1.py +++ b/examples/mpec/linear1.py @@ -19,10 +19,9 @@ a = 100 model = ConcreteModel() -model.x1 = Var(bounds=(-2,2)) -model.x2 = Var(bounds=(-1,1)) +model.x1 = Var(bounds=(-2, 2)) +model.x2 = Var(bounds=(-1, 1)) -model.f = Objective(expr=- model.x1 - 2*model.x2) +model.f = Objective(expr=-model.x1 - 2 * model.x2) model.c = Complementarity(expr=complements(model.x1 >= 0, model.x2 >= 0)) - diff --git a/examples/mpec/munson1.py b/examples/mpec/munson1.py index 7bb7dfc478a..debdf709db9 100644 --- a/examples/mpec/munson1.py +++ b/examples/mpec/munson1.py @@ -25,15 +25,10 @@ model.x2 = Var() model.x3 = Var() -model.f1 = Complementarity(expr=\ - complements(model.x1 >= 0, \ - model.x1 + 2*model.x2 + 3*model.x3 >= 1)) +model.f1 = Complementarity( + expr=complements(model.x1 >= 0, model.x1 + 2 * model.x2 + 3 * model.x3 >= 1) +) -model.f2 = Complementarity(expr=\ - complements(model.x2 >= 0, \ - model.x2 - model.x3 >= -1)) - -model.f3 = Complementarity(expr=\ - complements(model.x3 >= 0, \ - model.x1 + model.x2 >= -1)) +model.f2 = Complementarity(expr=complements(model.x2 >= 0, model.x2 - model.x3 >= -1)) +model.f3 = Complementarity(expr=complements(model.x3 >= 0, model.x1 + model.x2 >= -1)) diff --git a/examples/mpec/munson1a.py b/examples/mpec/munson1a.py index 61a145f13b1..519db4e6ec2 100644 --- a/examples/mpec/munson1a.py +++ b/examples/mpec/munson1a.py @@ -27,15 +27,10 @@ model.x2 = Var() model.x3 = Var() -model.f1 = Complementarity(expr=\ - complements(model.x1 >= 0, \ - model.x1 + 2*model.x2 + 3*model.x3 >= 1)) +model.f1 = Complementarity( + expr=complements(model.x1 >= 0, model.x1 + 2 * model.x2 + 3 * model.x3 >= 1) +) -model.f2 = Complementarity(expr=\ - complements(model.x2 >= 0, \ - model.x2 - model.x3 >= -1)) - -model.f3 = Complementarity(expr=\ - complements(model.x3 >= 0, \ - model.x1 + model.x2 >= -1)) +model.f2 = Complementarity(expr=complements(model.x2 >= 0, model.x2 - model.x3 >= -1)) +model.f3 = Complementarity(expr=complements(model.x3 >= 0, model.x1 + model.x2 >= -1)) diff --git a/examples/mpec/munson1b.py b/examples/mpec/munson1b.py index 59848a5d955..ff2b7b51294 100644 --- a/examples/mpec/munson1b.py +++ b/examples/mpec/munson1b.py @@ -27,15 +27,10 @@ model.x2 = Var() model.x3 = Var() -model.f1 = Complementarity(expr=\ - complements(model.x1 <= 0, \ - - model.x1 - 2*model.x2 - 3*model.x3 >= 1)) +model.f1 = Complementarity( + expr=complements(model.x1 <= 0, -model.x1 - 2 * model.x2 - 3 * model.x3 >= 1) +) -model.f2 = Complementarity(expr=\ - complements(model.x2 <= 0, \ - - model.x2 + model.x3 >= -1)) - -model.f3 = Complementarity(expr=\ - complements(model.x3 <= 0, \ - - model.x1 - model.x2 >= -1)) +model.f2 = Complementarity(expr=complements(model.x2 <= 0, -model.x2 + model.x3 >= -1)) +model.f3 = Complementarity(expr=complements(model.x3 <= 0, -model.x1 - model.x2 >= -1)) diff --git a/examples/mpec/munson1c.py b/examples/mpec/munson1c.py index 1e53d1c15d9..2592b25c515 100644 --- a/examples/mpec/munson1c.py +++ b/examples/mpec/munson1c.py @@ -27,15 +27,10 @@ model.x2 = Var() model.x3 = Var() -model.f1 = Complementarity(expr=\ - complements(model.x1 >= 0, \ - - model.x1 - 2*model.x2 - 3*model.x3 <= -1)) +model.f1 = Complementarity( + expr=complements(model.x1 >= 0, -model.x1 - 2 * model.x2 - 3 * model.x3 <= -1) +) -model.f2 = Complementarity(expr=\ - complements(model.x2 >= 0, \ - - model.x2 + model.x3 <= 1)) - -model.f3 = Complementarity(expr=\ - complements(model.x3 >= 0, \ - - model.x1 - model.x2 <= 1)) +model.f2 = Complementarity(expr=complements(model.x2 >= 0, -model.x2 + model.x3 <= 1)) +model.f3 = Complementarity(expr=complements(model.x3 >= 0, -model.x1 - model.x2 <= 1)) diff --git a/examples/mpec/munson1d.py b/examples/mpec/munson1d.py index d9e304f71d3..0fb08ce73fb 100644 --- a/examples/mpec/munson1d.py +++ b/examples/mpec/munson1d.py @@ -27,15 +27,10 @@ model.x2 = Var() model.x3 = Var() -model.f1 = Complementarity(expr=\ - complements(model.x1 <= 0, \ - model.x1 + 2*model.x2 + 3*model.x3 <= -1)) +model.f1 = Complementarity( + expr=complements(model.x1 <= 0, model.x1 + 2 * model.x2 + 3 * model.x3 <= -1) +) -model.f2 = Complementarity(expr=\ - complements(model.x2 <= 0, \ - model.x2 - model.x3 <= 1)) - -model.f3 = Complementarity(expr=\ - complements(model.x3 <= 0, \ - model.x1 + model.x2 <= 1)) +model.f2 = Complementarity(expr=complements(model.x2 <= 0, model.x2 - model.x3 <= 1)) +model.f3 = Complementarity(expr=complements(model.x3 <= 0, model.x1 + model.x2 <= 1)) diff --git a/examples/mpec/scholtes4.py b/examples/mpec/scholtes4.py index 330b1f129b4..904729780cf 100644 --- a/examples/mpec/scholtes4.py +++ b/examples/mpec/scholtes4.py @@ -13,8 +13,8 @@ model = ConcreteModel() -z_init = {1:0, 2:1} -model.z = Var([1,2], within=NonNegativeReals, initialize=z_init) +z_init = {1: 0, 2: 1} +model.z = Var([1, 2], within=NonNegativeReals, initialize=z_init) model.z3 = Var(initialize=0) model.objf = Objective(expr=model.z[1] + model.z[2] - model.z3) @@ -24,4 +24,3 @@ model.lin2 = Constraint(expr=-4 * model.z[2] + model.z3 <= 0) model.compl = Complementarity(expr=complements(0 <= model.z[1], model.z[2] >= 0)) - diff --git a/examples/performance/dae/run_stochpdegas1_automatic.py b/examples/performance/dae/run_stochpdegas1_automatic.py index 577b35b4446..993e22c7c86 100644 --- a/examples/performance/dae/run_stochpdegas1_automatic.py +++ b/examples/performance/dae/run_stochpdegas1_automatic.py @@ -9,73 +9,134 @@ # discretize model discretizer = TransformationFactory('dae.finite_difference') -discretizer.apply_to(instance,nfe=1,wrt=instance.DIS,scheme='FORWARD') -discretizer.apply_to(instance,nfe=47,wrt=instance.TIME,scheme='BACKWARD') +discretizer.apply_to(instance, nfe=1, wrt=instance.DIS, scheme='FORWARD') +discretizer.apply_to(instance, nfe=47, wrt=instance.TIME, scheme='BACKWARD') # What it should be to match description in paper -#discretizer.apply_to(instance,nfe=48,wrt=instance.TIME,scheme='BACKWARD') +# discretizer.apply_to(instance,nfe=48,wrt=instance.TIME,scheme='BACKWARD') -TimeStep = instance.TIME[2]-instance.TIME[1] +TimeStep = instance.TIME[2] - instance.TIME[1] -def supcost_rule(m,k): - return sum(m.cs*m.s[k,j,t]*(TimeStep) for j in m.SUP for t in m.TIME.get_finite_elements()) -instance.supcost = Expression(instance.SCEN,rule=supcost_rule) -def boostcost_rule(m,k): - return sum(m.ce*m.pow[k,j,t]*(TimeStep) for j in m.LINK_A for t in m.TIME.get_finite_elements()) -instance.boostcost = Expression(instance.SCEN,rule=boostcost_rule) +def supcost_rule(m, k): + return sum( + m.cs * m.s[k, j, t] * (TimeStep) + for j in m.SUP + for t in m.TIME.get_finite_elements() + ) -def trackcost_rule(m,k): - return sum(m.cd*(m.dem[k,j,t]-m.stochd[k,j,t])**2.0 for j in m.DEM for t in m.TIME.get_finite_elements()) -instance.trackcost = Expression(instance.SCEN,rule=trackcost_rule) -def sspcost_rule(m,k): - return sum(m.cT*(m.px[k,i,m.TIME.last(),j]-m.px[k,i,m.TIME.first(),j])**2.0 for i in m.LINK for j in m.DIS) -instance.sspcost = Expression(instance.SCEN,rule=sspcost_rule) +instance.supcost = Expression(instance.SCEN, rule=supcost_rule) -def ssfcost_rule(m,k): - return sum(m.cT*(m.fx[k,i,m.TIME.last(),j]-m.fx[k,i,m.TIME.first(),j])**2.0 for i in m.LINK for j in m.DIS) -instance.ssfcost = Expression(instance.SCEN,rule=ssfcost_rule) -def cost_rule(m,k): - return 1e-6*(m.supcost[k] + m.boostcost[k] + m.trackcost[k] + m.sspcost[k] + m.ssfcost[k]) -instance.cost = Expression(instance.SCEN,rule=cost_rule) +def boostcost_rule(m, k): + return sum( + m.ce * m.pow[k, j, t] * (TimeStep) + for j in m.LINK_A + for t in m.TIME.get_finite_elements() + ) + + +instance.boostcost = Expression(instance.SCEN, rule=boostcost_rule) + + +def trackcost_rule(m, k): + return sum( + m.cd * (m.dem[k, j, t] - m.stochd[k, j, t]) ** 2.0 + for j in m.DEM + for t in m.TIME.get_finite_elements() + ) + + +instance.trackcost = Expression(instance.SCEN, rule=trackcost_rule) + + +def sspcost_rule(m, k): + return sum( + m.cT * (m.px[k, i, m.TIME.last(), j] - m.px[k, i, m.TIME.first(), j]) ** 2.0 + for i in m.LINK + for j in m.DIS + ) + + +instance.sspcost = Expression(instance.SCEN, rule=sspcost_rule) + + +def ssfcost_rule(m, k): + return sum( + m.cT * (m.fx[k, i, m.TIME.last(), j] - m.fx[k, i, m.TIME.first(), j]) ** 2.0 + for i in m.LINK + for j in m.DIS + ) + + +instance.ssfcost = Expression(instance.SCEN, rule=ssfcost_rule) + + +def cost_rule(m, k): + return 1e-6 * ( + m.supcost[k] + m.boostcost[k] + m.trackcost[k] + m.sspcost[k] + m.ssfcost[k] + ) + + +instance.cost = Expression(instance.SCEN, rule=cost_rule) + def mcost_rule(m): - return (1.0/m.S)*sum(m.cost[k] for k in m.SCEN) + return (1.0 / m.S) * sum(m.cost[k] for k in m.SCEN) + + instance.mcost = Expression(rule=mcost_rule) -def eqcvar_rule(m,k): - return m.cost[k] - m.nu <= m.phi[k]; -instance.eqcvar = Constraint(instance.SCEN,rule=eqcvar_rule) + +def eqcvar_rule(m, k): + return m.cost[k] - m.nu <= m.phi[k] + + +instance.eqcvar = Constraint(instance.SCEN, rule=eqcvar_rule) + def obj_rule(m): - return (1.0-m.cvar_lambda)*m.mcost + m.cvar_lambda*m.cvarcost + return (1.0 - m.cvar_lambda) * m.mcost + m.cvar_lambda * m.cvarcost + + instance.obj = Objective(rule=obj_rule) -endTime = time.time()-start +endTime = time.time() - start print('%f seconds required to construct' % endTime) import sys + start = time.time() instance.write(sys.argv[1]) -endTime = time.time()-start +endTime = time.time() - start print('%f seconds required to write file %s' % (endTime, sys.argv[1])) if False: for i in instance.SCEN: - print("Scenario %s = %s" % ( - i, sum(sum(0.5*value(instance.pow[i,j,k]) - for j in instance.LINK_A) - for k in instance.TIME.get_finite_elements()) )) - - - solver=SolverFactory('ipopt') - results = solver.solve(instance,tee=True) + print( + "Scenario %s = %s" + % ( + i, + sum( + sum(0.5 * value(instance.pow[i, j, k]) for j in instance.LINK_A) + for k in instance.TIME.get_finite_elements() + ), + ) + ) + + solver = SolverFactory('ipopt') + results = solver.solve(instance, tee=True) for i in instance.SCEN: - print("Scenario %s = %s" % ( - i, sum(sum(0.5*value(instance.pow[i,j,k]) - for j in instance.LINK_A) - for k in instance.TIME.get_finite_elements()) )) + print( + "Scenario %s = %s" + % ( + i, + sum( + sum(0.5 * value(instance.pow[i, j, k]) for j in instance.LINK_A) + for k in instance.TIME.get_finite_elements() + ), + ) + ) diff --git a/examples/performance/dae/stochpdegas1_automatic.py b/examples/performance/dae/stochpdegas1_automatic.py index 4a948559726..48bfe32a531 100644 --- a/examples/performance/dae/stochpdegas1_automatic.py +++ b/examples/performance/dae/stochpdegas1_automatic.py @@ -1,7 +1,7 @@ # stochastic pde model for natural gas network # victor m. zavala / 2013 -#from __future__ import division +# from __future__ import division from pyomo.environ import * from pyomo.dae import * @@ -10,285 +10,409 @@ # sets model.TF = Param(within=NonNegativeReals) + + def _tinit(m): - return [0.5,value(m.TF)] + return [0.5, value(m.TF)] # What it should be to match description in paper - #return [0,value(m.TF)] + # return [0,value(m.TF)] + + model.TIME = ContinuousSet(initialize=_tinit) -model.DIS = ContinuousSet(bounds=(0.0,1.0)) +model.DIS = ContinuousSet(bounds=(0.0, 1.0)) model.S = Param(within=PositiveIntegers) -model.SCEN = RangeSet(1,model.S) +model.SCEN = RangeSet(1, model.S) # links model.LINK = Set() model.lstartloc = Param(model.LINK) model.lendloc = Param(model.LINK) -model.ldiam = Param(model.LINK,within=PositiveReals,mutable=True) -model.llength = Param(model.LINK,within=PositiveReals,mutable=True) +model.ldiam = Param(model.LINK, within=PositiveReals, mutable=True) +model.llength = Param(model.LINK, within=PositiveReals, mutable=True) model.ltype = Param(model.LINK) + def link_a_init_rule(m): return (l for l in m.LINK if m.ltype[l] == "a") + + model.LINK_A = Set(initialize=link_a_init_rule) + def link_p_init_rule(m): return (l for l in m.LINK if m.ltype[l] == "p") + + model.LINK_P = Set(initialize=link_p_init_rule) # nodes model.NODE = Set() -model.pmin = Param(model.NODE,within=PositiveReals,mutable=True) -model.pmax = Param(model.NODE,within=PositiveReals,mutable=True) +model.pmin = Param(model.NODE, within=PositiveReals, mutable=True) +model.pmax = Param(model.NODE, within=PositiveReals, mutable=True) # supply model.SUP = Set() model.sloc = Param(model.SUP) -model.smin = Param(model.SUP,within=NonNegativeReals,mutable=True) -model.smax = Param(model.SUP,within=NonNegativeReals,mutable=True) -model.scost = Param(model.SUP,within=NonNegativeReals) +model.smin = Param(model.SUP, within=NonNegativeReals, mutable=True) +model.smax = Param(model.SUP, within=NonNegativeReals, mutable=True) +model.scost = Param(model.SUP, within=NonNegativeReals) # demand model.DEM = Set() model.dloc = Param(model.DEM) -model.d = Param(model.DEM, within=PositiveReals,mutable=True) +model.d = Param(model.DEM, within=PositiveReals, mutable=True) # physical data -model.eps = Param(initialize=0.025,within=PositiveReals) -model.z = Param(initialize=0.80,within=PositiveReals) -model.rhon = Param(initialize=0.72,within=PositiveReals) -model.R = Param(initialize=8314.0,within=PositiveReals) -model.M = Param(initialize=18.0,within=PositiveReals) -model.pi = Param(initialize=3.14,within=PositiveReals) -model.nu2 = Param(within=PositiveReals,mutable=True) -model.lam = Param(model.LINK,within=PositiveReals,mutable=True) -model.A = Param(model.LINK,within=NonNegativeReals,mutable=True) -model.Tgas = Param(initialize=293.15,within=PositiveReals) -model.Cp = Param(initialize=2.34,within=PositiveReals) -model.Cv = Param(initialize=1.85,within=PositiveReals) -model.gam = Param(initialize=model.Cp/model.Cv, within=PositiveReals) -model.om = Param(initialize=(model.gam-1.0)/model.gam,within=PositiveReals) +model.eps = Param(initialize=0.025, within=PositiveReals) +model.z = Param(initialize=0.80, within=PositiveReals) +model.rhon = Param(initialize=0.72, within=PositiveReals) +model.R = Param(initialize=8314.0, within=PositiveReals) +model.M = Param(initialize=18.0, within=PositiveReals) +model.pi = Param(initialize=3.14, within=PositiveReals) +model.nu2 = Param(within=PositiveReals, mutable=True) +model.lam = Param(model.LINK, within=PositiveReals, mutable=True) +model.A = Param(model.LINK, within=NonNegativeReals, mutable=True) +model.Tgas = Param(initialize=293.15, within=PositiveReals) +model.Cp = Param(initialize=2.34, within=PositiveReals) +model.Cv = Param(initialize=1.85, within=PositiveReals) +model.gam = Param(initialize=model.Cp / model.Cv, within=PositiveReals) +model.om = Param(initialize=(model.gam - 1.0) / model.gam, within=PositiveReals) # scaling and constants -model.ffac = Param(within=PositiveReals,initialize=(1.0e+6*model.rhon)/(24.0*3600.0)) -model.ffac2 = Param(within=PositiveReals,initialize=(3600.0)/(1.0e+4*model.rhon)) -model.pfac = Param(within=PositiveReals,initialize=1.0e+5) -model.pfac2 = Param(within=PositiveReals,initialize=1.0e-5) -model.dfac = Param(within=PositiveReals,initialize=1.0e-3) -model.lfac = Param(within=PositiveReals,initialize=1.0e+3) - -model.c1 = Param(model.LINK,within=PositiveReals,mutable=True) -model.c2 = Param(model.LINK,within=PositiveReals,mutable=True) -model.c3 = Param(model.LINK,within=PositiveReals,mutable=True) -model.c4 = Param(within=PositiveReals,mutable=True) +model.ffac = Param( + within=PositiveReals, initialize=(1.0e6 * model.rhon) / (24.0 * 3600.0) +) +model.ffac2 = Param(within=PositiveReals, initialize=(3600.0) / (1.0e4 * model.rhon)) +model.pfac = Param(within=PositiveReals, initialize=1.0e5) +model.pfac2 = Param(within=PositiveReals, initialize=1.0e-5) +model.dfac = Param(within=PositiveReals, initialize=1.0e-3) +model.lfac = Param(within=PositiveReals, initialize=1.0e3) + +model.c1 = Param(model.LINK, within=PositiveReals, mutable=True) +model.c2 = Param(model.LINK, within=PositiveReals, mutable=True) +model.c3 = Param(model.LINK, within=PositiveReals, mutable=True) +model.c4 = Param(within=PositiveReals, mutable=True) # cost factors -model.ce = Param(initialize=0.1,within=NonNegativeReals) -model.cd = Param(initialize=1.0e+6,within=NonNegativeReals) -model.cT = Param(initialize=1.0e+6,within=NonNegativeReals) -model.cs = Param(initialize=0.0,within=NonNegativeReals) +model.ce = Param(initialize=0.1, within=NonNegativeReals) +model.cd = Param(initialize=1.0e6, within=NonNegativeReals) +model.cT = Param(initialize=1.0e6, within=NonNegativeReals) +model.cs = Param(initialize=0.0, within=NonNegativeReals) model.TDEC = Param(within=PositiveReals) # define stochastic info -model.rand_d = Param(model.SCEN,model.DEM,within=NonNegativeReals,mutable=True) +model.rand_d = Param(model.SCEN, model.DEM, within=NonNegativeReals, mutable=True) # convert units for input data def rescale_rule(m): - + for i in m.LINK: - m.ldiam[i] = m.ldiam[i]*m.dfac - m.llength[i] = m.llength[i]*m.lfac + m.ldiam[i] = m.ldiam[i] * m.dfac + m.llength[i] = m.llength[i] * m.lfac # m.dx[i] = m.llength[i]/float(m.DIS.last()) for i in m.SUP: - m.smin[i] = m.smin[i]*m.ffac*m.ffac2 # from scmx106/day to kg/s and then to scmx10-4/hr - m.smax[i] = m.smax[i]*m.ffac*m.ffac2 # from scmx106/day to kg/s and then to scmx10-4/hr + m.smin[i] = ( + m.smin[i] * m.ffac * m.ffac2 + ) # from scmx106/day to kg/s and then to scmx10-4/hr + m.smax[i] = ( + m.smax[i] * m.ffac * m.ffac2 + ) # from scmx106/day to kg/s and then to scmx10-4/hr for i in m.DEM: - m.d[i] = m.d[i]*m.ffac*m.ffac2 + m.d[i] = m.d[i] * m.ffac * m.ffac2 for i in m.NODE: - m.pmin[i] = m.pmin[i]*m.pfac*m.pfac2 # from bar to Pascals and then to bar - m.pmax[i] = m.pmax[i]*m.pfac*m.pfac2 # from bar to Pascals and then to bar + m.pmin[i] = m.pmin[i] * m.pfac * m.pfac2 # from bar to Pascals and then to bar + m.pmax[i] = m.pmax[i] * m.pfac * m.pfac2 # from bar to Pascals and then to bar + + model.rescale = BuildAction(rule=rescale_rule) + def compute_constants(m): - + for i in m.LINK: - m.lam[i] = (2.0*log10(3.7*m.ldiam[i]/(m.eps*m.dfac)))**(-2.0) - m.A[i] = (1.0/4.0)*m.pi*m.ldiam[i]*m.ldiam[i] - m.nu2 = m.gam*m.z*m.R*m.Tgas/m.M - m.c1[i] = (m.pfac2/m.ffac2)*(m.nu2/m.A[i]) - m.c2[i] = m.A[i]*(m.ffac2/m.pfac2) - m.c3[i] = m.A[i]*(m.pfac2/m.ffac2)*(8.0*m.lam[i]*m.nu2)/(m.pi*m.pi*(m.ldiam[i]**5.0)) - m.c4 = (1/m.ffac2)*(m.Cp*m.Tgas) + m.lam[i] = (2.0 * log10(3.7 * m.ldiam[i] / (m.eps * m.dfac))) ** (-2.0) + m.A[i] = (1.0 / 4.0) * m.pi * m.ldiam[i] * m.ldiam[i] + m.nu2 = m.gam * m.z * m.R * m.Tgas / m.M + m.c1[i] = (m.pfac2 / m.ffac2) * (m.nu2 / m.A[i]) + m.c2[i] = m.A[i] * (m.ffac2 / m.pfac2) + m.c3[i] = ( + m.A[i] + * (m.pfac2 / m.ffac2) + * (8.0 * m.lam[i] * m.nu2) + / (m.pi * m.pi * (m.ldiam[i] ** 5.0)) + ) + m.c4 = (1 / m.ffac2) * (m.Cp * m.Tgas) + model.compute_constants = BuildAction(rule=compute_constants) # set stochastic demands def compute_demands_rule(m): - + for k in m.SCEN: for j in m.DEM: if k == 2: - m.rand_d[k,j] = 1.1*m.d[j] + m.rand_d[k, j] = 1.1 * m.d[j] elif k == 1: - m.rand_d[k,j] = 1.2*m.d[j] + m.rand_d[k, j] = 1.2 * m.d[j] else: - m.rand_d[k,j] = 1.3*m.d[j] + m.rand_d[k, j] = 1.3 * m.d[j] + + model.compute_demands = BuildAction(rule=compute_demands_rule) -def stochd_init(m,k,j,t): + +def stochd_init(m, k, j, t): # What it should be to match description in paper # if t < m.TDEC: # return m.d[j] # if t >= m.TDEC and t < m.TDEC+5: # return m.rand_d[k,j] # if t >= m.TDEC+5: - # return m.d[j] - if t < m.TDEC+1: + # return m.d[j] + if t < m.TDEC + 1: return m.d[j] - if t >= m.TDEC+1 and t < m.TDEC+1+4.5: - return m.rand_d[k,j] - if t >= m.TDEC+1+4.5: - return m.d[j] + if t >= m.TDEC + 1 and t < m.TDEC + 1 + 4.5: + return m.rand_d[k, j] + if t >= m.TDEC + 1 + 4.5: + return m.d[j] + -model.stochd = Param(model.SCEN,model.DEM,model.TIME,within=PositiveReals,mutable=True,default=stochd_init) +model.stochd = Param( + model.SCEN, + model.DEM, + model.TIME, + within=PositiveReals, + mutable=True, + default=stochd_init, +) # define temporal variables -def p_bounds_rule(m,k,j,t): - return (value(m.pmin[j]),value(m.pmax[j])) +def p_bounds_rule(m, k, j, t): + return (value(m.pmin[j]), value(m.pmax[j])) + + model.p = Var(model.SCEN, model.NODE, model.TIME, bounds=p_bounds_rule, initialize=50.0) -model.dp = Var(model.SCEN,model.LINK_A,model.TIME,bounds=(0.0,100.0), initialize=10.0) -model.fin = Var(model.SCEN,model.LINK,model.TIME,bounds=(1.0,500.0),initialize=100.0) -model.fout = Var(model.SCEN,model.LINK,model.TIME,bounds=(1.0,500.0),initialize=100.0) - -def s_bounds_rule(m,k,j,t): - return (0.01,value(m.smax[j])) -model.s = Var(model.SCEN,model.SUP,model.TIME,bounds=s_bounds_rule,initialize=10.0) -model.dem = Var(model.SCEN,model.DEM,model.TIME,initialize=100.0) -model.pow = Var(model.SCEN,model.LINK_A,model.TIME,bounds=(0.0,3000.0),initialize=1000.0) -model.slack = Var(model.SCEN,model.LINK,model.TIME,model.DIS,bounds=(0.0,None),initialize=10.0) - +model.dp = Var( + model.SCEN, model.LINK_A, model.TIME, bounds=(0.0, 100.0), initialize=10.0 +) +model.fin = Var( + model.SCEN, model.LINK, model.TIME, bounds=(1.0, 500.0), initialize=100.0 +) +model.fout = Var( + model.SCEN, model.LINK, model.TIME, bounds=(1.0, 500.0), initialize=100.0 +) + + +def s_bounds_rule(m, k, j, t): + return (0.01, value(m.smax[j])) + + +model.s = Var(model.SCEN, model.SUP, model.TIME, bounds=s_bounds_rule, initialize=10.0) +model.dem = Var(model.SCEN, model.DEM, model.TIME, initialize=100.0) +model.pow = Var( + model.SCEN, model.LINK_A, model.TIME, bounds=(0.0, 3000.0), initialize=1000.0 +) +model.slack = Var( + model.SCEN, model.LINK, model.TIME, model.DIS, bounds=(0.0, None), initialize=10.0 +) + # define spatio-temporal variables -model.px = Var(model.SCEN,model.LINK,model.TIME,model.DIS,bounds=(10.0,100.0),initialize=50.0) -model.fx = Var(model.SCEN,model.LINK,model.TIME,model.DIS,bounds=(1.0,100.0),initialize=100.0) +model.px = Var( + model.SCEN, model.LINK, model.TIME, model.DIS, bounds=(10.0, 100.0), initialize=50.0 +) +model.fx = Var( + model.SCEN, model.LINK, model.TIME, model.DIS, bounds=(1.0, 100.0), initialize=100.0 +) # define derivatives -model.dpxdt = DerivativeVar(model.px,wrt=model.TIME,initialize=0) -model.dpxdx = DerivativeVar(model.px,wrt=model.DIS,initialize=0) -model.dfxdt = DerivativeVar(model.fx,wrt=model.TIME,initialize=0) -model.dfxdx = DerivativeVar(model.fx,wrt=model.DIS,initialize=0) +model.dpxdt = DerivativeVar(model.px, wrt=model.TIME, initialize=0) +model.dpxdx = DerivativeVar(model.px, wrt=model.DIS, initialize=0) +model.dfxdt = DerivativeVar(model.fx, wrt=model.TIME, initialize=0) +model.dfxdx = DerivativeVar(model.fx, wrt=model.DIS, initialize=0) # ----------- MODEL -------------- # compressor equations -def powereq_rule(m,j,i,t): - return m.pow[j,i,t] == m.c4*m.fin[j,i,t]*(((m.p[j,m.lstartloc[i],t]+m.dp[j,i,t])/m.p[j,m.lstartloc[i],t])**m.om - 1.0) -model.powereq = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=powereq_rule) +def powereq_rule(m, j, i, t): + return m.pow[j, i, t] == m.c4 * m.fin[j, i, t] * ( + ((m.p[j, m.lstartloc[i], t] + m.dp[j, i, t]) / m.p[j, m.lstartloc[i], t]) + ** m.om + - 1.0 + ) + -# cvar model +model.powereq = Constraint(model.SCEN, model.LINK_A, model.TIME, rule=powereq_rule) + +# cvar model model.cvar_lambda = Param(within=NonNegativeReals) model.nu = Var(initialize=100.0) -model.phi = Var(model.SCEN,bounds=(0.0,None),initialize=100.0) +model.phi = Var(model.SCEN, bounds=(0.0, None), initialize=100.0) def cvarcost_rule(m): - return (1.0/m.S)*sum((m.phi[k]/(1.0-0.95) + m.nu) for k in m.SCEN) + return (1.0 / m.S) * sum((m.phi[k] / (1.0 - 0.95) + m.nu) for k in m.SCEN) + + model.cvarcost = Expression(rule=cvarcost_rule) # node balances -def nodeeq_rule(m,k,i,t): - return sum(m.fout[k,j,t] for j in m.LINK if m.lendloc[j]==i) + \ - sum(m.s[k,j,t] for j in m.SUP if m.sloc[j]==i) - \ - sum(m.fin[k,j,t] for j in m.LINK if m.lstartloc[j]==i) - \ - sum(m.dem[k,j,t] for j in m.DEM if m.dloc[j]==i) == 0.0 -model.nodeeq = Constraint(model.SCEN,model.NODE,model.TIME,rule=nodeeq_rule) - +def nodeeq_rule(m, k, i, t): + return ( + sum(m.fout[k, j, t] for j in m.LINK if m.lendloc[j] == i) + + sum(m.s[k, j, t] for j in m.SUP if m.sloc[j] == i) + - sum(m.fin[k, j, t] for j in m.LINK if m.lstartloc[j] == i) + - sum(m.dem[k, j, t] for j in m.DEM if m.dloc[j] == i) + == 0.0 + ) + + +model.nodeeq = Constraint(model.SCEN, model.NODE, model.TIME, rule=nodeeq_rule) + # boundary conditions flow -def flow_start_rule(m,j,i,t): - return m.fx[j,i,t,m.DIS.first()] == m.fin[j,i,t] -model.flow_start = Constraint(model.SCEN,model.LINK,model.TIME,rule=flow_start_rule) +def flow_start_rule(m, j, i, t): + return m.fx[j, i, t, m.DIS.first()] == m.fin[j, i, t] + + +model.flow_start = Constraint(model.SCEN, model.LINK, model.TIME, rule=flow_start_rule) -def flow_end_rule(m,j,i,t): - return m.fx[j,i,t,m.DIS.last()] == m.fout[j,i,t] -model.flow_end = Constraint(model.SCEN,model.LINK,model.TIME,rule=flow_end_rule) + +def flow_end_rule(m, j, i, t): + return m.fx[j, i, t, m.DIS.last()] == m.fout[j, i, t] + + +model.flow_end = Constraint(model.SCEN, model.LINK, model.TIME, rule=flow_end_rule) # First PDE for gas network model -def flow_rule(m,j,i,t,k): - if t == m.TIME.first() or k == m.DIS.last(): - return Constraint.Skip # Do not apply pde at initial time or final location - return m.dpxdt[j,i,t,k]/3600 + m.c1[i]/m.llength[i]*m.dfxdx[j,i,t,k] == 0 -model.flow = Constraint(model.SCEN,model.LINK,model.TIME,model.DIS,rule=flow_rule) +def flow_rule(m, j, i, t, k): + if t == m.TIME.first() or k == m.DIS.last(): + return Constraint.Skip # Do not apply pde at initial time or final location + return ( + m.dpxdt[j, i, t, k] / 3600 + m.c1[i] / m.llength[i] * m.dfxdx[j, i, t, k] == 0 + ) + + +model.flow = Constraint(model.SCEN, model.LINK, model.TIME, model.DIS, rule=flow_rule) # Second PDE for gas network model -def press_rule(m,j,i,t,k): +def press_rule(m, j, i, t, k): if t == m.TIME.first() or k == m.DIS.last(): - return Constraint.Skip # Do not apply pde at initial time or final location - return m.dfxdt[j,i,t,k]/3600 == -m.c2[i]/m.llength[i]*m.dpxdx[j,i,t,k] - m.slack[j,i,t,k] -model.press = Constraint(model.SCEN,model.LINK,model.TIME,model.DIS,rule=press_rule) + return Constraint.Skip # Do not apply pde at initial time or final location + return ( + m.dfxdt[j, i, t, k] / 3600 + == -m.c2[i] / m.llength[i] * m.dpxdx[j, i, t, k] - m.slack[j, i, t, k] + ) + + +model.press = Constraint(model.SCEN, model.LINK, model.TIME, model.DIS, rule=press_rule) + -def slackeq_rule(m,j,i,t,k): +def slackeq_rule(m, j, i, t, k): if t == m.TIME.last(): return Constraint.Skip - return m.slack[j,i,t,k]*m.px[j,i,t,k] == m.c3[i]*m.fx[j,i,t,k]*m.fx[j,i,t,k] -model.slackeq = Constraint(model.SCEN,model.LINK,model.TIME,model.DIS,rule=slackeq_rule) + return ( + m.slack[j, i, t, k] * m.px[j, i, t, k] + == m.c3[i] * m.fx[j, i, t, k] * m.fx[j, i, t, k] + ) + + +model.slackeq = Constraint( + model.SCEN, model.LINK, model.TIME, model.DIS, rule=slackeq_rule +) # boundary conditions pressure, passive links -def presspas_start_rule(m,j,i,t): - return m.px[j,i,t,m.DIS.first()] == m.p[j,m.lstartloc[i],t] -model.presspas_start = Constraint(model.SCEN,model.LINK_P,model.TIME,rule=presspas_start_rule) +def presspas_start_rule(m, j, i, t): + return m.px[j, i, t, m.DIS.first()] == m.p[j, m.lstartloc[i], t] + + +model.presspas_start = Constraint( + model.SCEN, model.LINK_P, model.TIME, rule=presspas_start_rule +) + -def presspas_end_rule(m,j,i,t): - return m.px[j,i,t,m.DIS.last()] == m.p[j,m.lendloc[i],t] -model.presspas_end = Constraint(model.SCEN,model.LINK_P,model.TIME,rule=presspas_end_rule) +def presspas_end_rule(m, j, i, t): + return m.px[j, i, t, m.DIS.last()] == m.p[j, m.lendloc[i], t] + + +model.presspas_end = Constraint( + model.SCEN, model.LINK_P, model.TIME, rule=presspas_end_rule +) # boundary conditions pressure, active links -def pressact_start_rule(m,j,i,t): - return m.px[j,i,t,m.DIS.first()] == m.p[j,m.lstartloc[i],t]+m.dp[j,i,t] -model.pressact_start = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=pressact_start_rule) - -def pressact_end_rule(m,j,i,t): - return m.px[j,i,t,m.DIS.last()] == m.p[j,m.lendloc[i],t] -model.pressact_end = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=pressact_end_rule) - +def pressact_start_rule(m, j, i, t): + return m.px[j, i, t, m.DIS.first()] == m.p[j, m.lstartloc[i], t] + m.dp[j, i, t] + + +model.pressact_start = Constraint( + model.SCEN, model.LINK_A, model.TIME, rule=pressact_start_rule +) + + +def pressact_end_rule(m, j, i, t): + return m.px[j, i, t, m.DIS.last()] == m.p[j, m.lendloc[i], t] + + +model.pressact_end = Constraint( + model.SCEN, model.LINK_A, model.TIME, rule=pressact_end_rule +) + # fix pressure at supply nodes -def suppres_rule(m,k,j,t): - return m.p[k,m.sloc[j],t] == m.pmin[m.sloc[j]] -model.suppres = Constraint(model.SCEN,model.SUP,model.TIME,rule=suppres_rule) +def suppres_rule(m, k, j, t): + return m.p[k, m.sloc[j], t] == m.pmin[m.sloc[j]] + + +model.suppres = Constraint(model.SCEN, model.SUP, model.TIME, rule=suppres_rule) # discharge pressure for compressors -def dispress_rule(m,j,i,t): - return m.p[j,m.lstartloc[i],t]+m.dp[j,i,t] <= m.pmax[m.lstartloc[i]] -model.dispress = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=dispress_rule) +def dispress_rule(m, j, i, t): + return m.p[j, m.lstartloc[i], t] + m.dp[j, i, t] <= m.pmax[m.lstartloc[i]] + + +model.dispress = Constraint(model.SCEN, model.LINK_A, model.TIME, rule=dispress_rule) # ss constraints -def flow_ss_rule(m,j,i,k): +def flow_ss_rule(m, j, i, k): if k == m.DIS.last(): return Constraint.Skip - return m.dfxdx[j,i,m.TIME.first(),k]/m.llength[i] == 0.0 -model.flow_ss = Constraint(model.SCEN,model.LINK,model.DIS,rule=flow_ss_rule) + return m.dfxdx[j, i, m.TIME.first(), k] / m.llength[i] == 0.0 -def pres_ss_rule(m,j,i,k): + +model.flow_ss = Constraint(model.SCEN, model.LINK, model.DIS, rule=flow_ss_rule) + + +def pres_ss_rule(m, j, i, k): if k == m.DIS.last(): return Constraint.Skip - return 0.0 == - m.c2[i]/m.llength[i]*m.dpxdx[j,i,m.TIME.first(),k] - m.slack[j,i,m.TIME.first(),k]; -model.pres_ss = Constraint(model.SCEN,model.LINK,model.DIS,rule=pres_ss_rule) + return ( + 0.0 + == -m.c2[i] / m.llength[i] * m.dpxdx[j, i, m.TIME.first(), k] + - m.slack[j, i, m.TIME.first(), k] + ) + + +model.pres_ss = Constraint(model.SCEN, model.LINK, model.DIS, rule=pres_ss_rule) # non-anticipativity constraints -def nonantdq_rule(m,j,i,t): +def nonantdq_rule(m, j, i, t): if j == 1: return Constraint.Skip - if t >= m.TDEC+1: + if t >= m.TDEC + 1: return Constraint.Skip - return m.dp[j,i,t] == m.dp[1,i,t] + return m.dp[j, i, t] == m.dp[1, i, t] + -model.nonantdq = Constraint(model.SCEN,model.LINK_A,model.TIME,rule=nonantdq_rule) +model.nonantdq = Constraint(model.SCEN, model.LINK_A, model.TIME, rule=nonantdq_rule) -def nonantde_rule(m,j,i,t): + +def nonantde_rule(m, j, i, t): if j == 1: return Constraint.Skip - if t >= m.TDEC+1: + if t >= m.TDEC + 1: return Constraint.Skip - return m.dem[j,i,t] == m.dem[1,i,t] + return m.dem[j, i, t] == m.dem[1, i, t] + -model.nonantde = Constraint(model.SCEN,model.DEM,model.TIME,rule=nonantde_rule) +model.nonantde = Constraint(model.SCEN, model.DEM, model.TIME, rule=nonantde_rule) diff --git a/examples/performance/jump/clnlbeam.py b/examples/performance/jump/clnlbeam.py index 9ff2abf4aa2..d2ceda790ec 100644 --- a/examples/performance/jump/clnlbeam.py +++ b/examples/performance/jump/clnlbeam.py @@ -3,35 +3,48 @@ model = AbstractModel() model.N = Param(within=PositiveIntegers) -model.h = 1.0/model.N +model.h = 1.0 / model.N -model.VarIdx = RangeSet(model.N+1) +model.VarIdx = RangeSet(model.N + 1) -model.t = Var(model.VarIdx, bounds=(-1.0,1.0), initialize=lambda m,i: 0.05*cos(i*m.h)) -model.x = Var(model.VarIdx, bounds=(-0.05,0.05), initialize=lambda m,i: 0.05*cos(i*m.h)) +model.t = Var( + model.VarIdx, bounds=(-1.0, 1.0), initialize=lambda m, i: 0.05 * cos(i * m.h) +) +model.x = Var( + model.VarIdx, bounds=(-0.05, 0.05), initialize=lambda m, i: 0.05 * cos(i * m.h) +) model.u = Var(model.VarIdx, initialize=0.01) alpha = 350 + def c_rule(m): ex = 0 for i in m.VarIdx: - if i == m.N+1: + if i == m.N + 1: continue - ex += 0.5*m.h*(m.u[i+1]**2+m.u[i]**2) + 0.5*alpha*m.h*(cos(m.t[i+1])+cos(m.t[i])) + ex += 0.5 * m.h * (m.u[i + 1] ** 2 + m.u[i] ** 2) + 0.5 * alpha * m.h * ( + cos(m.t[i + 1]) + cos(m.t[i]) + ) return ex + model.c = Objective(rule=c_rule) + def cons1_rule(m, i): - if i == m.N+1: + if i == m.N + 1: return Constraint.Skip - return m.x[i+1] - m.x[i] - (0.5*m.h)*(sin(m.t[i+1])+sin(m.t[i])) == 0 + return m.x[i + 1] - m.x[i] - (0.5 * m.h) * (sin(m.t[i + 1]) + sin(m.t[i])) == 0 + + model.cons1 = Constraint(model.VarIdx, rule=cons1_rule) -def cons2_rule(m,i): - if i == m.N+1: + +def cons2_rule(m, i): + if i == m.N + 1: return Constraint.Skip - return m.t[i+1] - m.t[i] - (0.5*m.h)*m.u[i+1] - (0.5*m.h)*m.u[i] == 0 -model.cons2 = Constraint(model.VarIdx, rule=cons2_rule) + return m.t[i + 1] - m.t[i] - (0.5 * m.h) * m.u[i + 1] - (0.5 * m.h) * m.u[i] == 0 + +model.cons2 = Constraint(model.VarIdx, rule=cons2_rule) diff --git a/examples/performance/jump/facility.py b/examples/performance/jump/facility.py index 8b4acb75e70..6832e8d32ac 100644 --- a/examples/performance/jump/facility.py +++ b/examples/performance/jump/facility.py @@ -2,8 +2,8 @@ model = AbstractModel() -model.G = 25 #Param(within=PositiveIntegers) -model.F = 25 #Param(within=PositiveIntegers) +model.G = 25 # Param(within=PositiveIntegers) +model.F = 25 # Param(within=PositiveIntegers) model.Grid = RangeSet(0, model.G) model.Facs = RangeSet(1, model.F) @@ -15,28 +15,46 @@ model.s = Var(model.Grid, model.Grid, model.Facs, bounds=(0.0, None)) model.r = Var(model.Grid, model.Grid, model.Facs, model.Dims) + def obj_rule(mod): - return 1.0*mod.d + return 1.0 * mod.d + + model.obj = Objective(rule=obj_rule) + def assmt_rule(mod, i, j): - return sum([mod.z[i,j,f] for f in mod.Facs]) == 1 + return sum([mod.z[i, j, f] for f in mod.Facs]) == 1 + + model.assmt = Constraint(model.Grid, model.Grid, rule=assmt_rule) -M = 2*1.414 -def quadrhs_rule(mod,i,j,f): - return mod.s[i,j,f] == mod.d + M*(1 - mod.z[i,j,f]) +M = 2 * 1.414 + + +def quadrhs_rule(mod, i, j, f): + return mod.s[i, j, f] == mod.d + M * (1 - mod.z[i, j, f]) + + model.quadrhs = Constraint(model.Grid, model.Grid, model.Facs, rule=quadrhs_rule) -def quaddistk1_rule(mod,i,j,f): - return mod.r[i,j,f,1] == (1.0*i)/mod.G - mod.y[f,1] + +def quaddistk1_rule(mod, i, j, f): + return mod.r[i, j, f, 1] == (1.0 * i) / mod.G - mod.y[f, 1] + + model.quaddistk1 = Constraint(model.Grid, model.Grid, model.Facs, rule=quaddistk1_rule) -def quaddistk2_rule(mod,i,j,f): - return mod.r[i,j,f,2] == (1.0*j)/mod.G - mod.y[f,2] + +def quaddistk2_rule(mod, i, j, f): + return mod.r[i, j, f, 2] == (1.0 * j) / mod.G - mod.y[f, 2] + + model.quaddistk2 = Constraint(model.Grid, model.Grid, model.Facs, rule=quaddistk2_rule) -def quaddist_rule(mod,i,j,f): - return mod.r[i,j,f,1]**2 + mod.r[i,j,f,2]**2 <= mod.s[i,j,f]**2 -model.quaddist = Constraint(model.Grid, model.Grid, model.Facs, rule=quaddist_rule) +def quaddist_rule(mod, i, j, f): + return mod.r[i, j, f, 1] ** 2 + mod.r[i, j, f, 2] ** 2 <= mod.s[i, j, f] ** 2 + + +model.quaddist = Constraint(model.Grid, model.Grid, model.Facs, rule=quaddist_rule) diff --git a/examples/performance/jump/lqcp.py b/examples/performance/jump/lqcp.py index 10cb49cb262..bb3e66b36f5 100644 --- a/examples/performance/jump/lqcp.py +++ b/examples/performance/jump/lqcp.py @@ -4,9 +4,9 @@ model.n = 1000 model.m = 1000 -model.dx = 1.0/model.n +model.dx = 1.0 / model.n model.T = 1.58 -model.dt = model.T/model.n +model.dt = model.T / model.n model.h2 = model.dx**2 model.a = 0.001 @@ -16,32 +16,59 @@ model.y = Var(model.ms, model.ns, bounds=(0.0, 1.0)) model.u = Var(model.ms, bounds=(-1.0, 1.0)) -def yt(j,dx): - return 0.5*(1 - (j*dx)*(j*dx)) + +def yt(j, dx): + return 0.5 * (1 - (j * dx) * (j * dx)) + def rule(model): - return 0.25*model.dx*( - (model.y[model.m,0] - yt(0,model.dx))**2 + - 2*sum( (model.y[model.m,j] - yt(j,model.dx))**2 for j in range(1,model.n)) + - (model.y[model.m,model.n] - yt(model.n,model.dx))**2 - ) + 0.25*model.a*model.dt*( - 2 * sum( model.u[i]**2 for i in range(1,model.m)) + - model.u[model.m]**2 + return 0.25 * model.dx * ( + (model.y[model.m, 0] - yt(0, model.dx)) ** 2 + + 2 + * sum((model.y[model.m, j] - yt(j, model.dx)) ** 2 for j in range(1, model.n)) + + (model.y[model.m, model.n] - yt(model.n, model.dx)) ** 2 + ) + 0.25 * model.a * model.dt * ( + 2 * sum(model.u[i] ** 2 for i in range(1, model.m)) + model.u[model.m] ** 2 ) + + model.obj = Objective(rule=rule) + def pde_rule(model, i, j): - return (model.y[i+1,j] - model.y[i,j])/model.dt == 0.5*(model.y[i,j-1] - 2*model.y[i,j] + model.y[i,j+1] + model.y[i+1,j-1] - 2*model.y[i+1,j] + model.y[i+1,j+1])/model.h2 -model.pde = Constraint(RangeSet(0,model.n-1), RangeSet(1,model.n-1), rule=pde_rule) + return (model.y[i + 1, j] - model.y[i, j]) / model.dt == 0.5 * ( + model.y[i, j - 1] + - 2 * model.y[i, j] + + model.y[i, j + 1] + + model.y[i + 1, j - 1] + - 2 * model.y[i + 1, j] + + model.y[i + 1, j + 1] + ) / model.h2 + + +model.pde = Constraint( + RangeSet(0, model.n - 1), RangeSet(1, model.n - 1), rule=pde_rule +) + def ic_rule(model, j): - return model.y[0,j] == 0 + return model.y[0, j] == 0 + + model.ic = Constraint(model.ns, rule=ic_rule) + def bc1_rule(model, i): - return model.y[i, 2] - 4*model.y[i, 1] + 3*model.y[i,0] == 0 -model.bc1 = Constraint(RangeSet(1,model.n), rule=bc1_rule) + return model.y[i, 2] - 4 * model.y[i, 1] + 3 * model.y[i, 0] == 0 + + +model.bc1 = Constraint(RangeSet(1, model.n), rule=bc1_rule) + def bc2_rule(model, i): - return model.y[i,model.n-2] - 4*model.y[i,model.n-1] + 3*model.y[i,model.n-0] == (2*model.dx)*(model.u[i] - model.y[i,model.n-0]) -model.bc2 = Constraint(RangeSet(1,model.n), rule=bc2_rule) + return model.y[i, model.n - 2] - 4 * model.y[i, model.n - 1] + 3 * model.y[ + i, model.n - 0 + ] == (2 * model.dx) * (model.u[i] - model.y[i, model.n - 0]) + + +model.bc2 = Constraint(RangeSet(1, model.n), rule=bc2_rule) diff --git a/examples/performance/jump/opf_66200bus.py b/examples/performance/jump/opf_66200bus.py index ef20ed11940..f3e1822fbfb 100644 --- a/examples/performance/jump/opf_66200bus.py +++ b/examples/performance/jump/opf_66200bus.py @@ -1,15 +1,18 @@ from pyomo.environ import * + class Bus: pass + class Branch: pass + bus = [] busmap = {} busfile = open("IEEE66200.bus", "r") -for i,line in enumerate(busfile): +for i, line in enumerate(busfile): sp = line.split() b = Bus() busmap[sp[0]] = i @@ -40,7 +43,7 @@ class Branch: branchfile = open("IEEE66200.branch", "r") branch = [] -for i,line in enumerate(branchfile): +for i, line in enumerate(branchfile): sp = line.split() b = Branch() b.frm = busmap[sp[1]] @@ -57,14 +60,14 @@ class Branch: b.def_max = float(sp[12]) b.g = b.r / (b.r**2 + b.x**2) b.b = -b.x / (b.r**2 + b.x**2) - b.def_min *= 3.14159/180 - b.def_max *= 3.14159/180 - b.def0 *= -3.14159/180 + b.def_min *= 3.14159 / 180 + b.def_max *= 3.14159 / 180 + b.def0 *= -3.14159 / 180 branch.append(b) -bus_voltage_min = {0 : 0.85, 1 : 0.85, 2 : 0.92, 3 : 0.99} -bus_voltage_max = {0 : 1.15, 1 : 1.15, 2 : 1.08, 3 : 1.01} +bus_voltage_min = {0: 0.85, 1: 0.85, 2: 0.92, 3: 0.99} +bus_voltage_max = {0: 1.15, 1: 1.15, 2: 1.08, 3: 1.01} branch_tap_min = 0.85 branch_tap_max = 1.15 @@ -74,108 +77,244 @@ class Branch: nbus = len(bus) nbranch = len(branch) -in_lines = [ [] for i in range(nbus) ] -out_lines = [ [] for i in range(nbus) ] +in_lines = [[] for i in range(nbus)] +out_lines = [[] for i in range(nbus)] for i in range(nbranch): b = branch[i] out_lines[b.frm].append(i) in_lines[b.to].append(i) - assert(b.to >= 0 and b.to < nbus) + assert b.to >= 0 and b.to < nbus model = ConcreteModel() -model.bus_voltage = Var(range(nbus),bounds = lambda model,i : (bus_voltage_min[bus[i].bustype], bus_voltage_max[bus[i].bustype]), initialize=1) -model.bus_b_shunt = Var(range(nbus),bounds = lambda model,i : (bus[i].b_shunt_min, bus[i].b_shunt_max), initialize = lambda model,i : bus[i].b_shunt0) +model.bus_voltage = Var( + range(nbus), + bounds=lambda model, i: ( + bus_voltage_min[bus[i].bustype], + bus_voltage_max[bus[i].bustype], + ), + initialize=1, +) +model.bus_b_shunt = Var( + range(nbus), + bounds=lambda model, i: (bus[i].b_shunt_min, bus[i].b_shunt_max), + initialize=lambda model, i: bus[i].b_shunt0, +) model.bus_angle = Var(range(nbus), initialize=0) -model.branch_tap = Var(range(nbranch), bounds=(branch_tap_min, branch_tap_max), initialize=1) -model.branch_def = Var(range(nbranch), bounds=lambda model,i: (branch[i].def_min, branch[i].def_max), initialize = lambda model,i : branch[i].def0) +model.branch_tap = Var( + range(nbranch), bounds=(branch_tap_min, branch_tap_max), initialize=1 +) +model.branch_def = Var( + range(nbranch), + bounds=lambda model, i: (branch[i].def_min, branch[i].def_max), + initialize=lambda model, i: branch[i].def0, +) + def Gself(k): - return bus[k].g_shunt + sum(branch[i].g*model.branch_tap[i]**2 for i in out_lines[k]) + sum(branch[i].g for i in in_lines[k]) + return ( + bus[k].g_shunt + + sum(branch[i].g * model.branch_tap[i] ** 2 for i in out_lines[k]) + + sum(branch[i].g for i in in_lines[k]) + ) + def Gout(i): - return (-branch[i].g*cos(model.branch_def[i])+branch[i].b*sin(model.branch_def[i]))*model.branch_tap[i] + return ( + -branch[i].g * cos(model.branch_def[i]) + branch[i].b * sin(model.branch_def[i]) + ) * model.branch_tap[i] + def Gin(i): - return (-branch[i].g*cos(model.branch_def[i])-branch[i].b*sin(model.branch_def[i]))*model.branch_tap[i] + return ( + -branch[i].g * cos(model.branch_def[i]) - branch[i].b * sin(model.branch_def[i]) + ) * model.branch_tap[i] + def Bself(k): - return model.bus_b_shunt[k] + sum(branch[i].b*model.branch_tap[i]**2 + branch[i].c/2 for i in out_lines[k]) + sum(branch[i].b + branch[i].c/2 for i in in_lines[k]) + return ( + model.bus_b_shunt[k] + + sum( + branch[i].b * model.branch_tap[i] ** 2 + branch[i].c / 2 + for i in out_lines[k] + ) + + sum(branch[i].b + branch[i].c / 2 for i in in_lines[k]) + ) + def Bin(i): - return (branch[i].g*sin(model.branch_def[i])-branch[i].b*cos(model.branch_def[i]))*model.branch_tap[i] + return ( + branch[i].g * sin(model.branch_def[i]) - branch[i].b * cos(model.branch_def[i]) + ) * model.branch_tap[i] + def Bout(i): - return (-branch[i].g*sin(model.branch_def[i])-branch[i].b*cos(model.branch_def[i]))*model.branch_tap[i] - -model.obj = Objective(expr = sum( \ - (bus[k].p_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + \ - Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm])) \ - for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + \ - Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to])) \ - for i in out_lines[k]) + \ - model.bus_voltage[k]**2*Gself(k) )**2 \ - for k in range(nbus) if bus[k].bustype == 2 or bus[k].bustype == 3)) + return ( + -branch[i].g * sin(model.branch_def[i]) - branch[i].b * cos(model.branch_def[i]) + ) * model.branch_tap[i] + + +model.obj = Objective( + expr=sum( + ( + bus[k].p_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Gself(k) + ) + ** 2 + for k in range(nbus) + if bus[k].bustype == 2 or bus[k].bustype == 3 + ) +) + def p_load_rule(model, k): if bus[k].bustype != 0: return Constraint.Skip - - return bus[k].p_gen - bus[k].p_load - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm]) + Bin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to]) + Bout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) - \ - model.bus_voltage[k]**2*Gself(k) == 0 + + return ( + bus[k].p_gen + - bus[k].p_load + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + - model.bus_voltage[k] ** 2 * Gself(k) + == 0 + ) + model.p_load_constr = Constraint(range(nbus), rule=p_load_rule) + def q_load_rule(model, k): if bus[k].bustype != 0: return Constraint.Skip - - return bus[k].q_gen - bus[k].q_load - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm]) - Bin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to]) - Bout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) \ - + model.bus_voltage[k]**2*Bself(k) == 0 + + return ( + bus[k].q_gen + - bus[k].q_load + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + - Bin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + - Bout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Bself(k) + == 0 + ) + model.q_load_constr = Constraint(range(nbus), rule=q_load_rule) + def q_inj_rule(model, k): if not (bus[k].bustype == 2 or bus[k].bustype == 3): return Constraint.Skip - - return (bus[k].q_min, \ - bus[k].q_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm]) - Bin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to]) - Bout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) - \ - model.bus_voltage[k]**2*Bself(k), \ - bus[k].q_max) + + return ( + bus[k].q_min, + bus[k].q_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + - Bin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + - Bout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + - model.bus_voltage[k] ** 2 * Bself(k), + bus[k].q_max, + ) + model.q_inj_rule = Constraint(range(nbus), rule=q_inj_rule) + def p_inj_rule(model, k): if not (bus[k].bustype == 2 or bus[k].bustype == 3): return Constraint.Skip - - return (0, \ - bus[k].p_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm]) + Bin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to]) + Bout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) + \ - model.bus_voltage[k]**2*Gself(k),\ - p_gen_upper*bus[k].p_gen) + + return ( + 0, + bus[k].p_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Gself(k), + p_gen_upper * bus[k].p_gen, + ) + model.p_inj_rule = Constraint(range(nbus), rule=p_inj_rule) diff --git a/examples/performance/jump/opf_6620bus.py b/examples/performance/jump/opf_6620bus.py index d89fc4985c2..64348ae931e 100644 --- a/examples/performance/jump/opf_6620bus.py +++ b/examples/performance/jump/opf_6620bus.py @@ -1,15 +1,18 @@ from pyomo.environ import * + class Bus: pass + class Branch: pass + bus = [] busmap = {} busfile = open("IEEE6620.bus", "r") -for i,line in enumerate(busfile): +for i, line in enumerate(busfile): sp = line.split() b = Bus() busmap[sp[0]] = i @@ -40,7 +43,7 @@ class Branch: branchfile = open("IEEE6620.branch", "r") branch = [] -for i,line in enumerate(branchfile): +for i, line in enumerate(branchfile): sp = line.split() b = Branch() b.frm = busmap[sp[1]] @@ -57,14 +60,14 @@ class Branch: b.def_max = float(sp[12]) b.g = b.r / (b.r**2 + b.x**2) b.b = -b.x / (b.r**2 + b.x**2) - b.def_min *= 3.14159/180 - b.def_max *= 3.14159/180 - b.def0 *= -3.14159/180 + b.def_min *= 3.14159 / 180 + b.def_max *= 3.14159 / 180 + b.def0 *= -3.14159 / 180 branch.append(b) -bus_voltage_min = {0 : 0.85, 1 : 0.85, 2 : 0.92, 3 : 0.99} -bus_voltage_max = {0 : 1.15, 1 : 1.15, 2 : 1.08, 3 : 1.01} +bus_voltage_min = {0: 0.85, 1: 0.85, 2: 0.92, 3: 0.99} +bus_voltage_max = {0: 1.15, 1: 1.15, 2: 1.08, 3: 1.01} branch_tap_min = 0.85 branch_tap_max = 1.15 @@ -74,108 +77,244 @@ class Branch: nbus = len(bus) nbranch = len(branch) -in_lines = [ [] for i in range(nbus) ] -out_lines = [ [] for i in range(nbus) ] +in_lines = [[] for i in range(nbus)] +out_lines = [[] for i in range(nbus)] for i in range(nbranch): b = branch[i] out_lines[b.frm].append(i) in_lines[b.to].append(i) - assert(b.to >= 0 and b.to < nbus) + assert b.to >= 0 and b.to < nbus model = ConcreteModel() -model.bus_voltage = Var(range(nbus),bounds = lambda model,i : (bus_voltage_min[bus[i].bustype], bus_voltage_max[bus[i].bustype]), initialize=1) -model.bus_b_shunt = Var(range(nbus),bounds = lambda model,i : (bus[i].b_shunt_min, bus[i].b_shunt_max), initialize = lambda model,i : bus[i].b_shunt0) +model.bus_voltage = Var( + range(nbus), + bounds=lambda model, i: ( + bus_voltage_min[bus[i].bustype], + bus_voltage_max[bus[i].bustype], + ), + initialize=1, +) +model.bus_b_shunt = Var( + range(nbus), + bounds=lambda model, i: (bus[i].b_shunt_min, bus[i].b_shunt_max), + initialize=lambda model, i: bus[i].b_shunt0, +) model.bus_angle = Var(range(nbus), initialize=0) -model.branch_tap = Var(range(nbranch), bounds=(branch_tap_min, branch_tap_max), initialize=1) -model.branch_def = Var(range(nbranch), bounds=lambda model,i: (branch[i].def_min, branch[i].def_max), initialize = lambda model,i : branch[i].def0) +model.branch_tap = Var( + range(nbranch), bounds=(branch_tap_min, branch_tap_max), initialize=1 +) +model.branch_def = Var( + range(nbranch), + bounds=lambda model, i: (branch[i].def_min, branch[i].def_max), + initialize=lambda model, i: branch[i].def0, +) + def Gself(k): - return bus[k].g_shunt + sum(branch[i].g*model.branch_tap[i]**2 for i in out_lines[k]) + sum(branch[i].g for i in in_lines[k]) + return ( + bus[k].g_shunt + + sum(branch[i].g * model.branch_tap[i] ** 2 for i in out_lines[k]) + + sum(branch[i].g for i in in_lines[k]) + ) + def Gout(i): - return (-branch[i].g*cos(model.branch_def[i])+branch[i].b*sin(model.branch_def[i]))*model.branch_tap[i] + return ( + -branch[i].g * cos(model.branch_def[i]) + branch[i].b * sin(model.branch_def[i]) + ) * model.branch_tap[i] + def Gin(i): - return (-branch[i].g*cos(model.branch_def[i])-branch[i].b*sin(model.branch_def[i]))*model.branch_tap[i] + return ( + -branch[i].g * cos(model.branch_def[i]) - branch[i].b * sin(model.branch_def[i]) + ) * model.branch_tap[i] + def Bself(k): - return model.bus_b_shunt[k] + sum(branch[i].b*model.branch_tap[i]**2 + branch[i].c/2 for i in out_lines[k]) + sum(branch[i].b + branch[i].c/2 for i in in_lines[k]) + return ( + model.bus_b_shunt[k] + + sum( + branch[i].b * model.branch_tap[i] ** 2 + branch[i].c / 2 + for i in out_lines[k] + ) + + sum(branch[i].b + branch[i].c / 2 for i in in_lines[k]) + ) + def Bin(i): - return (branch[i].g*sin(model.branch_def[i])-branch[i].b*cos(model.branch_def[i]))*model.branch_tap[i] + return ( + branch[i].g * sin(model.branch_def[i]) - branch[i].b * cos(model.branch_def[i]) + ) * model.branch_tap[i] + def Bout(i): - return (-branch[i].g*sin(model.branch_def[i])-branch[i].b*cos(model.branch_def[i]))*model.branch_tap[i] - -model.obj = Objective(expr = sum( \ - (bus[k].p_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + \ - Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm])) \ - for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + \ - Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to])) \ - for i in out_lines[k]) + \ - model.bus_voltage[k]**2*Gself(k) )**2 \ - for k in range(nbus) if bus[k].bustype == 2 or bus[k].bustype == 3)) + return ( + -branch[i].g * sin(model.branch_def[i]) - branch[i].b * cos(model.branch_def[i]) + ) * model.branch_tap[i] + + +model.obj = Objective( + expr=sum( + ( + bus[k].p_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Gself(k) + ) + ** 2 + for k in range(nbus) + if bus[k].bustype == 2 or bus[k].bustype == 3 + ) +) + def p_load_rule(model, k): if bus[k].bustype != 0: return Constraint.Skip - - return bus[k].p_gen - bus[k].p_load - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm]) + Bin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to]) + Bout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) - \ - model.bus_voltage[k]**2*Gself(k) == 0 + + return ( + bus[k].p_gen + - bus[k].p_load + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + - model.bus_voltage[k] ** 2 * Gself(k) + == 0 + ) + model.p_load_constr = Constraint(range(nbus), rule=p_load_rule) + def q_load_rule(model, k): if bus[k].bustype != 0: return Constraint.Skip - - return bus[k].q_gen - bus[k].q_load - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm]) - Bin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to]) - Bout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) \ - + model.bus_voltage[k]**2*Bself(k) == 0 + + return ( + bus[k].q_gen + - bus[k].q_load + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + - Bin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + - Bout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Bself(k) + == 0 + ) + model.q_load_constr = Constraint(range(nbus), rule=q_load_rule) + def q_inj_rule(model, k): if not (bus[k].bustype == 2 or bus[k].bustype == 3): return Constraint.Skip - - return (bus[k].q_min, \ - bus[k].q_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm]) - Bin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to]) - Bout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) - \ - model.bus_voltage[k]**2*Bself(k), \ - bus[k].q_max) + + return ( + bus[k].q_min, + bus[k].q_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + - Bin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + - Bout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + - model.bus_voltage[k] ** 2 * Bself(k), + bus[k].q_max, + ) + model.q_inj_rule = Constraint(range(nbus), rule=q_inj_rule) + def p_inj_rule(model, k): if not (bus[k].bustype == 2 or bus[k].bustype == 3): return Constraint.Skip - - return (0, \ - bus[k].p_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm]) + Bin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to]) + Bout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) + \ - model.bus_voltage[k]**2*Gself(k),\ - p_gen_upper*bus[k].p_gen) + + return ( + 0, + bus[k].p_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Gself(k), + p_gen_upper * bus[k].p_gen, + ) + model.p_inj_rule = Constraint(range(nbus), rule=p_inj_rule) diff --git a/examples/performance/jump/opf_662bus.py b/examples/performance/jump/opf_662bus.py index e205287f385..6ff97c577e3 100644 --- a/examples/performance/jump/opf_662bus.py +++ b/examples/performance/jump/opf_662bus.py @@ -1,15 +1,18 @@ from pyomo.environ import * + class Bus: pass + class Branch: pass + bus = [] busmap = {} busfile = open("IEEE662.bus", "r") -for i,line in enumerate(busfile): +for i, line in enumerate(busfile): sp = line.split() b = Bus() busmap[sp[0]] = i @@ -40,7 +43,7 @@ class Branch: branchfile = open("IEEE662.branch", "r") branch = [] -for i,line in enumerate(branchfile): +for i, line in enumerate(branchfile): sp = line.split() b = Branch() b.frm = busmap[sp[1]] @@ -57,14 +60,14 @@ class Branch: b.def_max = float(sp[12]) b.g = b.r / (b.r**2 + b.x**2) b.b = -b.x / (b.r**2 + b.x**2) - b.def_min *= 3.14159/180 - b.def_max *= 3.14159/180 - b.def0 *= -3.14159/180 + b.def_min *= 3.14159 / 180 + b.def_max *= 3.14159 / 180 + b.def0 *= -3.14159 / 180 branch.append(b) -bus_voltage_min = {0 : 0.85, 1 : 0.85, 2 : 0.92, 3 : 0.99} -bus_voltage_max = {0 : 1.15, 1 : 1.15, 2 : 1.08, 3 : 1.01} +bus_voltage_min = {0: 0.85, 1: 0.85, 2: 0.92, 3: 0.99} +bus_voltage_max = {0: 1.15, 1: 1.15, 2: 1.08, 3: 1.01} branch_tap_min = 0.85 branch_tap_max = 1.15 @@ -74,108 +77,244 @@ class Branch: nbus = len(bus) nbranch = len(branch) -in_lines = [ [] for i in range(nbus) ] -out_lines = [ [] for i in range(nbus) ] +in_lines = [[] for i in range(nbus)] +out_lines = [[] for i in range(nbus)] for i in range(nbranch): b = branch[i] out_lines[b.frm].append(i) in_lines[b.to].append(i) - assert(b.to >= 0 and b.to < nbus) + assert b.to >= 0 and b.to < nbus model = ConcreteModel() -model.bus_voltage = Var(range(nbus),bounds = lambda model,i : (bus_voltage_min[bus[i].bustype], bus_voltage_max[bus[i].bustype]), initialize=1) -model.bus_b_shunt = Var(range(nbus),bounds = lambda model,i : (bus[i].b_shunt_min, bus[i].b_shunt_max), initialize = lambda model,i : bus[i].b_shunt0) +model.bus_voltage = Var( + range(nbus), + bounds=lambda model, i: ( + bus_voltage_min[bus[i].bustype], + bus_voltage_max[bus[i].bustype], + ), + initialize=1, +) +model.bus_b_shunt = Var( + range(nbus), + bounds=lambda model, i: (bus[i].b_shunt_min, bus[i].b_shunt_max), + initialize=lambda model, i: bus[i].b_shunt0, +) model.bus_angle = Var(range(nbus), initialize=0) -model.branch_tap = Var(range(nbranch), bounds=(branch_tap_min, branch_tap_max), initialize=1) -model.branch_def = Var(range(nbranch), bounds=lambda model,i: (branch[i].def_min, branch[i].def_max), initialize = lambda model,i : branch[i].def0) +model.branch_tap = Var( + range(nbranch), bounds=(branch_tap_min, branch_tap_max), initialize=1 +) +model.branch_def = Var( + range(nbranch), + bounds=lambda model, i: (branch[i].def_min, branch[i].def_max), + initialize=lambda model, i: branch[i].def0, +) + def Gself(k): - return bus[k].g_shunt + sum(branch[i].g*model.branch_tap[i]**2 for i in out_lines[k]) + sum(branch[i].g for i in in_lines[k]) + return ( + bus[k].g_shunt + + sum(branch[i].g * model.branch_tap[i] ** 2 for i in out_lines[k]) + + sum(branch[i].g for i in in_lines[k]) + ) + def Gout(i): - return (-branch[i].g*cos(model.branch_def[i])+branch[i].b*sin(model.branch_def[i]))*model.branch_tap[i] + return ( + -branch[i].g * cos(model.branch_def[i]) + branch[i].b * sin(model.branch_def[i]) + ) * model.branch_tap[i] + def Gin(i): - return (-branch[i].g*cos(model.branch_def[i])-branch[i].b*sin(model.branch_def[i]))*model.branch_tap[i] + return ( + -branch[i].g * cos(model.branch_def[i]) - branch[i].b * sin(model.branch_def[i]) + ) * model.branch_tap[i] + def Bself(k): - return model.bus_b_shunt[k] + sum(branch[i].b*model.branch_tap[i]**2 + branch[i].c/2 for i in out_lines[k]) + sum(branch[i].b + branch[i].c/2 for i in in_lines[k]) + return ( + model.bus_b_shunt[k] + + sum( + branch[i].b * model.branch_tap[i] ** 2 + branch[i].c / 2 + for i in out_lines[k] + ) + + sum(branch[i].b + branch[i].c / 2 for i in in_lines[k]) + ) + def Bin(i): - return (branch[i].g*sin(model.branch_def[i])-branch[i].b*cos(model.branch_def[i]))*model.branch_tap[i] + return ( + branch[i].g * sin(model.branch_def[i]) - branch[i].b * cos(model.branch_def[i]) + ) * model.branch_tap[i] + def Bout(i): - return (-branch[i].g*sin(model.branch_def[i])-branch[i].b*cos(model.branch_def[i]))*model.branch_tap[i] - -model.obj = Objective(expr = sum( \ - (bus[k].p_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + \ - Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm])) \ - for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + \ - Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to])) \ - for i in out_lines[k]) + \ - model.bus_voltage[k]**2*Gself(k) )**2 \ - for k in range(nbus) if bus[k].bustype == 2 or bus[k].bustype == 3)) + return ( + -branch[i].g * sin(model.branch_def[i]) - branch[i].b * cos(model.branch_def[i]) + ) * model.branch_tap[i] + + +model.obj = Objective( + expr=sum( + ( + bus[k].p_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Gself(k) + ) + ** 2 + for k in range(nbus) + if bus[k].bustype == 2 or bus[k].bustype == 3 + ) +) + def p_load_rule(model, k): if bus[k].bustype != 0: return Constraint.Skip - - return bus[k].p_gen - bus[k].p_load - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm]) + Bin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to]) + Bout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) - \ - model.bus_voltage[k]**2*Gself(k) == 0 + + return ( + bus[k].p_gen + - bus[k].p_load + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + - model.bus_voltage[k] ** 2 * Gself(k) + == 0 + ) + model.p_load_constr = Constraint(range(nbus), rule=p_load_rule) + def q_load_rule(model, k): if bus[k].bustype != 0: return Constraint.Skip - - return bus[k].q_gen - bus[k].q_load - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm]) - Bin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) - \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to]) - Bout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) \ - + model.bus_voltage[k]**2*Bself(k) == 0 + + return ( + bus[k].q_gen + - bus[k].q_load + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + - Bin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + - sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + - Bout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Bself(k) + == 0 + ) + model.q_load_constr = Constraint(range(nbus), rule=q_load_rule) + def q_inj_rule(model, k): if not (bus[k].bustype == 2 or bus[k].bustype == 3): return Constraint.Skip - - return (bus[k].q_min, \ - bus[k].q_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm]) - Bin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to]) - Bout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) - \ - model.bus_voltage[k]**2*Bself(k), \ - bus[k].q_max) + + return ( + bus[k].q_min, + bus[k].q_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + - Bin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + - Bout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + - model.bus_voltage[k] ** 2 * Bself(k), + bus[k].q_max, + ) + model.q_inj_rule = Constraint(range(nbus), rule=q_inj_rule) + def p_inj_rule(model, k): if not (bus[k].bustype == 2 or bus[k].bustype == 3): return Constraint.Skip - - return (0, \ - bus[k].p_load + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].frm] * \ - (Gin(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].frm]) + Bin(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].frm])) for i in in_lines[k]) + \ - sum( model.bus_voltage[k]*model.bus_voltage[branch[i].to] * \ - (Gout(i)*cos(model.bus_angle[k]-model.bus_angle[branch[i].to]) + Bout(i)*sin(model.bus_angle[k]-model.bus_angle[branch[i].to])) for i in out_lines[k]) + \ - model.bus_voltage[k]**2*Gself(k),\ - p_gen_upper*bus[k].p_gen) + + return ( + 0, + bus[k].p_load + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].frm] + * ( + Gin(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + + Bin(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].frm]) + ) + for i in in_lines[k] + ) + + sum( + model.bus_voltage[k] + * model.bus_voltage[branch[i].to] + * ( + Gout(i) * cos(model.bus_angle[k] - model.bus_angle[branch[i].to]) + + Bout(i) * sin(model.bus_angle[k] - model.bus_angle[branch[i].to]) + ) + for i in out_lines[k] + ) + + model.bus_voltage[k] ** 2 * Gself(k), + p_gen_upper * bus[k].p_gen, + ) + model.p_inj_rule = Constraint(range(nbus), rule=p_inj_rule) diff --git a/examples/performance/misc/bilinear1_100.py b/examples/performance/misc/bilinear1_100.py index d6bc3e5cc5e..a73a7b23f41 100644 --- a/examples/performance/misc/bilinear1_100.py +++ b/examples/performance/misc/bilinear1_100.py @@ -1,20 +1,22 @@ from pyomo.environ import * + def create_model(N): model = ConcreteModel() model.A = RangeSet(N) - model.x = Var(model.A, bounds=(1,2)) + model.x = Var(model.A, bounds=(1, 2)) - expr=0 + expr = 0 for i in model.A: - if not (i+1) in model.A: + if not (i + 1) in model.A: continue - expr += i*(model.x[i]*model.x[i+1]+1) + expr += i * (model.x[i] * model.x[i + 1] + 1) model.obj = Objective(expr=expr) return model + def pyomo_create_model(options=None, model_options=None): return create_model(100) diff --git a/examples/performance/misc/bilinear1_100000.py b/examples/performance/misc/bilinear1_100000.py index 6034cac2931..6d83468b46a 100644 --- a/examples/performance/misc/bilinear1_100000.py +++ b/examples/performance/misc/bilinear1_100000.py @@ -1,20 +1,22 @@ from pyomo.environ import * + def create_model(N): model = ConcreteModel() model.A = RangeSet(N) - model.x = Var(model.A, bounds=(1,2)) + model.x = Var(model.A, bounds=(1, 2)) - expr=0 + expr = 0 for i in model.A: - if not (i+1) in model.A: + if not (i + 1) in model.A: continue - expr += i*(model.x[i]*model.x[i+1]+1) + expr += i * (model.x[i] * model.x[i + 1] + 1) model.obj = Objective(expr=expr) return model + def pyomo_create_model(options=None, model_options=None): return create_model(100000) diff --git a/examples/performance/misc/bilinear2_100.py b/examples/performance/misc/bilinear2_100.py index 2997631e727..040aad2363b 100644 --- a/examples/performance/misc/bilinear2_100.py +++ b/examples/performance/misc/bilinear2_100.py @@ -1,20 +1,22 @@ from pyomo.environ import * + def create_model(N): model = ConcreteModel() model.A = RangeSet(N) - model.x = Var(model.A, bounds=(1,2)) + model.x = Var(model.A, bounds=(1, 2)) with nonlinear_expression as expr: for i in model.A: - if not (i+1) in model.A: + if not (i + 1) in model.A: continue - expr += i*(model.x[i]*model.x[i+1]+1) + expr += i * (model.x[i] * model.x[i + 1] + 1) model.obj = Objective(expr=expr) return model + def pyomo_create_model(options=None, model_options=None): return create_model(100) diff --git a/examples/performance/misc/bilinear2_100000.py b/examples/performance/misc/bilinear2_100000.py index c999ab5f081..4d1124f0cae 100644 --- a/examples/performance/misc/bilinear2_100000.py +++ b/examples/performance/misc/bilinear2_100000.py @@ -1,20 +1,22 @@ from pyomo.environ import * + def create_model(N): model = ConcreteModel() model.A = RangeSet(N) - model.x = Var(model.A, bounds=(1,2)) + model.x = Var(model.A, bounds=(1, 2)) with nonlinear_expression as expr: for i in model.A: - if not (i+1) in model.A: + if not (i + 1) in model.A: continue - expr += i*(model.x[i]*model.x[i+1]+1) + expr += i * (model.x[i] * model.x[i + 1] + 1) model.obj = Objective(expr=expr) return model + def pyomo_create_model(options=None, model_options=None): return create_model(100000) diff --git a/examples/performance/misc/diag1_100.py b/examples/performance/misc/diag1_100.py index 7f791d18f2d..e47a9179974 100644 --- a/examples/performance/misc/diag1_100.py +++ b/examples/performance/misc/diag1_100.py @@ -1,19 +1,22 @@ from pyomo.environ import * + def create_model(N): model = ConcreteModel() model.A = RangeSet(N) model.x = Var(model.A) - expr=sum(i*model.x[i] for i in model.A) + expr = sum(i * model.x[i] for i in model.A) model.obj = Objective(expr=expr) def c_rule(model, i): - return (N-i+1)*model.x[i] >= N + return (N - i + 1) * model.x[i] >= N + model.c = Constraint(model.A) return model + def pyomo_create_model(options=None, model_options=None): return create_model(100) diff --git a/examples/performance/misc/diag1_100000.py b/examples/performance/misc/diag1_100000.py index c690f375dad..a110c0d9d67 100644 --- a/examples/performance/misc/diag1_100000.py +++ b/examples/performance/misc/diag1_100000.py @@ -1,19 +1,22 @@ from pyomo.environ import * + def create_model(N): model = ConcreteModel() model.A = RangeSet(N) model.x = Var(model.A) - expr=sum(i*model.x[i] for i in model.A) + expr = sum(i * model.x[i] for i in model.A) model.obj = Objective(expr=expr) def c_rule(model, i): - return (N-i+1)*model.x[i] >= N + return (N - i + 1) * model.x[i] >= N + model.c = Constraint(model.A) return model + def pyomo_create_model(options=None, model_options=None): return create_model(100000) diff --git a/examples/performance/misc/diag2_100.py b/examples/performance/misc/diag2_100.py index abe47d625cf..fe820e8590b 100644 --- a/examples/performance/misc/diag2_100.py +++ b/examples/performance/misc/diag2_100.py @@ -1,19 +1,22 @@ from pyomo.environ import * + def create_model(N): model = ConcreteModel() model.A = RangeSet(N) model.x = Var(model.A) - expr = Sum(i*model.x[i] for i in model.A) + expr = Sum(i * model.x[i] for i in model.A) model.obj = Objective(expr=expr) def c_rule(model, i): - return (N-i+1)*model.x[i] >= N + return (N - i + 1) * model.x[i] >= N + model.c = Constraint(model.A) return model + def pyomo_create_model(options=None, model_options=None): return create_model(100) diff --git a/examples/performance/misc/diag2_100000.py b/examples/performance/misc/diag2_100000.py index 100e378caae..38563de57b9 100644 --- a/examples/performance/misc/diag2_100000.py +++ b/examples/performance/misc/diag2_100000.py @@ -1,19 +1,22 @@ from pyomo.environ import * + def create_model(N): model = ConcreteModel() model.A = RangeSet(N) model.x = Var(model.A) - expr = Sum(i*model.x[i] for i in model.A) + expr = Sum(i * model.x[i] for i in model.A) model.obj = Objective(expr=expr) def c_rule(model, i): - return (N-i+1)*model.x[i] >= N + return (N - i + 1) * model.x[i] >= N + model.c = Constraint(model.A) return model + def pyomo_create_model(options=None, model_options=None): return create_model(100000) diff --git a/examples/performance/misc/sparse1.py b/examples/performance/misc/sparse1.py index 0026f9fc94f..264862760f9 100644 --- a/examples/performance/misc/sparse1.py +++ b/examples/performance/misc/sparse1.py @@ -9,13 +9,16 @@ def f(N): M.A = Set(initialize=range(N)) M.x = Var() M.o = Objective(expr=M.x) + def rule(m, i): if i == 3 or i == 5: return M.x >= i return Constraint.Skip + M.c = Constraint(M.A, rule=rule) return M + # # Generation of this model is slow because set M.A is big # diff --git a/examples/performance/pmedian/pmedian1.py b/examples/performance/pmedian/pmedian1.py index dbb883e59bf..3d3f6c5407f 100644 --- a/examples/performance/pmedian/pmedian1.py +++ b/examples/performance/pmedian/pmedian1.py @@ -12,6 +12,7 @@ from pyomo.environ import * + def pyomo_create_model(options=None, model_options=None): import random @@ -21,34 +22,47 @@ def pyomo_create_model(options=None, model_options=None): model.N = Param(within=PositiveIntegers) - model.Locations = RangeSet(1,model.N) + model.Locations = RangeSet(1, model.N) - model.P = Param(within=RangeSet(1,model.N)) + model.P = Param(within=RangeSet(1, model.N)) model.M = Param(within=PositiveIntegers) - model.Customers = RangeSet(1,model.M) + model.Customers = RangeSet(1, model.M) - model.d = Param(model.Locations, model.Customers, initialize=lambda n, m, model : random.uniform(1.0,2.0), within=Reals) + model.d = Param( + model.Locations, + model.Customers, + initialize=lambda n, m, model: random.uniform(1.0, 2.0), + within=Reals, + ) - model.x = Var(model.Locations, model.Customers, bounds=(0.0,1.0), initialize=0.0) + model.x = Var(model.Locations, model.Customers, bounds=(0.0, 1.0), initialize=0.0) model.y = Var(model.Locations, bounds=(0.0, 1.0), initialize=0.0) def rule(model): - return sum( model.d[n,m]*model.x[n,m] for n in model.Locations for m in model.Customers ) + return sum( + model.d[n, m] * model.x[n, m] + for n in model.Locations + for m in model.Customers + ) + model.obj = Objective(rule=rule) def rule(model, m): - return (sum( model.x[n,m] for n in model.Locations ), 1.0) + return (sum(model.x[n, m] for n in model.Locations), 1.0) + model.single_x = Constraint(model.Customers, rule=rule) - def rule(model, n,m): - return (None, model.x[n,m] - model.y[n], 0.0) + def rule(model, n, m): + return (None, model.x[n, m] - model.y[n], 0.0) + model.bound_y = Constraint(model.Locations, model.Customers, rule=rule) def rule(model): - return (sum( model.y[n] for n in model.Locations ) - model.P, 0.0) + return (sum(model.y[n] for n in model.Locations) - model.P, 0.0) + model.num_facilities = Constraint(rule=rule) return model diff --git a/examples/performance/pmedian/pmedian2.py b/examples/performance/pmedian/pmedian2.py index 006bbf317ff..434ded6dcbc 100644 --- a/examples/performance/pmedian/pmedian2.py +++ b/examples/performance/pmedian/pmedian2.py @@ -12,6 +12,7 @@ from pyomo.environ import * + def pyomo_create_model(options=None, model_options=None): import random @@ -21,34 +22,47 @@ def pyomo_create_model(options=None, model_options=None): model.N = Param(within=PositiveIntegers) - model.Locations = RangeSet(1,model.N) + model.Locations = RangeSet(1, model.N) - model.P = Param(within=RangeSet(1,model.N)) + model.P = Param(within=RangeSet(1, model.N)) model.M = Param(within=PositiveIntegers) - model.Customers = RangeSet(1,model.M) + model.Customers = RangeSet(1, model.M) - model.d = Param(model.Locations, model.Customers, initialize=lambda n, m, model : random.uniform(1.0,2.0), within=Reals) + model.d = Param( + model.Locations, + model.Customers, + initialize=lambda n, m, model: random.uniform(1.0, 2.0), + within=Reals, + ) - model.x = Var(model.Locations, model.Customers, bounds=(0.0,1.0), initialize=0.0) + model.x = Var(model.Locations, model.Customers, bounds=(0.0, 1.0), initialize=0.0) model.y = Var(model.Locations, bounds=(0.0, 1.0), initialize=0.0) def rule(model): - return Sum(model.d[n,m]*model.x[n,m] for n in model.Locations for m in model.Customers) + return Sum( + model.d[n, m] * model.x[n, m] + for n in model.Locations + for m in model.Customers + ) + model.obj = Objective(rule=rule) def rule(model, m): - return (Sum(model.x[n,m] for n in model.Locations), 1.0) + return (Sum(model.x[n, m] for n in model.Locations), 1.0) + model.single_x = Constraint(model.Customers, rule=rule) - def rule(model, n,m): - return (None, model.x[n,m] - model.y[n], 0.0) + def rule(model, n, m): + return (None, model.x[n, m] - model.y[n], 0.0) + model.bound_y = Constraint(model.Locations, model.Customers, rule=rule) def rule(model): return (Sum(model.y[n] for n in model.Locations) - model.P, 0.0) + model.num_facilities = Constraint(rule=rule) return model diff --git a/examples/pyomo/amplbook2/diet.py b/examples/pyomo/amplbook2/diet.py index 3b1cb313adc..8cdffefa20f 100644 --- a/examples/pyomo/amplbook2/diet.py +++ b/examples/pyomo/amplbook2/diet.py @@ -27,29 +27,44 @@ model.f_min = Param(model.FOOD, within=NonNegativeReals) -def f_max_valid (model, value, j): + +def f_max_valid(model, value, j): return value > model.f_min[j] + + model.f_max = Param(model.FOOD, validate=f_max_valid) model.n_min = Param(model.NUTR, within=NonNegativeReals) + def paramn_max(model, value, i): return value > model.n_min[i] + + model.n_max = Param(model.NUTR, validate=paramn_max) model.amt = Param(model.NUTR, model.FOOD, within=NonNegativeReals) + def Buy_bounds(model, i): - return (model.f_min[i],model.f_max[i]) + return (model.f_min[i], model.f_max[i]) + + model.Buy = Var(model.FOOD, bounds=Buy_bounds) + def Objective_rule(model): return sum_product(model.cost, model.Buy) + + model.totalcost = Objective(rule=Objective_rule) + def Diet_rule(model, i): expr = 0 for j in model.FOOD: - expr = expr + model.amt[i,j] * model.Buy[j] + expr = expr + model.amt[i, j] * model.Buy[j] return (model.n_min[i], expr, model.n_max[i]) + + model.Diet = Constraint(model.NUTR, rule=Diet_rule) diff --git a/examples/pyomo/amplbook2/dieti.py b/examples/pyomo/amplbook2/dieti.py index 261ece5da24..0934dcf83c6 100644 --- a/examples/pyomo/amplbook2/dieti.py +++ b/examples/pyomo/amplbook2/dieti.py @@ -27,29 +27,44 @@ model.f_min = Param(model.FOOD, within=NonNegativeReals) -def f_max_valid (model, value, j): + +def f_max_valid(model, value, j): return value > model.f_min[j] + + model.f_max = Param(model.FOOD, validate=f_max_valid) model.n_min = Param(model.NUTR, within=NonNegativeReals) -def paramn_max (model, value, i): + +def paramn_max(model, value, i): return value > model.n_min[i] + + model.n_max = Param(model.NUTR, validate=paramn_max) model.amt = Param(model.NUTR, model.FOOD, within=NonNegativeReals) -def Buy_bounds(model,i): - return (model.f_min[i],model.f_max[i]) + +def Buy_bounds(model, i): + return (model.f_min[i], model.f_max[i]) + + model.Buy = Var(model.FOOD, bounds=Buy_bounds, domain=Integers) + def Objective_rule(model): return sum_product(model.cost, model.Buy) + + model.totalcost = Objective(rule=Objective_rule) + def Diet_rule(model, i): expr = 0 for j in model.FOOD: - expr = expr + model.amt[i,j] * model.Buy[j] + expr = expr + model.amt[i, j] * model.Buy[j] return (model.n_min[i], expr, model.n_max[i]) + + model.Diet = Constraint(model.NUTR, rule=Diet_rule) diff --git a/examples/pyomo/amplbook2/econ2min.py b/examples/pyomo/amplbook2/econ2min.py index 4022f6559ce..0d27df780bb 100644 --- a/examples/pyomo/amplbook2/econ2min.py +++ b/examples/pyomo/amplbook2/econ2min.py @@ -28,31 +28,55 @@ # *********************************** -model.cost = Param(model.ACT, within=PositiveReals, doc='cost per unit of each activity') +model.cost = Param( + model.ACT, within=PositiveReals, doc='cost per unit of each activity' +) -model.demand = Param(model.PROD, within=NonNegativeReals, doc='units of demand for each product') +model.demand = Param( + model.PROD, within=NonNegativeReals, doc='units of demand for each product' +) -model.io = Param(model.PROD, model.ACT, within=NonNegativeReals, doc='units of each product from 1 unit of each activity') +model.io = Param( + model.PROD, + model.ACT, + within=NonNegativeReals, + doc='units of each product from 1 unit of each activity', +) -model.level_min = Param(model.ACT, within=NonNegativeReals, doc='min allowed level for each activity') +model.level_min = Param( + model.ACT, within=NonNegativeReals, doc='min allowed level for each activity' +) -model.level_max = Param(model.ACT, within=NonNegativeReals, doc='max allowed level for each activity') +model.level_max = Param( + model.ACT, within=NonNegativeReals, doc='max allowed level for each activity' +) # *********************************** + def Level_bounds(model, i): return (model.level_min[i], model.level_max[i]) + + model.Level = Var(model.ACT, bounds=Level_bounds, doc='level for each activity') # *********************************** + def Total_Cost_rule(model): return sum_product(model.cost, model.Level) + + model.Total_Cost = Objective(rule=Total_Cost_rule, doc='minimize total cost') + def Demand_rule(model, i): expr = 0 for j in model.ACT: - expr += model.io[i,j] * model.Level[j] + expr += model.io[i, j] * model.Level[j] return model.demand[i] < expr -model.Demand = Constraint(model.PROD, rule=Demand_rule, doc='total level for each activity exceeds demand') + + +model.Demand = Constraint( + model.PROD, rule=Demand_rule, doc='total level for each activity exceeds demand' +) diff --git a/examples/pyomo/amplbook2/econmin.py b/examples/pyomo/amplbook2/econmin.py index 173e58d8e11..84e41107ff2 100644 --- a/examples/pyomo/amplbook2/econmin.py +++ b/examples/pyomo/amplbook2/econmin.py @@ -39,13 +39,19 @@ # *********************************** + def Total_Cost_rule(model): return sum_product(model.cost, model.Level) + + model.Total_Cost = Objective(rule=Total_Cost_rule) + def Demand_rule(model, i): expr = 0 for j in model.ACT: - expr += model.io[i,j] * model.Level[j] + expr += model.io[i, j] * model.Level[j] return expr > model.demand[i] + + model.Demand = Constraint(model.PROD, rule=Demand_rule) diff --git a/examples/pyomo/amplbook2/prod.py b/examples/pyomo/amplbook2/prod.py index 066f6a3b113..e1ffea959f0 100644 --- a/examples/pyomo/amplbook2/prod.py +++ b/examples/pyomo/amplbook2/prod.py @@ -29,15 +29,21 @@ # Objective def Objective_rule(model): - return sum([model.c[j]*model.X[j] for j in model.P]) + return sum([model.c[j] * model.X[j] for j in model.P]) + + model.Total_Profit = Objective(rule=Objective_rule, sense=maximize) # Time Constraint def Time_rule(model): return sum_product(model.X, denom=model.a) <= model.b + + model.Time = Constraint(rule=Time_rule) # Limit Constraint def Limit_rule(model, j): return (0, model.X[j], model.u[j]) + + model.Limit = Constraint(model.P, rule=Limit_rule) diff --git a/examples/pyomo/amplbook2/steel.py b/examples/pyomo/amplbook2/steel.py index 2fe276220e5..43bea775526 100644 --- a/examples/pyomo/amplbook2/steel.py +++ b/examples/pyomo/amplbook2/steel.py @@ -22,7 +22,7 @@ model.PROD = Set() -model.rate = Param(model.PROD,within=PositiveReals) +model.rate = Param(model.PROD, within=PositiveReals) model.avail = Param(within=NonNegativeReals) @@ -30,20 +30,30 @@ model.market = Param(model.PROD, within=NonNegativeReals) -def Make_bounds(model,i): - return (0,model.market[i]) + +def Make_bounds(model, i): + return (0, model.market[i]) + + model.Make = Var(model.PROD, bounds=Make_bounds) + def Objective_rule(model): return sum_product(model.profit, model.Make) + + model.Total_Profit = Objective(rule=Objective_rule, sense=maximize) + def Time_rule(model): ans = 0 for p in model.PROD: - ans = ans + (1.0/model.rate[p]) * model.Make[p] + ans = ans + (1.0 / model.rate[p]) * model.Make[p] return ans < model.avail + def XTime_rule(model): - return sum_product(model.Make, denom=(model.rate,) ) < model.avail -#model.Time = Constraint(rule=Time_rule) + return sum_product(model.Make, denom=(model.rate,)) < model.avail + + +# model.Time = Constraint(rule=Time_rule) diff --git a/examples/pyomo/amplbook2/steel3.py b/examples/pyomo/amplbook2/steel3.py index f0681a4723b..e9e494b6a1a 100644 --- a/examples/pyomo/amplbook2/steel3.py +++ b/examples/pyomo/amplbook2/steel3.py @@ -32,14 +32,23 @@ model.market = Param(model.PROD, within=NonNegativeReals) + def Make_bounds(model, i): - return (model.commit[i],model.market[i]) + return (model.commit[i], model.market[i]) + + model.Make = Var(model.PROD, bounds=Make_bounds) + def Objective_rule(model): return sum_product(model.profit, model.Make) + + model.totalprofit = Objective(rule=Objective_rule, sense=maximize) + def Time_rule(model): return sum_product(model.Make, denom=(model.rate)) < model.avail + + model.Time = Constraint(rule=Time_rule) diff --git a/examples/pyomo/amplbook2/steel4.py b/examples/pyomo/amplbook2/steel4.py index d88c5210128..b6709e478e9 100644 --- a/examples/pyomo/amplbook2/steel4.py +++ b/examples/pyomo/amplbook2/steel4.py @@ -34,17 +34,26 @@ model.market = Param(model.PROD, within=NonNegativeReals) -def Make_bounds(model,i): - return (model.commit[i],model.market[i]) + +def Make_bounds(model, i): + return (model.commit[i], model.market[i]) + + model.Make = Var(model.PROD, bounds=Make_bounds) -def Objective_rule (model): + +def Objective_rule(model): return sum_product(model.profit, model.Make) + + model.Total_Profit = Objective(rule=Objective_rule, sense=maximize) + def Timelim_rule(model, s): timeexpr = 0 for p in model.PROD: - timeexpr = timeexpr + (1.0/model.rate[p,s]) * model.Make[p] + timeexpr = timeexpr + (1.0 / model.rate[p, s]) * model.Make[p] return timeexpr < model.avail[s] + + model.Time = Constraint(model.STAGE, rule=Timelim_rule) diff --git a/examples/pyomo/benders/master.py b/examples/pyomo/benders/master.py index 69aa55b67e3..a457bf28b06 100644 --- a/examples/pyomo/benders/master.py +++ b/examples/pyomo/benders/master.py @@ -54,8 +54,11 @@ # projected revenue/ton, per scenario. model.revenue = Param(model.PROD, model.WEEKS, model.SCEN, within=NonNegativeReals) + def prob_validator(model, value, s): return (value >= 0) and (value <= 1.0) + + model.prob = Param(model.SCEN, validate=prob_validator) ############################################################################## @@ -64,8 +67,11 @@ def prob_validator(model, value, s): model.Inv1 = Var(model.PROD, within=NonNegativeReals) + def sell_bounds(model, p): return (0, model.market[p, 1]) + + model.Sell1 = Var(model.PROD, within=NonNegativeReals, bounds=sell_bounds) model.Min_Stage2_Profit = Var(within=NonNegativeReals) @@ -74,32 +80,52 @@ def sell_bounds(model, p): model.CUTS = Set(within=PositiveIntegers, ordered=True) -model.time_price = Param(model.TWOPLUSWEEKS, model.SCEN, \ - model.CUTS, default=0.0, mutable=True) +model.time_price = Param( + model.TWOPLUSWEEKS, model.SCEN, model.CUTS, default=0.0, mutable=True +) + +model.bal2_price = Param(model.PROD, model.SCEN, model.CUTS, default=0.0, mutable=True) -model.bal2_price = Param(model.PROD, model.SCEN, model.CUTS, \ - default=0.0, mutable=True) +model.sell_lim_price = Param( + model.PROD, model.TWOPLUSWEEKS, model.SCEN, model.CUTS, default=0.0, mutable=True +) -model.sell_lim_price = Param(model.PROD, model.TWOPLUSWEEKS, \ - model.SCEN, model.CUTS, \ - default=0.0, mutable=True) def time1_rule(model): - return (None, sum([1.0 / model.rate[p] * model.Make1[p] for p in model.PROD]) - model.avail[1], 0.0) + return ( + None, + sum([1.0 / model.rate[p] * model.Make1[p] for p in model.PROD]) + - model.avail[1], + 0.0, + ) + + model.Time1 = Constraint(rule=time1_rule) + def balance1_rule(model, p): - return model.Make1[p] + model.inv0[p] - (model.Sell1[p] + model.Inv1[p]) == 0.0 + return model.Make1[p] + model.inv0[p] - (model.Sell1[p] + model.Inv1[p]) == 0.0 + + model.Balance1 = Constraint(model.PROD, rule=balance1_rule) # cuts are generated on-the-fly, so no rules are necessary. model.Cut_Defn = ConstraintList() + def expected_profit_rule(model): - return sum([model.prob[s] * model.revenue[p, 1, s] * model.Sell1[p] - \ - model.prob[s] * model.prodcost[p] * model.Make1[p] - \ - model.prob[s] * model.invcost[p] * model.Inv1[p] \ - for p in model.PROD for s in model.SCEN]) + \ - model.Min_Stage2_Profit + return ( + sum( + [ + model.prob[s] * model.revenue[p, 1, s] * model.Sell1[p] + - model.prob[s] * model.prodcost[p] * model.Make1[p] + - model.prob[s] * model.invcost[p] * model.Inv1[p] + for p in model.PROD + for s in model.SCEN + ] + ) + + model.Min_Stage2_Profit + ) + model.Expected_Profit = Objective(rule=expected_profit_rule, sense=maximize) diff --git a/examples/pyomo/benders/subproblem.py b/examples/pyomo/benders/subproblem.py index 089ccb7f065..9268ae8e574 100644 --- a/examples/pyomo/benders/subproblem.py +++ b/examples/pyomo/benders/subproblem.py @@ -31,14 +31,22 @@ # derived set containing all valid week indices and subsets of interest. def weeks_rule(model): return list(sequence(model.T())) + + model.WEEKS = Set(initialize=weeks_rule, within=PositiveIntegers) + def two_plus_weeks_rule(model): return list(sequence(2, model.T())) + + model.TWOPLUSWEEKS = Set(initialize=two_plus_weeks_rule, within=PositiveIntegers) + def three_plus_weeks_rule(model): return list(sequence(3, model.T())) + + model.THREEPLUSWEEKS = Set(initialize=three_plus_weeks_rule, within=PositiveIntegers) # tons per hour produced @@ -62,6 +70,8 @@ def three_plus_weeks_rule(model): # scenario probability def unit_interval_validate(model, value): return (value >= 0.0) and (value <= 1.0) + + model.prob = Param(validate=unit_interval_validate) # inventory at end of first period. @@ -76,25 +86,53 @@ def unit_interval_validate(model, value): # tons sold def sell_bounds(model, p, t): return (0, model.market[p, t]) -model.Sell = Var(model.PROD, model.TWOPLUSWEEKS, within=NonNegativeReals, bounds=sell_bounds) + + +model.Sell = Var( + model.PROD, model.TWOPLUSWEEKS, within=NonNegativeReals, bounds=sell_bounds +) + def time_rule(model, t): - return sum([(1.0 / model.rate[p]) * model.Make[p, t] for p in model.PROD]) - model.avail[t] <= 0.0 + return ( + sum([(1.0 / model.rate[p]) * model.Make[p, t] for p in model.PROD]) + - model.avail[t] + <= 0.0 + ) + + model.Time = Constraint(model.TWOPLUSWEEKS, rule=time_rule) + def balance2_rule(model, p): - return (model.Make[p, 2] + model.inv1[p]) - (model.Sell[p, 2] + model.Inv[p, 2]) == 0.0 + return (model.Make[p, 2] + model.inv1[p]) - ( + model.Sell[p, 2] + model.Inv[p, 2] + ) == 0.0 + + model.Balance2 = Constraint(model.PROD, rule=balance2_rule) + def balance_rule(model, p, t): - return (model.Make[p, t] + model.Inv[p, t-1]) - (model.Sell[p, t] + model.Inv[p, t]) == 0.0 + return (model.Make[p, t] + model.Inv[p, t - 1]) - ( + model.Sell[p, t] + model.Inv[p, t] + ) == 0.0 + + model.Balance = Constraint(model.PROD, model.THREEPLUSWEEKS, rule=balance_rule) # the manual distribution of model.prob is ugly, but at the moment necessary; Pyomo # expression simplification will be significantly improved in the near-term future. def exp_stage2_profit_rule(model): - return sum([model.prob * model.revenue[p, t] * model.Sell[p, t] - \ - model.prob * model.prodcost[p] * model.Make[p, t] - \ - model.prob * model.invcost[p] * model.Inv[p, t] \ - for p in model.PROD for t in model.TWOPLUSWEEKS]) + return sum( + [ + model.prob * model.revenue[p, t] * model.Sell[p, t] + - model.prob * model.prodcost[p] * model.Make[p, t] + - model.prob * model.invcost[p] * model.Inv[p, t] + for p in model.PROD + for t in model.TWOPLUSWEEKS + ] + ) + + model.Exp_Stage2_Profit = Objective(rule=exp_stage2_profit_rule, sense=maximize) diff --git a/examples/pyomo/callbacks/sc.py b/examples/pyomo/callbacks/sc.py index b6477c1bc29..1ef3242c99f 100644 --- a/examples/pyomo/callbacks/sc.py +++ b/examples/pyomo/callbacks/sc.py @@ -14,8 +14,9 @@ import math import random -def print_model_stats(options,model): - print("-"*40) + +def print_model_stats(options, model): + print("-" * 40) if options is None: print("DEFAULT") else: @@ -26,22 +27,23 @@ def print_model_stats(options,model): colc = {} for i in model.J: colc[i] = 0 - for (i,j) in model.S: - rowc[i] += 1 - colc[j] += 1 + for (i, j) in model.S: + rowc[i] += 1 + colc[j] += 1 print("Row Counts") s = 0.0 for i in sorted(rowc): s += rowc[i] - print("Average: %s" % str(s/len(rowc))) + print("Average: %s" % str(s / len(rowc))) print("Col Counts") s = 0.0 for i in sorted(colc): s += colc[i] - print("Average: %s" % str(s/len(colc))) + print("Average: %s" % str(s / len(colc))) print("I %d" % len(model.I)) print("J %d" % len(model.J)) - print("-"*40) + print("-" * 40) + def pyomo_create_model(options=None, model_options=None): if model_options is None: @@ -73,12 +75,13 @@ def pyomo_create_model(options=None, model_options=None): # def S_rule(model): ans = set() - for j in range(1,n+1): - tmp = list(range(1,m+1)) - random.shuffle( tmp ) - for i in range(0,p): - ans.add( (tmp[i], j) ) + for j in range(1, n + 1): + tmp = list(range(1, m + 1)) + random.shuffle(tmp) + for i in range(0, p): + ans.add((tmp[i], j)) return ans + elif model_options.type == 'fixed_element_coverage': # # p - fixed number of sets that cover each element @@ -93,12 +96,13 @@ def S_rule(model): # def S_rule(model): ans = set() - for i in range(1,m+1): - tmp = list(range(1,n+1)) - random.shuffle( tmp ) - for j in range(0,p): - ans.add( (i, tmp[j]) ) + for i in range(1, m + 1): + tmp = list(range(1, n + 1)) + random.shuffle(tmp) + for j in range(0, p): + ans.add((i, tmp[j])) return ans + elif model_options.type == 'fixed_probability': # # rho - probability of selecting element for a set @@ -107,11 +111,12 @@ def S_rule(model): # def S_rule(model): ans = set() - for j in range(1,n+1): - for i in range(1,m+1): - if random.uniform(0,1) < rho: - ans.add( (i, j) ) + for j in range(1, n + 1): + for i in range(1, m + 1): + if random.uniform(0, 1) < rho: + ans.add((i, j)) return ans + elif model_options.type == 'fixed_fill': # # rho - |S|/(I*J) @@ -120,11 +125,12 @@ def S_rule(model): # def S_rule(model): ans = set() - for j in range(1,n+1): - for i in range(1,m+1): - if random.uniform(0,1) < rho: - ans.add( (i, j) ) + for j in range(1, n + 1): + for i in range(1, m + 1): + if random.uniform(0, 1) < rho: + ans.add((i, j)) return ans + # # CREATE MODEL # @@ -138,10 +144,13 @@ def S_rule(model): # some rows or columns of S may not be populated. # def I_rule(model): - return set((i for (i,j) in model.S)) + return set((i for (i, j) in model.S)) + model.I = Set(initialize=I_rule) + def J_rule(model): - return set((j for (i,j) in model.S)) + return set((j for (i, j) in model.S)) + model.J = Set(initialize=J_rule) # # Weights @@ -156,6 +165,7 @@ def J_rule(model): # def cost_rule(model): return sum_product(model.w, model.x) + model.cost = Objective(rule=cost_rule) # @@ -164,23 +174,26 @@ def cost_rule(model): def cover_rule(model, i): expr = 0 for j in model.x: - if (i,j) in model.S: + if (i, j) in model.S: expr += model.x[j] # # WEH - this check is not needed, since I is constructed dynamically # - #if expr is 0: - #return Constraint.Skip + # if expr is 0: + # return Constraint.Skip return expr >= 1 + model.cover = Constraint(model.I, rule=cover_rule) # print_model_stats(model_options, model) return model + def test_model(options=None): model = pyomo_create_model(model_options=options) - #print_model_stats(options, model) + # print_model_stats(options, model) + if __name__ == '__main__': test_model() @@ -209,4 +222,3 @@ def test_model(options=None): options.rho = 0.1 test_model(options) # - diff --git a/examples/pyomo/columngeneration/cutting_stock.py b/examples/pyomo/columngeneration/cutting_stock.py index 6d5ff0e8dda..296246a4ed6 100644 --- a/examples/pyomo/columngeneration/cutting_stock.py +++ b/examples/pyomo/columngeneration/cutting_stock.py @@ -21,45 +21,49 @@ import pyomo.environ as pyo - # width: number -demand = { 1380: 22, - 1520: 25, - 1560: 12, - 1710: 14, - 1820: 18, - 1880: 18, - 1930: 20, - 2000: 10, - 2050: 12, - 2100: 14, - 2140: 16, - 2150: 18, - 2200: 20, - } +# width: number +demand = { + 1380: 22, + 1520: 25, + 1560: 12, + 1710: 14, + 1820: 18, + 1880: 18, + 1930: 20, + 2000: 10, + 2050: 12, + 2100: 14, + 2140: 16, + 2150: 18, + 2200: 20, +} # master roll size W = 5600 + def create_base_cutting_stock(demand, W): - initial_patterns = dict() + initial_patterns = dict() ## cutting stock base problem cs = pyo.ConcreteModel() cs.pattern = pyo.VarList(domain=pyo.NonNegativeReals) - # add initial columns for each + # add initial columns for each # demanded width for i, width in enumerate(demand): cs.pattern.add() - initial_patterns[i+1] = { width: int( W // width ) } + initial_patterns[i + 1] = {width: int(W // width)} # add the demand constraints; supply initial identity columns; # filling in as many of a single width on a pattern as possible cs.demand = pyo.Constraint(demand.keys()) for i, (width, quantity) in enumerate(demand.items()): - cs.demand[width] = initial_patterns[i+1][width]*cs.pattern[i+1] >= quantity + cs.demand[width] = ( + initial_patterns[i + 1][width] * cs.pattern[i + 1] >= quantity + ) cs.obj = pyo.Objective(expr=pyo.quicksum(cs.pattern.values()), sense=pyo.minimize) @@ -70,19 +74,24 @@ def create_base_cutting_stock(demand, W): ks.widths = pyo.Var(demand.keys(), within=pyo.NonNegativeIntegers) - ks.knapsack = pyo.Constraint(expr=pyo.quicksum(width*ks.widths[width] for width in demand) <= W) + ks.knapsack = pyo.Constraint( + expr=pyo.quicksum(width * ks.widths[width] for width in demand) <= W + ) # blank objective, set by the dual values of cs ks.obj = pyo.Objective(expr=0, sense=pyo.maximize) return cs, ks, initial_patterns + def solve_cutting_stock(demand, W, solver, iterations=30): cs, ks, patterns = create_base_cutting_stock(demand, W) if '_persistent' not in solver: - raise RuntimeError('solver must be a string for pyo.SolverFactory and persistent') + raise RuntimeError( + 'solver must be a string for pyo.SolverFactory and persistent' + ) cs_s = pyo.SolverFactory(solver) ks_s = pyo.SolverFactory(solver) @@ -94,9 +103,9 @@ def solve_cutting_stock(demand, W, solver, iterations=30): cs_s.solve() - duals = { width : cs.dual[cs.demand[width]] for width in demand } + duals = {width: cs.dual[cs.demand[width]] for width in demand} - ks.obj.expr = sum(duals[width]*ks.widths[width] for width in demand) + ks.obj.expr = sum(duals[width] * ks.widths[width] for width in demand) ks_s.set_objective(ks.obj) @@ -108,7 +117,7 @@ def solve_cutting_stock(demand, W, solver, iterations=30): # else we'll add the column from ks new_pattern_var = cs.pattern.add() - np_widths = [] + np_widths = [] np_constraints = [] pattern = dict() @@ -123,7 +132,7 @@ def solve_cutting_stock(demand, W, solver, iterations=30): patterns[len(cs.pattern)] = pattern - cs_s.add_column(cs, new_pattern_var, 1., np_constraints, np_widths) + cs_s.add_column(cs, new_pattern_var, 1.0, np_constraints, np_widths) # heuristically solve the cutting stock problem with integer restrictions # to get an integer feasible solution @@ -137,18 +146,20 @@ def solve_cutting_stock(demand, W, solver, iterations=30): return cs, patterns + if __name__ == '__main__': import sys + solver = sys.argv[1] cs, patterns = solve_cutting_stock(demand, W, solver) - print('Sheets Required: '+str(int(pyo.value(cs.obj)))) + print('Sheets Required: ' + str(int(pyo.value(cs.obj)))) print('Repetition\tPattern') for idx, var in cs.pattern.items(): quantity = int(pyo.value(var)) if quantity > 0: - print_str = str(quantity)+'\t\t' + print_str = str(quantity) + '\t\t' for width, number in patterns[idx].items(): - print_str += str(int(number))+':'+str(int(width))+', ' + print_str += str(int(number)) + ':' + str(int(width)) + ', ' print(print_str[:-2]) diff --git a/examples/pyomo/concrete/Whiskas.py b/examples/pyomo/concrete/Whiskas.py index 8ae0b03b891..9bc8dd87e9d 100644 --- a/examples/pyomo/concrete/Whiskas.py +++ b/examples/pyomo/concrete/Whiskas.py @@ -16,53 +16,82 @@ Ingredients = ['CHICKEN', 'BEEF', 'MUTTON', 'RICE', 'WHEAT', 'GEL'] # A dictionary of the costs of each of the Ingredients is created -costs = {'CHICKEN': 0.013, - 'BEEF': 0.008, - 'MUTTON': 0.010, - 'RICE': 0.002, - 'WHEAT': 0.005, - 'GEL': 0.001} +costs = { + 'CHICKEN': 0.013, + 'BEEF': 0.008, + 'MUTTON': 0.010, + 'RICE': 0.002, + 'WHEAT': 0.005, + 'GEL': 0.001, +} # A dictionary of the protein percent in each of the Ingredients is created -proteinPercent = {'CHICKEN': 0.100, - 'BEEF': 0.200, - 'MUTTON': 0.150, - 'RICE': 0.000, - 'WHEAT': 0.040, - 'GEL': 0.000} +proteinPercent = { + 'CHICKEN': 0.100, + 'BEEF': 0.200, + 'MUTTON': 0.150, + 'RICE': 0.000, + 'WHEAT': 0.040, + 'GEL': 0.000, +} # A dictionary of the fat percent in each of the Ingredients is created -fatPercent = {'CHICKEN': 0.080, - 'BEEF': 0.100, - 'MUTTON': 0.110, - 'RICE': 0.010, - 'WHEAT': 0.010, - 'GEL': 0.000} +fatPercent = { + 'CHICKEN': 0.080, + 'BEEF': 0.100, + 'MUTTON': 0.110, + 'RICE': 0.010, + 'WHEAT': 0.010, + 'GEL': 0.000, +} # A dictionary of the fibre percent in each of the Ingredients is created -fibrePercent = {'CHICKEN': 0.001, - 'BEEF': 0.005, - 'MUTTON': 0.003, - 'RICE': 0.100, - 'WHEAT': 0.150, - 'GEL': 0.000} +fibrePercent = { + 'CHICKEN': 0.001, + 'BEEF': 0.005, + 'MUTTON': 0.003, + 'RICE': 0.100, + 'WHEAT': 0.150, + 'GEL': 0.000, +} # A dictionary of the salt percent in each of the Ingredients is created -saltPercent = {'CHICKEN': 0.002, - 'BEEF': 0.005, - 'MUTTON': 0.007, - 'RICE': 0.002, - 'WHEAT': 0.008, - 'GEL': 0.000} +saltPercent = { + 'CHICKEN': 0.002, + 'BEEF': 0.005, + 'MUTTON': 0.007, + 'RICE': 0.002, + 'WHEAT': 0.008, + 'GEL': 0.000, +} model = ConcreteModel(name="The Whiskas Problem") -model.ingredient_vars = Var(Ingredients, bounds=(0,None), doc="The amount of each ingredient that is used") +model.ingredient_vars = Var( + Ingredients, bounds=(0, None), doc="The amount of each ingredient that is used" +) -model.obj = Objective(expr=sum(costs[i]*model.ingredient_vars[i] for i in Ingredients), doc="Total Cost of Ingredients per can") +model.obj = Objective( + expr=sum(costs[i] * model.ingredient_vars[i] for i in Ingredients), + doc="Total Cost of Ingredients per can", +) -model.c0 = Constraint(expr=sum(model.ingredient_vars[i] for i in Ingredients) == 100, doc="PercentagesSum") -model.c1 = Constraint(expr=sum(proteinPercent[i] * model.ingredient_vars[i] for i in Ingredients) >= 8.0, doc="ProteinRequirement") -model.c2 = Constraint(expr=sum(fatPercent[i] * model.ingredient_vars[i] for i in Ingredients) >= 6.0, doc="FatRequirement") -model.c3 = Constraint(expr=sum(fibrePercent[i] * model.ingredient_vars[i] for i in Ingredients) <= 2.0, doc="FibreRequirement") -model.c4 = Constraint(expr=sum(saltPercent[i] * model.ingredient_vars[i] for i in Ingredients) <= 0.4, doc="SaltRequirement") +model.c0 = Constraint( + expr=sum(model.ingredient_vars[i] for i in Ingredients) == 100, doc="PercentagesSum" +) +model.c1 = Constraint( + expr=sum(proteinPercent[i] * model.ingredient_vars[i] for i in Ingredients) >= 8.0, + doc="ProteinRequirement", +) +model.c2 = Constraint( + expr=sum(fatPercent[i] * model.ingredient_vars[i] for i in Ingredients) >= 6.0, + doc="FatRequirement", +) +model.c3 = Constraint( + expr=sum(fibrePercent[i] * model.ingredient_vars[i] for i in Ingredients) <= 2.0, + doc="FibreRequirement", +) +model.c4 = Constraint( + expr=sum(saltPercent[i] * model.ingredient_vars[i] for i in Ingredients) <= 0.4, + doc="SaltRequirement", +) diff --git a/examples/pyomo/concrete/knapsack-abstract.py b/examples/pyomo/concrete/knapsack-abstract.py index e5efc203ce4..bbef95f7810 100644 --- a/examples/pyomo/concrete/knapsack-abstract.py +++ b/examples/pyomo/concrete/knapsack-abstract.py @@ -27,29 +27,27 @@ model.x = Var(model.ITEMS, within=Binary) + def value_rule(model): - return sum(model.v[i]*model.x[i] for i in model.ITEMS) + return sum(model.v[i] * model.x[i] for i in model.ITEMS) + + model.value = Objective(sense=maximize, rule=value_rule) + def weight_rule(model): - return sum(model.w[i]*model.x[i] for i in model.ITEMS) <= model.limit + return sum(model.w[i] * model.x[i] for i in model.ITEMS) <= model.limit + + model.weight = Constraint(rule=weight_rule) if __name__ == '__main__': data = { - 'ITEMS': {None:('hammer','wrench','screwdriver','towel')}, - 'v': {'hammer': 8, - 'wrench': 3, - 'screwdriver': 6, - 'towel': 11, - }, - 'w': { 'hammer': 5, - 'wrench': 7, - 'screwdriver': 4, - 'towel': 3, - }, - 'limit': {None:14}, + 'ITEMS': {None: ('hammer', 'wrench', 'screwdriver', 'towel')}, + 'v': {'hammer': 8, 'wrench': 3, 'screwdriver': 6, 'towel': 11}, + 'w': {'hammer': 5, 'wrench': 7, 'screwdriver': 4, 'towel': 3}, + 'limit': {None: 14}, } - inst = model.create_instance(data={None:data}) + inst = model.create_instance(data={None: data}) inst.pprint() diff --git a/examples/pyomo/concrete/knapsack-concrete.py b/examples/pyomo/concrete/knapsack-concrete.py index 5adbd8df71b..cd115ab40a3 100644 --- a/examples/pyomo/concrete/knapsack-concrete.py +++ b/examples/pyomo/concrete/knapsack-concrete.py @@ -15,8 +15,8 @@ from pyomo.environ import * -v = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11} -w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3} +v = {'hammer': 8, 'wrench': 3, 'screwdriver': 6, 'towel': 11} +w = {'hammer': 5, 'wrench': 7, 'screwdriver': 4, 'towel': 3} limit = 14 @@ -26,6 +26,6 @@ M.x = Var(M.ITEMS, within=Binary) -M.value = Objective(expr=sum(v[i]*M.x[i] for i in M.ITEMS), sense=maximize) +M.value = Objective(expr=sum(v[i] * M.x[i] for i in M.ITEMS), sense=maximize) -M.weight = Constraint(expr=sum(w[i]*M.x[i] for i in M.ITEMS) <= limit) +M.weight = Constraint(expr=sum(w[i] * M.x[i] for i in M.ITEMS) <= limit) diff --git a/examples/pyomo/concrete/rosen.py b/examples/pyomo/concrete/rosen.py index efa50f637ce..a8e8a175127 100644 --- a/examples/pyomo/concrete/rosen.py +++ b/examples/pyomo/concrete/rosen.py @@ -4,8 +4,6 @@ M = ConcreteModel() M.x = Var() M.y = Var() -M.o = Objective( - expr=(M.x-1)**2 + \ - 100*(M.y-M.x**2)**2) +M.o = Objective(expr=(M.x - 1) ** 2 + 100 * (M.y - M.x**2) ** 2) model = M diff --git a/examples/pyomo/concrete/sodacan.py b/examples/pyomo/concrete/sodacan.py index 10cb295e137..3c0cfd3aab2 100644 --- a/examples/pyomo/concrete/sodacan.py +++ b/examples/pyomo/concrete/sodacan.py @@ -3,9 +3,7 @@ from math import pi M = ConcreteModel() -M.r = Var(bounds=(0,None)) -M.h = Var(bounds=(0,None)) -M.o = Objective(expr=\ - 2*pi*M.r*(M.r + M.h)) -M.c = Constraint(expr=\ - pi*M.h*M.r**2 == 355) +M.r = Var(bounds=(0, None)) +M.h = Var(bounds=(0, None)) +M.o = Objective(expr=2 * pi * M.r * (M.r + M.h)) +M.c = Constraint(expr=pi * M.h * M.r**2 == 355) diff --git a/examples/pyomo/concrete/sodacan_fig.py b/examples/pyomo/concrete/sodacan_fig.py index 1f25651e732..bf9ae476b4c 100644 --- a/examples/pyomo/concrete/sodacan_fig.py +++ b/examples/pyomo/concrete/sodacan_fig.py @@ -10,22 +10,23 @@ R_ = np.arange(0.25, 10, 0.25) H_ = np.arange(0.25, 10, 0.25) R, H = np.meshgrid(R_, H_) -Z = 2*pi*R*(R+H) -surf = ax.plot_surface(R, H, Z, rstride=1, cstride=1, cmap=cm.hot, - linewidth=0, antialiased=False) +Z = 2 * pi * R * (R + H) +surf = ax.plot_surface( + R, H, Z, rstride=1, cstride=1, cmap=cm.hot, linewidth=0, antialiased=False +) ax.set_xlabel("r") ax.set_ylabel("h") ax.set_zlim(0, 1200) ax.zaxis.set_major_locator(LinearLocator(10)) -#ax.zaxis.set_major_formatter(FormatStrFormatter(' %.02f')) +# ax.zaxis.set_major_formatter(FormatStrFormatter(' %.02f')) -#fig.colorbar(surf, shrink=0.5, aspect=5) +# fig.colorbar(surf, shrink=0.5, aspect=5) -H_ = 355/(pi*R_*R_) +H_ = 355 / (pi * R_ * R_) valid = np.where(H_ < 10.1) -Z_ = R_+H_ -Z_ = 2*pi*R_*Z_ +Z_ = R_ + H_ +Z_ = 2 * pi * R_ * Z_ ax.plot(R_[valid], H_[valid], Z_[valid], label='parametric curve') plt.show() diff --git a/examples/pyomo/concrete/sp.py b/examples/pyomo/concrete/sp.py index 6c0f5281cd3..edc2d68b170 100644 --- a/examples/pyomo/concrete/sp.py +++ b/examples/pyomo/concrete/sp.py @@ -1,19 +1,25 @@ # sp.py from pyomo.environ import * -from sp_data import * # define c, b, h, and d +from sp_data import * # define c, b, h, and d -scenarios = range(1,6) +scenarios = range(1, 6) M = ConcreteModel() M.x = Var(within=NonNegativeReals) + def b_rule(B, i): - B.y = Var() - B.l = Constraint(expr=B.y >= (c-b)*M.x + b*d[i]) - B.u = Constraint(expr=B.y >= (c+h)*M.x + h*d[i]) - return B + B.y = Var() + B.l = Constraint(expr=B.y >= (c - b) * M.x + b * d[i]) + B.u = Constraint(expr=B.y >= (c + h) * M.x + h * d[i]) + return B + + M.B = Block(scenarios, rule=b_rule) + def o_rule(M): - return sum(M.B[i].y for i in scenarios)/5.0 + return sum(M.B[i].y for i in scenarios) / 5.0 + + M.o = Objective(rule=o_rule) diff --git a/examples/pyomo/concrete/sp_data.py b/examples/pyomo/concrete/sp_data.py index 080ff4f3e0e..58210126819 100644 --- a/examples/pyomo/concrete/sp_data.py +++ b/examples/pyomo/concrete/sp_data.py @@ -1,4 +1,4 @@ -c=1.0 -b=1.5 -h=0.1 -d = {1:15, 2:60, 3:72, 4:78, 5:82} +c = 1.0 +b = 1.5 +h = 0.1 +d = {1: 15, 2: 60, 3: 72, 4: 78, 5: 82} diff --git a/examples/pyomo/connectors/network_flow.py b/examples/pyomo/connectors/network_flow.py index 7a5b92a603f..921c70f098f 100644 --- a/examples/pyomo/connectors/network_flow.py +++ b/examples/pyomo/connectors/network_flow.py @@ -12,14 +12,16 @@ from pyomo.core import * + def pipe_rule(pipe, i): m = pipe.model() pipe.flow = Var() - pipe.pIn = Var( within=NonNegativeReals ) - pipe.pOut = Var( within=NonNegativeReals ) - pipe.pDrop = Constraint( expr=pipe.pIn - pipe.pOut == - m.friction*m.pipe_length[i]*pipe.flow ) - + pipe.pIn = Var(within=NonNegativeReals) + pipe.pOut = Var(within=NonNegativeReals) + pipe.pDrop = Constraint( + expr=pipe.pIn - pipe.pOut == m.friction * m.pipe_length[i] * pipe.flow + ) + pipe.IN = Connector() pipe.IN.add(-pipe.flow, "flow") pipe.IN.add(pipe.pIn, "pressure") @@ -28,45 +30,47 @@ def pipe_rule(pipe, i): pipe.OUT.add(pipe.flow) pipe.OUT.add(pipe.pOut, "pressure") + def node_rule(node, i): def _mass_balance(node, flows): return node.model().demands[i] == sum_product(flows) node.flow = VarList() - node.pressure = Var( within=NonNegativeReals ) + node.pressure = Var(within=NonNegativeReals) node.port = Connector() - #node.port.add(node.flow, + # node.port.add(node.flow, # aggregate=lambda n,v: n.model().demands[id] == sum_product(v)) - node.port.add( node.flow, aggregate=_mass_balance ) - node.port.add( node.pressure ) + node.port.add(node.flow, aggregate=_mass_balance) + node.port.add(node.pressure) def _src_rule(model, pipe): - return model.nodes[ value(model.pipe_links[pipe, 0]) ].port == \ - model.pipes[pipe].IN + return model.nodes[value(model.pipe_links[pipe, 0])].port == model.pipes[pipe].IN + def _sink_rule(model, pipe): - return model.nodes[ value(model.pipe_links[pipe, 1]) ].port == \ - model.pipes[pipe].OUT + return model.nodes[value(model.pipe_links[pipe, 1])].port == model.pipes[pipe].OUT model = AbstractModel() model.PIPES = Set() model.NODES = Set() -model.friction = Param( within=NonNegativeReals ) -model.pipe_length = Param( model.PIPES, within=NonNegativeReals ) -model.pipe_links = Param( model.PIPES, [0,1] ) -model.demands = Param( model.NODES, within=Reals, default=0 ) +model.friction = Param(within=NonNegativeReals) +model.pipe_length = Param(model.PIPES, within=NonNegativeReals) +model.pipe_links = Param(model.PIPES, [0, 1]) +model.demands = Param(model.NODES, within=Reals, default=0) -model.pipes = Block( model.PIPES, rule=pipe_rule ) -model.nodes = Block( model.NODES, rule=node_rule ) +model.pipes = Block(model.PIPES, rule=pipe_rule) +model.nodes = Block(model.NODES, rule=node_rule) # Connect the network -model.network_src = Constraint(model.PIPES, rule=_src_rule) +model.network_src = Constraint(model.PIPES, rule=_src_rule) model.network_sink = Constraint(model.PIPES, rule=_sink_rule) # Solve so the minimum pressure in the network is 0 def _obj(model): return sum(model.nodes[n].pressure for n in model.NODES) -model.obj = Objective( rule=_obj ) + + +model.obj = Objective(rule=_obj) diff --git a/examples/pyomo/connectors/network_flow_proposed.py b/examples/pyomo/connectors/network_flow_proposed.py index bee2cc4c2d6..e8226b486be 100644 --- a/examples/pyomo/connectors/network_flow_proposed.py +++ b/examples/pyomo/connectors/network_flow_proposed.py @@ -12,62 +12,66 @@ from pyomo.core import * + def pipe_rule(model, pipe, id): - pipe.length = Param( within=NonNegativeReals ) + pipe.length = Param(within=NonNegativeReals) pipe.flow = Var() - pipe.pIn = Var( within=NonNegativeReals ) - pipe.pOut = Var( within=NonNegativeReals ) - pipe.pDrop = Constraint( expr=pipe.pIn - pipe.pOut == - model.friction*model.pipe_length[id]*pipe.flow ) - + pipe.pIn = Var(within=NonNegativeReals) + pipe.pOut = Var(within=NonNegativeReals) + pipe.pDrop = Constraint( + expr=pipe.pIn - pipe.pOut == model.friction * model.pipe_length[id] * pipe.flow + ) + pipe.IN = Connector() - pipe.IN.add(-1*pipe.flow, "flow") + pipe.IN.add(-1 * pipe.flow, "flow") pipe.IN.add(pipe.pIn, "pressure") pipe.OUT = Connector() pipe.OUT.add(pipe.flow) pipe.OUT.add(pipe.pOut, "pressure") + def node_rule(model, node, id): def _mass_balance(model, node, flows): return node.demand == sum_product(flows) - node.demand = Param( within=Reals, default=0 ) + node.demand = Param(within=Reals, default=0) node.flow = VarList() - node.pressure = Var( within=NonNegativeReals ) + node.pressure = Var(within=NonNegativeReals) node.port = Connector() - #node.port.add( node.flow, + # node.port.add( node.flow, # aggregate=lambda m,n,v: m.demands[id] == sum_product(v) ) - node.port.add( node.flow, aggregate=_mass_balance ) - node.port.add( node.pressure ) + node.port.add(node.flow, aggregate=_mass_balance) + node.port.add(node.pressure) def _src_rule(model, pipe): - return model.nodes[ value(model.pipe_links[pipe, 0]) ].port == \ - model.pipes[pipe].IN + return model.nodes[value(model.pipe_links[pipe, 0])].port == model.pipes[pipe].IN + def _sink_rule(model, pipe): - return model.nodes[ value(model.pipe_links[pipe, 1]) ].port == \ - model.pipes[pipe].OUT + return model.nodes[value(model.pipe_links[pipe, 1])].port == model.pipes[pipe].OUT model = AbstractModel() model.PIPES = Set() model.NODES = Set() -model.friction = Param( within=NonNegativeReals ) -model.pipe_links = Param( model.PIPES, RangeSet(2) ) +model.friction = Param(within=NonNegativeReals) +model.pipe_links = Param(model.PIPES, RangeSet(2)) -model.pipes = Block( model.PIPES, rule=pipe_rule ) -model.nodes = Block( model.NODES, rule=node_rule ) +model.pipes = Block(model.PIPES, rule=pipe_rule) +model.nodes = Block(model.NODES, rule=node_rule) # Connect the network -model.network_src = Constraint(model.PIPES, rule=_src_rule) +model.network_src = Constraint(model.PIPES, rule=_src_rule) model.network_sink = Constraint(model.PIPES, rule=_sink_rule) # Solve so the minimum pressure in the network is 0 def _obj(model): return sum(model.nodes[n].pressure for n in model.NODES) -model.obj = Objective( rule=_obj ) + + +model.obj = Objective(rule=_obj) diff --git a/examples/pyomo/core/block1.py b/examples/pyomo/core/block1.py index 42f86708b79..96f8114f19c 100644 --- a/examples/pyomo/core/block1.py +++ b/examples/pyomo/core/block1.py @@ -17,5 +17,4 @@ model.b = Block() model.b.x = Var() -model.o = Objective(expr=(model.x-1.0)**2 + (model.b.x - 2.0)**2) - +model.o = Objective(expr=(model.x - 1.0) ** 2 + (model.b.x - 2.0) ** 2) diff --git a/examples/pyomo/core/integrality1.py b/examples/pyomo/core/integrality1.py index 5ddc01c5f8f..db81805555f 100644 --- a/examples/pyomo/core/integrality1.py +++ b/examples/pyomo/core/integrality1.py @@ -16,8 +16,8 @@ M.x2 = Var(within=Boolean) M.x3 = Var(within=Boolean) -M.o = Objective(expr=M.x1+M.x2+M.x3) -M.c1 = Constraint(expr=4*M.x1+M.x2 >= 1) -M.c2 = Constraint(expr=M.x2+4*M.x3 >= 1) +M.o = Objective(expr=M.x1 + M.x2 + M.x3) +M.c1 = Constraint(expr=4 * M.x1 + M.x2 >= 1) +M.c2 = Constraint(expr=M.x2 + 4 * M.x3 >= 1) -model=M +model = M diff --git a/examples/pyomo/core/integrality2.py b/examples/pyomo/core/integrality2.py index 661df5e3b3a..2d85c9f2455 100644 --- a/examples/pyomo/core/integrality2.py +++ b/examples/pyomo/core/integrality2.py @@ -12,10 +12,10 @@ from pyomo.environ import * M = ConcreteModel() -M.x = Var([1,2,3], within=Boolean) +M.x = Var([1, 2, 3], within=Boolean) M.o = Objective(expr=sum_product(M.x)) -M.c1 = Constraint(expr=4*M.x[1]+M.x[2] >= 1) -M.c2 = Constraint(expr=M.x[2]+4*M.x[3] >= 1) +M.c1 = Constraint(expr=4 * M.x[1] + M.x[2] >= 1) +M.c2 = Constraint(expr=M.x[2] + 4 * M.x[3] >= 1) -model=M +model = M diff --git a/examples/pyomo/core/simple.py b/examples/pyomo/core/simple.py index 2ba94471232..d0359c143bf 100644 --- a/examples/pyomo/core/simple.py +++ b/examples/pyomo/core/simple.py @@ -13,12 +13,10 @@ M = ConcreteModel() M.x1 = Var() -M.x2 = Var(bounds=(-1,1)) -M.x3 = Var(bounds=(1,2)) -M.o = Objective( - expr=M.x1**2 + (M.x2*M.x3)**4 + \ - M.x1*M.x3 + \ - M.x2*sin(M.x1+M.x3) + M.x2) +M.x2 = Var(bounds=(-1, 1)) +M.x3 = Var(bounds=(1, 2)) +M.o = Objective( + expr=M.x1**2 + (M.x2 * M.x3) ** 4 + M.x1 * M.x3 + M.x2 * sin(M.x1 + M.x3) + M.x2 +) model = M - diff --git a/examples/pyomo/core/t1.py b/examples/pyomo/core/t1.py index b5e4e49c2af..2f684e82abb 100644 --- a/examples/pyomo/core/t1.py +++ b/examples/pyomo/core/t1.py @@ -11,6 +11,7 @@ from pyomo.environ import * + def pyomo_create_model(options, model_options): model = ConcreteModel() @@ -18,11 +19,10 @@ def pyomo_create_model(options, model_options): model.x2 = Var(within=NonNegativeReals) model.x3 = Var(within=NonNegativeReals) - model.o = Objective(expr=6*model.x1 + 4*model.x2 + 2*model.x3, sense=minimize) + model.o = Objective(expr=6 * model.x1 + 4 * model.x2 + 2 * model.x3, sense=minimize) - model.c1 = Constraint(expr=4*model.x1 + 2*model.x2 + model.x3 >= 5) + model.c1 = Constraint(expr=4 * model.x1 + 2 * model.x2 + model.x3 >= 5) model.c2 = Constraint(expr=model.x1 + model.x2 >= 3) model.c3 = Constraint(expr=model.x2 + model.x3 >= 4) return model - diff --git a/examples/pyomo/core/t2.py b/examples/pyomo/core/t2.py index 81128d6537c..2c3b78726a9 100644 --- a/examples/pyomo/core/t2.py +++ b/examples/pyomo/core/t2.py @@ -11,6 +11,7 @@ from pyomo.environ import * + def pyomo_create_model(options, model_options): model = ConcreteModel() @@ -18,10 +19,10 @@ def pyomo_create_model(options, model_options): model.x2 = Var(within=NonPositiveReals) model.x3 = Var(within=Reals) - model.o = Objective(expr=model.x1 + 2*model.x2 + 3*model.x3, sense=maximize) + model.o = Objective(expr=model.x1 + 2 * model.x2 + 3 * model.x3, sense=maximize) - model.c1 = Constraint(expr= - model.x1 + 3*model.x2 == 5) - model.c2 = Constraint(expr=2*model.x1 - model.x2 + 3*model.x3 >= 6) + model.c1 = Constraint(expr=-model.x1 + 3 * model.x2 == 5) + model.c2 = Constraint(expr=2 * model.x1 - model.x2 + 3 * model.x3 >= 6) model.c3 = Constraint(expr=model.x3 <= 4) return model diff --git a/examples/pyomo/core/t5.py b/examples/pyomo/core/t5.py index f67956c9e17..2a678575dfa 100644 --- a/examples/pyomo/core/t5.py +++ b/examples/pyomo/core/t5.py @@ -15,17 +15,17 @@ # from pyomo.environ import * + def pyomo_create_model(options, model_options): model = ConcreteModel() model.x1 = Var(within=NonNegativeReals) model.x2 = Var(within=NonNegativeReals) - model.o = Objective(expr=3*model.x1 + 2.5*model.x2, sense=maximize) + model.o = Objective(expr=3 * model.x1 + 2.5 * model.x2, sense=maximize) - model.c1 = Constraint(expr=4.44*model.x1 <= 100) - model.c2 = Constraint(expr=6.67*model.x2 <= 100) - model.c3 = Constraint(expr=4*model.x1 + 2.86*model.x2 <= 100) - model.c4 = Constraint(expr=3*model.x1 + 6*model.x2 <= 100) + model.c1 = Constraint(expr=4.44 * model.x1 <= 100) + model.c2 = Constraint(expr=6.67 * model.x2 <= 100) + model.c3 = Constraint(expr=4 * model.x1 + 2.86 * model.x2 <= 100) + model.c4 = Constraint(expr=3 * model.x1 + 6 * model.x2 <= 100) return model - diff --git a/examples/pyomo/diet/diet-sqlite.py b/examples/pyomo/diet/diet-sqlite.py index 5be5c83832a..e8963485294 100644 --- a/examples/pyomo/diet/diet-sqlite.py +++ b/examples/pyomo/diet/diet-sqlite.py @@ -23,7 +23,8 @@ c.execute('DROP TABLE IF EXISTS ' + table) conn.commit() -c.execute(''' +c.execute( + ''' CREATE TABLE Food ( FOOD text not null, cost float not null, @@ -31,7 +32,8 @@ f_max float, PRIMARY KEY (FOOD) ) -''') +''' +) conn.commit() Food_data = [ @@ -43,20 +45,22 @@ ("Fries, small", 0.77, None, None), ("Sausage McMuffin", 1.29, None, None), ("1% Lowfat Milk", 0.60, None, None), - ("Orange Juice", 0.72, None, None) + ("Orange Juice", 0.72, None, None), ] for row in Food_data: c.execute('''INSERT INTO Food VALUES (?,?,?,?)''', row) conn.commit() -c.execute(''' +c.execute( + ''' CREATE TABLE Nutr ( NUTR text not null, n_min float, n_max float, PRIMARY KEY (NUTR) ) -''') +''' +) Nutr_data = [ ("Cal", 2000.0, None), @@ -65,13 +69,14 @@ ("VitA", 100.0, None), ("VitC", 100.0, None), ("Calc", 100.0, None), - ("Iron", 100.0, None) + ("Iron", 100.0, None), ] for row in Nutr_data: c.execute('''INSERT INTO Nutr VALUES (?,?,?)''', row) conn.commit() -c.execute(''' +c.execute( + ''' CREATE TABLE Amount ( NUTR text not null, FOOD varchar not null, @@ -80,73 +85,74 @@ FOREIGN KEY (NUTR) REFERENCES Nutr (NUTR), FOREIGN KEY (FOOD) REFERENCES Food (FOOD) ) -''') +''' +) conn.commit() Amount_data = [ - ('Cal','Quarter Pounder w Cheese','510'), - ('Carbo','Quarter Pounder w Cheese','34'), - ('Protein','Quarter Pounder w Cheese','28'), - ('VitA','Quarter Pounder w Cheese','15'), - ('VitC','Quarter Pounder w Cheese','6'), - ('Calc','Quarter Pounder w Cheese','30'), - ('Iron','Quarter Pounder w Cheese','20'), - ('Cal','McLean Deluxe w Cheese','370'), - ('Carbo','McLean Deluxe w Cheese','35'), - ('Protein','McLean Deluxe w Cheese','24'), - ('VitA','McLean Deluxe w Cheese','15'), - ('VitC','McLean Deluxe w Cheese','10'), - ('Calc','McLean Deluxe w Cheese','20'), - ('Iron','McLean Deluxe w Cheese','20'), - ('Cal','Big Mac','500'), - ('Carbo','Big Mac','42'), - ('Protein','Big Mac','25'), - ('VitA','Big Mac','6'), - ('VitC','Big Mac','2'), - ('Calc','Big Mac','25'), - ('Iron','Big Mac','20'), - ('Cal','Filet-O-Fish','370'), - ('Carbo','Filet-O-Fish','38'), - ('Protein','Filet-O-Fish','14'), - ('VitA','Filet-O-Fish','2'), - ('VitC','Filet-O-Fish','0'), - ('Calc','Filet-O-Fish','15'), - ('Iron','Filet-O-Fish','10'), - ('Cal','McGrilled Chicken','400'), - ('Carbo','McGrilled Chicken','42'), - ('Protein','McGrilled Chicken','31'), - ('VitA','McGrilled Chicken','8'), - ('VitC','McGrilled Chicken','15'), - ('Calc','McGrilled Chicken','15'), - ('Iron','McGrilled Chicken','8'), - ('Cal','Fries, small','220'), - ('Carbo','Fries, small','26'), - ('Protein','Fries, small','3'), - ('VitA','Fries, small','0'), - ('VitC','Fries, small','15'), - ('Calc','Fries, small','0'), - ('Iron','Fries, small','2'), - ('Cal','Sausage McMuffin','345'), - ('Carbo','Sausage McMuffin','27'), - ('Protein','Sausage McMuffin','15'), - ('VitA','Sausage McMuffin','4'), - ('VitC','Sausage McMuffin','0'), - ('Calc','Sausage McMuffin','20'), - ('Iron','Sausage McMuffin','15'), - ('Cal','1% Lowfat Milk','110'), - ('Carbo','1% Lowfat Milk','12'), - ('Protein','1% Lowfat Milk','9'), - ('VitA','1% Lowfat Milk','10'), - ('VitC','1% Lowfat Milk','4'), - ('Calc','1% Lowfat Milk','30'), - ('Iron','1% Lowfat Milk','0'), - ('Cal','Orange Juice','80'), - ('Carbo','Orange Juice','20'), - ('Protein','Orange Juice','1'), - ('VitA','Orange Juice','2'), - ('VitC','Orange Juice','120'), - ('Calc','Orange Juice','2'), - ('Iron','Orange Juice','2') + ('Cal', 'Quarter Pounder w Cheese', '510'), + ('Carbo', 'Quarter Pounder w Cheese', '34'), + ('Protein', 'Quarter Pounder w Cheese', '28'), + ('VitA', 'Quarter Pounder w Cheese', '15'), + ('VitC', 'Quarter Pounder w Cheese', '6'), + ('Calc', 'Quarter Pounder w Cheese', '30'), + ('Iron', 'Quarter Pounder w Cheese', '20'), + ('Cal', 'McLean Deluxe w Cheese', '370'), + ('Carbo', 'McLean Deluxe w Cheese', '35'), + ('Protein', 'McLean Deluxe w Cheese', '24'), + ('VitA', 'McLean Deluxe w Cheese', '15'), + ('VitC', 'McLean Deluxe w Cheese', '10'), + ('Calc', 'McLean Deluxe w Cheese', '20'), + ('Iron', 'McLean Deluxe w Cheese', '20'), + ('Cal', 'Big Mac', '500'), + ('Carbo', 'Big Mac', '42'), + ('Protein', 'Big Mac', '25'), + ('VitA', 'Big Mac', '6'), + ('VitC', 'Big Mac', '2'), + ('Calc', 'Big Mac', '25'), + ('Iron', 'Big Mac', '20'), + ('Cal', 'Filet-O-Fish', '370'), + ('Carbo', 'Filet-O-Fish', '38'), + ('Protein', 'Filet-O-Fish', '14'), + ('VitA', 'Filet-O-Fish', '2'), + ('VitC', 'Filet-O-Fish', '0'), + ('Calc', 'Filet-O-Fish', '15'), + ('Iron', 'Filet-O-Fish', '10'), + ('Cal', 'McGrilled Chicken', '400'), + ('Carbo', 'McGrilled Chicken', '42'), + ('Protein', 'McGrilled Chicken', '31'), + ('VitA', 'McGrilled Chicken', '8'), + ('VitC', 'McGrilled Chicken', '15'), + ('Calc', 'McGrilled Chicken', '15'), + ('Iron', 'McGrilled Chicken', '8'), + ('Cal', 'Fries, small', '220'), + ('Carbo', 'Fries, small', '26'), + ('Protein', 'Fries, small', '3'), + ('VitA', 'Fries, small', '0'), + ('VitC', 'Fries, small', '15'), + ('Calc', 'Fries, small', '0'), + ('Iron', 'Fries, small', '2'), + ('Cal', 'Sausage McMuffin', '345'), + ('Carbo', 'Sausage McMuffin', '27'), + ('Protein', 'Sausage McMuffin', '15'), + ('VitA', 'Sausage McMuffin', '4'), + ('VitC', 'Sausage McMuffin', '0'), + ('Calc', 'Sausage McMuffin', '20'), + ('Iron', 'Sausage McMuffin', '15'), + ('Cal', '1% Lowfat Milk', '110'), + ('Carbo', '1% Lowfat Milk', '12'), + ('Protein', '1% Lowfat Milk', '9'), + ('VitA', '1% Lowfat Milk', '10'), + ('VitC', '1% Lowfat Milk', '4'), + ('Calc', '1% Lowfat Milk', '30'), + ('Iron', '1% Lowfat Milk', '0'), + ('Cal', 'Orange Juice', '80'), + ('Carbo', 'Orange Juice', '20'), + ('Protein', 'Orange Juice', '1'), + ('VitA', 'Orange Juice', '2'), + ('VitC', 'Orange Juice', '120'), + ('Calc', 'Orange Juice', '2'), + ('Iron', 'Orange Juice', '2'), ] for row in Amount_data: c.execute('''INSERT INTO Amount VALUES (?,?,?)''', row) diff --git a/examples/pyomo/diet/diet1.py b/examples/pyomo/diet/diet1.py index 3eee2689e70..1fd61ca268c 100644 --- a/examples/pyomo/diet/diet1.py +++ b/examples/pyomo/diet/diet1.py @@ -28,9 +28,13 @@ model.f_min = Param(model.FOOD, within=NonNegativeReals, default=0.0) -MAX_FOOD_SUPPLY = 20.0 # McDonald's doesn't stock infinite food -def f_max_validate (model, value, j): +MAX_FOOD_SUPPLY = 20.0 # McDonald's doesn't stock infinite food + + +def f_max_validate(model, value, j): return model.f_max[j] > model.f_min[j] + + model.f_max = Param(model.FOOD, validate=f_max_validate, default=MAX_FOOD_SUPPLY) # Unneeded vars - they're in the .dat file, so we list them here @@ -41,29 +45,50 @@ def f_max_validate (model, value, j): # -------------------------------------------------------- + def Buy_bounds(model, i): return (model.f_min[i], model.f_max[i]) + + model.Buy = Var(model.FOOD, bounds=Buy_bounds, within=NonNegativeIntegers) # -------------------------------------------------------- + def Total_Cost_rule(model): return sum(model.cost[j] * model.Buy[j] for j in model.FOOD) + + model.Total_Cost = Objective(rule=Total_Cost_rule, sense=minimize) # -------------------------------------------------------- + def Entree_rule(model): - entrees = ['Quarter Pounder w Cheese', 'McLean Deluxe w Cheese', 'Big Mac', 'Filet-O-Fish', 'McGrilled Chicken'] + entrees = [ + 'Quarter Pounder w Cheese', + 'McLean Deluxe w Cheese', + 'Big Mac', + 'Filet-O-Fish', + 'McGrilled Chicken', + ] return sum(model.Buy[e] for e in entrees) >= 1 + + model.Entree = Constraint(rule=Entree_rule) + def Side_rule(model): sides = ['Fries, small', 'Sausage McMuffin'] return sum(model.Buy[s] for s in sides) >= 1 + + model.Side = Constraint(rule=Side_rule) + def Drink_rule(model): drinks = ['1% Lowfat Milk', 'Orange Juice'] return sum(model.Buy[d] for d in drinks) >= 1 + + model.Drink = Constraint(rule=Drink_rule) diff --git a/examples/pyomo/diet/diet2.py b/examples/pyomo/diet/diet2.py index e497bf3f292..526dbcef484 100644 --- a/examples/pyomo/diet/diet2.py +++ b/examples/pyomo/diet/diet2.py @@ -29,47 +29,63 @@ model.f_min = Param(model.FOOD, within=NonNegativeReals, default=0.0) -def f_max_validate (model, value, j): + +def f_max_validate(model, value, j): return model.f_max[j] > model.f_min[j] -model.f_max = Param(model.FOOD, validate=f_max_validate, - default=infinity) + + +model.f_max = Param(model.FOOD, validate=f_max_validate, default=infinity) model.n_min = Param(model.NUTR, within=NonNegativeReals, default=0.0) -def n_max_validate (model, value, j): + +def n_max_validate(model, value, j): return value > model.n_min[j] -model.n_max = Param(model.NUTR, validate=n_max_validate, - default=infinity) + + +model.n_max = Param(model.NUTR, validate=n_max_validate, default=infinity) model.amt = Param(model.NUTR, model.FOOD, within=NonNegativeReals) # -------------------------------------------------------- + def Buy_bounds(model, i): - return (model.f_min[i],model.f_max[i]) + return (model.f_min[i], model.f_max[i]) + + model.Buy = Var(model.FOOD, bounds=Buy_bounds, within=NonNegativeIntegers) # -------------------------------------------------------- + def Total_Cost_rule(model): ans = 0 for j in model.FOOD: ans = ans + model.cost[j] * model.Buy[j] return ans + + model.Total_Cost = Objective(rule=Total_Cost_rule, sense=minimize) + def Nutr_Amt_rule(model, i): ans = 0 for j in model.FOOD: - ans = ans + model.amt[i,j] * model.Buy[j] + ans = ans + model.amt[i, j] * model.Buy[j] return ans -#model.Nutr_Amt = Objective(model.NUTR, rule=Nutr_Amt_rule) + + +# model.Nutr_Amt = Objective(model.NUTR, rule=Nutr_Amt_rule) # -------------------------------------------------------- + def Diet_rule(model, i): expr = 0 for j in model.FOOD: - expr = expr + model.amt[i,j] * model.Buy[j] + expr = expr + model.amt[i, j] * model.Buy[j] return (model.n_min[i], expr, model.n_max[i]) + + model.Diet = Constraint(model.NUTR, rule=Diet_rule) diff --git a/examples/pyomo/draft/bpack.py b/examples/pyomo/draft/bpack.py index 763a5927088..12634b08eff 100644 --- a/examples/pyomo/draft/bpack.py +++ b/examples/pyomo/draft/bpack.py @@ -20,7 +20,7 @@ # # Set I # -model.I = RangeSet(1,model.N) +model.I = RangeSet(1, model.N) # # Variable b # @@ -31,10 +31,12 @@ def costrule(model): ans = 0 for i in model.I: -# ans += (-1 - .02*i)*model.b[i] - ans += (1 + .02*i)*model.b[i] + # ans += (-1 - .02*i)*model.b[i] + ans += (1 + 0.02 * i) * model.b[i] return ans -#model.zot = Objective(rule=costrule) + + +# model.zot = Objective(rule=costrule) model.zot = Objective(rule=costrule, sense=maximize) # # Set w_ind @@ -47,11 +49,13 @@ def w_ind_rule(model): j = i i9 = i + 9 while j <= i9: - ans.add((i,j)) + ans.add((i, j)) j += 1 i += 1 return ans -model.w_ind = Set(initialize=w_ind_rule,dimen=2) + + +model.w_ind = Set(initialize=w_ind_rule, dimen=2) # # Parameter w # @@ -59,7 +63,7 @@ def w_ind_rule(model): # # Set rhs_ind # -model.rhs_ind = RangeSet(1,model.N-9) +model.rhs_ind = RangeSet(1, model.N - 9) # # Parameter rhs # @@ -72,8 +76,10 @@ def bletch_rule(model, i): j = i i9 = i + 9 while j <= i9: - ans += model.w[i,j]*model.b[j] + ans += model.w[i, j] * model.b[j] j += 1 ans = ans < model.rhs[i] return ans + + model.bletch = Constraint(model.rhs_ind, rule=bletch_rule) diff --git a/examples/pyomo/draft/diet2.py b/examples/pyomo/draft/diet2.py index 2a6c8b112f9..9e4d2c5d9c4 100644 --- a/examples/pyomo/draft/diet2.py +++ b/examples/pyomo/draft/diet2.py @@ -29,25 +29,35 @@ model.f_min = Param(model.FOOD, within=NonNegativeReals) -def f_max_valid (model, value, j): + +def f_max_valid(model, value, j): return model.f_max[j] > model.f_min[j] + + model.f_max = Param(model.FOOD, validate=f_max_valid) model.n_min = Param(model.NUTR, within=NonNegativeReals) -def paramn_max (model, i): + +def paramn_max(model, i): model.n_max[i] > model.n_min[i] return model.n_max[i] + + model.n_max = Param(model.NUTR, initialize=paramn_max) # *********************************** model.amt = Param(model.NUTR, model.FOOD, within=NonNegativeReals) + def Buy_bounds(model, i): - return (model.f_min[i],model.f_max[i]) + return (model.f_min[i], model.f_max[i]) + + model.Buy = Var(model.FOOD, bounds=Buy_bounds) + def Objective_rule(model): ans = 0 for j in model.FOOD: @@ -55,15 +65,20 @@ def Objective_rule(model): for j in model.FOOD: ans = ans + model.cost[j] * model.Buy[j] return ans + + model.totalcost = Objective(rule=Objective_rule) + def Diet_rule(model, i): expr = 0 for j in model.FOOD: - expr = expr + model.amt[i,j] * model.Buy[j] + expr = expr + model.amt[i, j] * model.Buy[j] for j in model.FOOD: - expr = expr + model.amt[i,j] * model.Buy[j] - expr = expr > 2*model.n_min[i] - expr = expr < 2*model.n_max[i] + expr = expr + model.amt[i, j] * model.Buy[j] + expr = expr > 2 * model.n_min[i] + expr = expr < 2 * model.n_max[i] return expr + + model.Diet = Constraint(model.NUTR, rule=Diet_rule) diff --git a/examples/pyomo/p-median/decorated_pmedian.py b/examples/pyomo/p-median/decorated_pmedian.py index ec0c015760a..90345daf78d 100644 --- a/examples/pyomo/p-median/decorated_pmedian.py +++ b/examples/pyomo/p-median/decorated_pmedian.py @@ -1,39 +1,49 @@ from pyomo.environ import * import random + random.seed(1000) model = AbstractModel() model.N = Param(within=PositiveIntegers) -model.P = Param(within=RangeSet(1,model.N)) +model.P = Param(within=RangeSet(1, model.N)) model.M = Param(within=PositiveIntegers) -model.Locations = RangeSet(1,model.N) -model.Customers = RangeSet(1,model.M) +model.Locations = RangeSet(1, model.N) +model.Customers = RangeSet(1, model.M) -model.d = Param( model.Locations, model.Customers, - initialize=lambda n, m, model : random.uniform(1.0,2.0), - within=Reals) +model.d = Param( + model.Locations, + model.Customers, + initialize=lambda n, m, model: random.uniform(1.0, 2.0), + within=Reals, +) -model.x = Var(model.Locations, model.Customers, bounds=(0.0,1.0)) +model.x = Var(model.Locations, model.Customers, bounds=(0.0, 1.0)) model.y = Var(model.Locations, within=Binary) + @model.Objective() def obj(model): - return sum( model.d[n,m]*model.x[n,m] for n in model.Locations - for m in model.Customers ) + return sum( + model.d[n, m] * model.x[n, m] for n in model.Locations for m in model.Customers + ) + @model.Constraint(model.Customers) def single_x(model, m): - return (sum( model.x[n,m] for n in model.Locations ), 1.0) + return (sum(model.x[n, m] for n in model.Locations), 1.0) + @model.Constraint(model.Locations, model.Customers) -def bound_y(model, n,m): - return model.x[n,m] - model.y[n] <= 0.0 +def bound_y(model, n, m): + return model.x[n, m] - model.y[n] <= 0.0 + @model.Constraint() def num_facilities(model): - return sum( model.y[n] for n in model.Locations ) == model.P + return sum(model.y[n] for n in model.Locations) == model.P + -#model.pprint() +# model.pprint() diff --git a/examples/pyomo/p-median/pmedian.py b/examples/pyomo/p-median/pmedian.py index ebc4635360a..88731f287d8 100644 --- a/examples/pyomo/p-median/pmedian.py +++ b/examples/pyomo/p-median/pmedian.py @@ -12,6 +12,7 @@ from pyomo.core import * + def pyomo_create_model(options=None, model_options=None): import random @@ -21,34 +22,47 @@ def pyomo_create_model(options=None, model_options=None): model.N = Param(within=PositiveIntegers) - model.Locations = RangeSet(1,model.N) + model.Locations = RangeSet(1, model.N) - model.P = Param(within=RangeSet(1,model.N)) + model.P = Param(within=RangeSet(1, model.N)) model.M = Param(within=PositiveIntegers) - model.Customers = RangeSet(1,model.M) + model.Customers = RangeSet(1, model.M) - model.d = Param(model.Locations, model.Customers, initialize=lambda n, m, model : random.uniform(1.0,2.0), within=Reals) + model.d = Param( + model.Locations, + model.Customers, + initialize=lambda n, m, model: random.uniform(1.0, 2.0), + within=Reals, + ) - model.x = Var(model.Locations, model.Customers, bounds=(0.0,1.0)) + model.x = Var(model.Locations, model.Customers, bounds=(0.0, 1.0)) model.y = Var(model.Locations, within=Binary) def rule(model): - return sum( model.d[n,m]*model.x[n,m] for n in model.Locations for m in model.Customers ) + return sum( + model.d[n, m] * model.x[n, m] + for n in model.Locations + for m in model.Customers + ) + model.obj = Objective(rule=rule) def rule(model, m): - return (sum( model.x[n,m] for n in model.Locations ), 1.0) + return (sum(model.x[n, m] for n in model.Locations), 1.0) + model.single_x = Constraint(model.Customers, rule=rule) - def rule(model, n,m): - return (None, model.x[n,m] - model.y[n], 0.0) + def rule(model, n, m): + return (None, model.x[n, m] - model.y[n], 0.0) + model.bound_y = Constraint(model.Locations, model.Customers, rule=rule) def rule(model): - return (sum( model.y[n] for n in model.Locations ) - model.P, 0.0) + return (sum(model.y[n] for n in model.Locations) - model.P, 0.0) + model.num_facilities = Constraint(rule=rule) return model diff --git a/examples/pyomo/p-median/solver1.py b/examples/pyomo/p-median/solver1.py index d4fbda0c81e..2bb67754d3a 100644 --- a/examples/pyomo/p-median/solver1.py +++ b/examples/pyomo/p-median/solver1.py @@ -42,7 +42,7 @@ def solve(self, instance, **kwds): soln.status = SolutionStatus.feasible for j in sequence(n): if instance.y[j].value is 1: - soln.variable[instance.y[j].name] = {"Value" : 1, "Id" : j} + soln.variable[instance.y[j].name] = {"Value": 1, "Id": j} return results # Perform a greedy search @@ -50,33 +50,33 @@ def _greedy(self, instance): p = value(instance.P) n = value(instance.N) m = value(instance.M) - fixed=set() + fixed = set() # Initialize for j in sequence(n): - instance.y[j].value=0 + instance.y[j].value = 0 # Greedily fix the next best facility for i in sequence(p): best = None - ndx=j + ndx = j for j in sequence(n): if j in fixed: continue - instance.y[j].value=1 + instance.y[j].value = 1 # Compute value val = 0.0 for kk in sequence(m): - tmp=copy.copy(fixed) + tmp = copy.copy(fixed) tmp.add(j) tbest = None for jj in tmp: - if tbest is None or instance.d[jj,kk].value < tbest: - tbest = instance.d[jj,kk].value + if tbest is None or instance.d[jj, kk].value < tbest: + tbest = instance.d[jj, kk].value val += tbest # Keep best greedy choice if best is None or val < best: - best=val - ndx=j - instance.y[j].value=0 + best = val + ndx = j + instance.y[j].value = 0 fixed.add(ndx) - instance.y[ndx].value=1 + instance.y[ndx].value = 1 return [best, instance] diff --git a/examples/pyomo/p-median/solver2.py b/examples/pyomo/p-median/solver2.py index c7215183481..8c6207c151d 100644 --- a/examples/pyomo/p-median/solver2.py +++ b/examples/pyomo/p-median/solver2.py @@ -16,6 +16,7 @@ import random import copy + @plugin_factory class MySolver(object): @@ -42,13 +43,13 @@ def solve(self, instance, **kwds): soln.value = val soln.status = SolutionStatus.feasible for j in sequence(n): - soln.variable[instance.y[j].name] = {"Value" : sol[j-1], "Id" : j} + soln.variable[instance.y[j].name] = {"Value": sol[j - 1], "Id": j} # Return results return results # Perform a random search def _random(self, instance): - sol = [0]*instance.N.value + sol = [0] * instance.N.value for j in range(instance.P.value): sol[j] = 1 # Generate 100 random solutions, and keep the best @@ -57,12 +58,16 @@ def _random(self, instance): for kk in range(100): random.shuffle(sol) # Compute value - val=0.0 + val = 0.0 for j in sequence(instance.M.value): - val += min([instance.d[i,j].value - for i in sequence(instance.N.value) - if sol[i-1] == 1]) + val += min( + [ + instance.d[i, j].value + for i in sequence(instance.N.value) + if sol[i - 1] == 1 + ] + ) if best is None or val < best: - best=val - best_sol=copy.copy(sol) + best = val + best_sol = copy.copy(sol) return [best, best_sol] diff --git a/examples/pyomo/piecewise/convex.py b/examples/pyomo/piecewise/convex.py index 3acec3fc75d..8bbd25d9325 100644 --- a/examples/pyomo/piecewise/convex.py +++ b/examples/pyomo/piecewise/convex.py @@ -11,7 +11,7 @@ # A simple example illustrating a piecewise # representation of the function Z(X) -# +# # / -X+2 , -5 <= X <= 1 # Z(X) >= | # \ X , 1 <= X <= 5 @@ -22,23 +22,27 @@ # Define the function # Just like in Pyomo constraint rules, a Pyomo model object # must be the first argument for the function rule -def f(model,x): - return abs(x-1)+1.0 +def f(model, x): + return abs(x - 1) + 1.0 + model = ConcreteModel() -model.X = Var(bounds=(-5,5)) +model.X = Var(bounds=(-5, 5)) model.Z = Var() # See documentation on Piecewise component by typing # help(Piecewise) in a python terminal after importing pyomo.core -model.con = Piecewise(model.Z,model.X, # range and domain variables - pw_pts=[-5,1,5] , - pw_constr_type='LB', - f_rule=f) +model.con = Piecewise( + model.Z, + model.X, # range and domain variables + pw_pts=[-5, 1, 5], + pw_constr_type='LB', + f_rule=f, +) # The default piecewise representation implemented by Piecewise is SOS2. -# Note, however, that no SOS2 variables will be generated since the +# Note, however, that no SOS2 variables will be generated since the # check for convexity within Piecewise automatically simplifies the constraints # when a lower bounding convex function is supplied. Adding 'force_pw=True' # to the Piecewise argument list will cause the original piecewise constraints diff --git a/examples/pyomo/piecewise/indexed.py b/examples/pyomo/piecewise/indexed.py index f0245550150..4e15fb8c74a 100644 --- a/examples/pyomo/piecewise/indexed.py +++ b/examples/pyomo/piecewise/indexed.py @@ -16,17 +16,17 @@ # Define the function # Just like in Pyomo constraint rules, a Pyomo model object # must be the first argument for the function rule -def f(model,t1,t2,x): - return 0.1*x - cos(5.0*x) +def f(model, t1, t2, x): + return 0.1 * x - cos(5.0 * x) model = ConcreteModel() -# Note we can use an arbitrary number of index sets of +# Note we can use an arbitrary number of index sets of # arbitrary dimension as the first arguments to the # Piecewise component. -model.INDEX1 = Set(dimen=2, initialize=[(0,1),(8,3)]) -model.X = Var(model.INDEX1, bounds=(-2,2)) +model.INDEX1 = Set(dimen=2, initialize=[(0, 1), (8, 3)]) +model.X = Var(model.INDEX1, bounds=(-2, 2)) model.Z = Var(model.INDEX1) # For indexed variables, pw_pts must be a @@ -40,19 +40,22 @@ def f(model,t1,t2,x): # binary variables ('LOG', 'DLOG') requires that pw_pts lists # must have 2^n + 1 breakpoints. num_points = 1 + 2**n -step = (2.0 - (-2.0))/(num_points-1) +step = (2.0 - (-2.0)) / (num_points - 1) for idx in model.X.index_set(): - PW_PTS[idx] = [-2.0 + i*step for i in range(num_points)] # [-2.0, ..., 2.0] - -model.linearized_constraint = Piecewise(model.INDEX1, # indexing sets - model.Z,model.X, # range and domain variables - pw_pts=PW_PTS, - pw_constr_type='EQ', - pw_repn='LOG', - f_rule=f, - force_pw=True) + PW_PTS[idx] = [-2.0 + i * step for i in range(num_points)] # [-2.0, ..., 2.0] + +model.linearized_constraint = Piecewise( + model.INDEX1, # indexing sets + model.Z, + model.X, # range and domain variables + pw_pts=PW_PTS, + pw_constr_type='EQ', + pw_repn='LOG', + f_rule=f, + force_pw=True, +) # maximize the sum of Z over its index # This is just a simple example of how to implement indexed variables. All indices # of Z will have the same solution. -model.obj = Objective(expr= sum_product(model.Z) , sense=maximize) +model.obj = Objective(expr=sum_product(model.Z), sense=maximize) diff --git a/examples/pyomo/piecewise/indexed_nonlinear.py b/examples/pyomo/piecewise/indexed_nonlinear.py index d6980a550cc..12e525015ae 100644 --- a/examples/pyomo/piecewise/indexed_nonlinear.py +++ b/examples/pyomo/piecewise/indexed_nonlinear.py @@ -13,13 +13,15 @@ # Must have a nonlinear solver # to run this example. from pyomo.core import * -from indexed import model,f +from indexed import model, f -# Reuse the rule from example4 to define the +# Reuse the rule from example4 to define the # nonlinear constraint -def nonlinear_con_rule(model,i,j): - return model.Z[i,j] == f(model,i,j,model.X[i,j]) -model.nonlinear_constraint = Constraint(model.INDEX1,rule=nonlinear_con_rule) +def nonlinear_con_rule(model, i, j): + return model.Z[i, j] == f(model, i, j, model.X[i, j]) + + +model.nonlinear_constraint = Constraint(model.INDEX1, rule=nonlinear_con_rule) # deactivate all constraints on the Piecewise component model.linearized_constraint.deactivate() @@ -28,4 +30,3 @@ def nonlinear_con_rule(model,i,j): for idx in model.X.index_set(): model.X[idx] = 1.7 model.Z[idx] = 1.25 - diff --git a/examples/pyomo/piecewise/indexed_points.py b/examples/pyomo/piecewise/indexed_points.py index f68bef63f00..15b1c33a7ec 100644 --- a/examples/pyomo/piecewise/indexed_points.py +++ b/examples/pyomo/piecewise/indexed_points.py @@ -21,15 +21,13 @@ y = [1.1, -1.1, 2.0, 1.1] model = ConcreteModel() -model.index = Set(initialize=[1,2,3]) +model.index = Set(initialize=[1, 2, 3]) model.x = Var(model.index, bounds=(min(x), max(x))) model.y = Var(model.index) -model.fx = Piecewise(model.index, - model.y, model.x, - pw_pts=x, - pw_constr_type='EQ', - f_rule=y) +model.fx = Piecewise( + model.index, model.y, model.x, pw_pts=x, pw_constr_type='EQ', f_rule=y +) model.c = ConstraintList() model.c.add(model.x[1] >= 1.0) diff --git a/examples/pyomo/piecewise/nonconvex.py b/examples/pyomo/piecewise/nonconvex.py index 0319b105331..406e2b9d732 100644 --- a/examples/pyomo/piecewise/nonconvex.py +++ b/examples/pyomo/piecewise/nonconvex.py @@ -20,26 +20,32 @@ # Define the function # Just like in Pyomo constraint rules, a Pyomo model object # must be the first argument for the function rule -RANGE_POINTS = {-1.0:-1.0, 2.0:0.0, 6.0:-8.0, 10.0:12.0} -def f(model,x): +RANGE_POINTS = {-1.0: -1.0, 2.0: 0.0, 6.0: -8.0, 10.0: 12.0} + + +def f(model, x): return RANGE_POINTS[x] + model = ConcreteModel() -model.X = Var(bounds=(-1.0,10.0)) +model.X = Var(bounds=(-1.0, 10.0)) model.Z = Var() -model.p = Var(within = NonNegativeReals) -model.n = Var(within = NonNegativeReals) +model.p = Var(within=NonNegativeReals) +model.n = Var(within=NonNegativeReals) # See documentation on Piecewise component by typing # help(Piecewise) in a python terminal after importing pyomo.core # Using BigM constraints with binary variables to represent the piecwise constraints -model.con = Piecewise(model.Z,model.X, # range and domain variables - pw_pts=[-1.0,2.0,6.0,10.0], - pw_constr_type='EQ', - pw_repn='DCC', - f_rule=f) +model.con = Piecewise( + model.Z, + model.X, # range and domain variables + pw_pts=[-1.0, 2.0, 6.0, 10.0], + pw_constr_type='EQ', + pw_repn='DCC', + f_rule=f, +) # minimize the 1-norm distance of Z to 7.0, i.e., |Z-7| -model.pn_con = Constraint(expr= model.Z - 7.0 == model.p - model.n) -model.obj = Objective(rule = lambda model: model.p+model.n , sense=minimize) +model.pn_con = Constraint(expr=model.Z - 7.0 == model.p - model.n) +model.obj = Objective(rule=lambda model: model.p + model.n, sense=minimize) diff --git a/examples/pyomo/piecewise/points.py b/examples/pyomo/piecewise/points.py index cf48c866808..c822ceb5860 100644 --- a/examples/pyomo/piecewise/points.py +++ b/examples/pyomo/piecewise/points.py @@ -21,9 +21,6 @@ model.x = Var(bounds=(min(x), max(x))) model.y = Var() -model.fx = Piecewise(model.y, model.x, - pw_pts=x, - pw_constr_type='EQ', - f_rule=y) +model.fx = Piecewise(model.y, model.x, pw_pts=x, pw_constr_type='EQ', f_rule=y) model.o = Objective(expr=model.y) diff --git a/examples/pyomo/piecewise/step.py b/examples/pyomo/piecewise/step.py index e87e6f1cb6a..e49dbed818b 100644 --- a/examples/pyomo/piecewise/step.py +++ b/examples/pyomo/piecewise/step.py @@ -11,7 +11,7 @@ # A simple example illustrating a piecewise # representation of the step function Z(X) -# +# # / 0 , 0 <= x <= 1 # Z(X) >= | 2 , 1 <= x <= 2 # \ 0.5 , 2 <= x <= 3 @@ -21,25 +21,28 @@ # range variable can solve to any value # on the vertical line. There is no # discontinuous "jump". -DOMAIN_PTS = [0., 1., 1., 2., 2., 3.] -RANGE_PTS = [0., 0., 2., 2., 0.5, 0.5] +DOMAIN_PTS = [0.0, 1.0, 1.0, 2.0, 2.0, 3.0] +RANGE_PTS = [0.0, 0.0, 2.0, 2.0, 0.5, 0.5] from pyomo.core import * model = ConcreteModel() -model.X = Var(bounds=(0,3)) +model.X = Var(bounds=(0, 3)) model.Z = Var() # See documentation on Piecewise component by typing # help(Piecewise) in a python terminal after importing pyomo.core -model.con = Piecewise(model.Z,model.X, # range and domain variables - pw_pts=DOMAIN_PTS , - pw_constr_type='EQ', - f_rule=RANGE_PTS, - pw_repn='INC') # **NOTE**: The not all piecewise represenations - # handle step functions. Those which do - # not work with step functions are: - # BIGM_SOS1, BIGM_BIN, and MC +model.con = Piecewise( + model.Z, + model.X, # range and domain variables + pw_pts=DOMAIN_PTS, + pw_constr_type='EQ', + f_rule=RANGE_PTS, + pw_repn='INC', +) # **NOTE**: The not all piecewise represenations +# handle step functions. Those which do +# not work with step functions are: +# BIGM_SOS1, BIGM_BIN, and MC -model.obj = Objective(expr=model.Z+model.X, sense=maximize) +model.obj = Objective(expr=model.Z + model.X, sense=maximize) diff --git a/examples/pyomo/quadratic/example1.py b/examples/pyomo/quadratic/example1.py index 79565c70044..dff911a0f0c 100644 --- a/examples/pyomo/quadratic/example1.py +++ b/examples/pyomo/quadratic/example1.py @@ -18,8 +18,11 @@ model = AbstractModel() -model.x = Var(bounds=(-10,10), within=Reals) +model.x = Var(bounds=(-10, 10), within=Reals) + def objective_rule(model): return model.x * model.x + + model.objective = Objective(rule=objective_rule, sense=minimize) diff --git a/examples/pyomo/quadratic/example2.py b/examples/pyomo/quadratic/example2.py index 06347321bf5..981f2ef0bfb 100644 --- a/examples/pyomo/quadratic/example2.py +++ b/examples/pyomo/quadratic/example2.py @@ -16,16 +16,25 @@ model = AbstractModel() + def indices_rule(model): - return range(1,4) + return range(1, 4) + + model.indices = Set(initialize=indices_rule, within=PositiveIntegers) model.x = Var(model.indices, within=Reals) + def bound_x_rule(model, i): return (-10, model.x[i], 10) + + model.bound_x = Constraint(model.indices, rule=bound_x_rule) + def objective_rule(model): return sum([model.x[i] * model.x[i] for i in model.indices]) + + model.objective = Objective(rule=objective_rule, sense=minimize) diff --git a/examples/pyomo/quadratic/example3.py b/examples/pyomo/quadratic/example3.py index 1c96fd62ad6..4d96afe3328 100644 --- a/examples/pyomo/quadratic/example3.py +++ b/examples/pyomo/quadratic/example3.py @@ -17,16 +17,25 @@ model = AbstractModel() + def indices_rule(model): - return xrange(1,4) + return xrange(1, 4) + + model.indices = Set(initialize=indices_rule, within=PositiveIntegers) model.x = Var(model.indices, within=Reals) + def bound_x_rule(model, i): return (-10, model.x[i], 10) + + model.bound_x = Constraint(model.indices, rule=bound_x_rule) + def objective_rule(model): return 5 + sum([(model.x[i] - 3) * (model.x[i] - 3) for i in model.indices]) + + model.objective = Objective(rule=objective_rule, sense=minimize) diff --git a/examples/pyomo/quadratic/example4.py b/examples/pyomo/quadratic/example4.py index 51cab0fa0ae..256fc862a16 100644 --- a/examples/pyomo/quadratic/example4.py +++ b/examples/pyomo/quadratic/example4.py @@ -19,10 +19,20 @@ model.x = Var(within=NonNegativeReals) model.y = Var(within=NonNegativeReals) + def constraint_rule(model): return model.x + model.y >= 10 + + model.constraint = Constraint(rule=constraint_rule) + def objective_rule(model): - return model.x + model.y + 0.5 * (model.x * model.x + 4 * model.x * model.y + 7 * model.y * model.y) + return ( + model.x + + model.y + + 0.5 * (model.x * model.x + 4 * model.x * model.y + 7 * model.y * model.y) + ) + + model.objective = Objective(rule=objective_rule, sense=minimize) diff --git a/examples/pyomo/radertext/Ex2_1.py b/examples/pyomo/radertext/Ex2_1.py index f814e819b7c..c02d2dff1b6 100644 --- a/examples/pyomo/radertext/Ex2_1.py +++ b/examples/pyomo/radertext/Ex2_1.py @@ -36,22 +36,33 @@ # Objective def CalcProfit(M): - return sum (M.NumDoors[d]*M.Profit[d] for d in M.DoorType) + return sum(M.NumDoors[d] * M.Profit[d] for d in M.DoorType) + + model.TotProf = Objective(rule=CalcProfit, sense=maximize) # Constraints def EnsureMachineLimit(M, m): - return sum (M.NumDoors[d]*M.Labor[d,m] for d in M.DoorType) \ - <= M.MachineLimit[m] + return sum(M.NumDoors[d] * M.Labor[d, m] for d in M.DoorType) <= M.MachineLimit[m] + + model.MachineUpBound = Constraint(model.MachineType, rule=EnsureMachineLimit) + def EnsureLaborLimit(M): - return sum (M.NumDoors[d]*M.Labor[d,m] \ - for d in M.DoorType for m in M.MachineType) \ - <= M.LaborLimit + return ( + sum(M.NumDoors[d] * M.Labor[d, m] for d in M.DoorType for m in M.MachineType) + <= M.LaborLimit + ) + + model.MachineUpBound = Constraint(rule=EnsureLaborLimit) + def EnsureMarketRatio(M): - return sum (M.NumDoors[d] for d in M.MarketDoorType1) \ - <= sum (M.NumDoors[d] for d in M.MarketDoorType2) + return sum(M.NumDoors[d] for d in M.MarketDoorType1) <= sum( + M.NumDoors[d] for d in M.MarketDoorType2 + ) + + model.MarketRatio = Constraint(rule=EnsureMarketRatio) diff --git a/examples/pyomo/radertext/Ex2_2.py b/examples/pyomo/radertext/Ex2_2.py index 692fd073c50..b0fd88946e2 100644 --- a/examples/pyomo/radertext/Ex2_2.py +++ b/examples/pyomo/radertext/Ex2_2.py @@ -22,7 +22,7 @@ model.NumTimePeriods = Param(within=NonNegativeIntegers) # Sets -model.StartTime = RangeSet(1,model.NumTimePeriods) +model.StartTime = RangeSet(1, model.NumTimePeriods) # Parameters model.RequiredWorkers = Param(model.StartTime, within=NonNegativeIntegers) @@ -32,14 +32,20 @@ # Objective def CalcTotalWorkers(M): - return sum (M.NumWorkers[i] for i in M.StartTime) + return sum(M.NumWorkers[i] for i in M.StartTime) + + model.TotalWorkers = Objective(rule=CalcTotalWorkers, sense=minimize) # Constraints def EnsureWorkforce(M, i): if i != M.NumTimePeriods.value: - return M.NumWorkers[i] + M.NumWorkers[i+1] >= M.RequiredWorkers[i+1] + return M.NumWorkers[i] + M.NumWorkers[i + 1] >= M.RequiredWorkers[i + 1] else: - return M.NumWorkers[1] + M.NumWorkers[M.NumTimePeriods.value] \ - >= M.RequiredWorkers[1] + return ( + M.NumWorkers[1] + M.NumWorkers[M.NumTimePeriods.value] + >= M.RequiredWorkers[1] + ) + + model.WorkforceDemand = Constraint(model.StartTime, rule=EnsureWorkforce) diff --git a/examples/pyomo/radertext/Ex2_3.py b/examples/pyomo/radertext/Ex2_3.py index 99ac2a13598..7018cf80acf 100644 --- a/examples/pyomo/radertext/Ex2_3.py +++ b/examples/pyomo/radertext/Ex2_3.py @@ -24,20 +24,22 @@ model.NumGasTypes = Param(within=PositiveIntegers) # Sets -model.CrudeType = RangeSet(1,model.NumCrudeTypes) -model.GasType = RangeSet(1,model.NumGasTypes) +model.CrudeType = RangeSet(1, model.NumCrudeTypes) +model.GasType = RangeSet(1, model.NumGasTypes) # Parameters -model.Cost = Param(model.CrudeType, within= NonNegativeReals) +model.Cost = Param(model.CrudeType, within=NonNegativeReals) model.CrudeOctane = Param(model.CrudeType, within=NonNegativeReals) model.CrudeMax = Param(model.CrudeType, within=NonNegativeReals) model.MinGasOctane = Param(model.GasType, within=NonNegativeReals) model.GasPrice = Param(model.GasType, within=NonNegativeReals) model.GasDemand = Param(model.GasType, within=NonNegativeReals) -model.MixtureUpBounds = Param(model.CrudeType, model.GasType, \ - within=NonNegativeReals, default=10**8) -model.MixtureLowBounds = Param(model.CrudeType, model.GasType, \ - within=NonNegativeReals, default=0) +model.MixtureUpBounds = Param( + model.CrudeType, model.GasType, within=NonNegativeReals, default=10**8 +) +model.MixtureLowBounds = Param( + model.CrudeType, model.GasType, within=NonNegativeReals, default=0 +) # Variabls model.x = Var(model.CrudeType, model.GasType, within=NonNegativeReals) @@ -46,41 +48,63 @@ # Objective def CalcProfit(M): - return sum(M.GasPrice[j]*M.z[j] for j in M.GasType) \ - - sum(M.Cost[i]*M.q[i] for i in M.CrudeType) + return sum(M.GasPrice[j] * M.z[j] for j in M.GasType) - sum( + M.Cost[i] * M.q[i] for i in M.CrudeType + ) + + model.Profit = Objective(rule=CalcProfit, sense=maximize) # Constraints -def BalanceCrude(M,i): - return sum (M.x[i,j] for j in M.GasType) == M.q[i] + +def BalanceCrude(M, i): + return sum(M.x[i, j] for j in M.GasType) == M.q[i] + + model.BalanceCrudeProduction = Constraint(model.CrudeType, rule=BalanceCrude) -def BalanceGas(M,j): - return sum (M.x[i,j] for i in M.CrudeType) == M.z[j] + +def BalanceGas(M, j): + return sum(M.x[i, j] for i in M.CrudeType) == M.z[j] + + model.BalanceGasProduction = Constraint(model.GasType, rule=BalanceGas) -def EnsureCrudeLimit(M,i): + +def EnsureCrudeLimit(M, i): return M.q[i] <= M.CrudeMax[i] + + model.LimitCrude = Constraint(model.CrudeType, rule=EnsureCrudeLimit) -def EnsureGasDemand(M,j): + +def EnsureGasDemand(M, j): return M.z[j] >= M.GasDemand[j] + + model.DemandGas = Constraint(model.GasType, rule=EnsureGasDemand) -def EnsureOctane(M,j): - return sum (M.x[i,j]*M.CrudeOctane[i] for i in M.CrudeType) \ - >= M.MinGasOctane[j]*M.z[j] + +def EnsureOctane(M, j): + return ( + sum(M.x[i, j] * M.CrudeOctane[i] for i in M.CrudeType) + >= M.MinGasOctane[j] * M.z[j] + ) + + model.OctaneLimit = Constraint(model.GasType, rule=EnsureOctane) -def EnsureLowMixture(M,i,j): - return sum (M.x[k,j] for k in M.CrudeType)*M.MixtureLowBounds[i,j] \ - <= M.x[i,j] -model.LowCrudeBound = Constraint(model.CrudeType, model.GasType, \ - rule=EnsureLowMixture) - -def EnsureUpMixture(M,i,j): - return sum (M.x[k,j] for k in M.CrudeType)*M.MixtureUpBounds[i,j] \ - >= M.x[i,j] -model.UpCrudeBound = Constraint(model.CrudeType, model.GasType, \ - rule=EnsureUpMixture) + +def EnsureLowMixture(M, i, j): + return sum(M.x[k, j] for k in M.CrudeType) * M.MixtureLowBounds[i, j] <= M.x[i, j] + + +model.LowCrudeBound = Constraint(model.CrudeType, model.GasType, rule=EnsureLowMixture) + + +def EnsureUpMixture(M, i, j): + return sum(M.x[k, j] for k in M.CrudeType) * M.MixtureUpBounds[i, j] >= M.x[i, j] + + +model.UpCrudeBound = Constraint(model.CrudeType, model.GasType, rule=EnsureUpMixture) diff --git a/examples/pyomo/radertext/Ex2_5.py b/examples/pyomo/radertext/Ex2_5.py index 8bd76b71ba3..b3204c2acf7 100644 --- a/examples/pyomo/radertext/Ex2_5.py +++ b/examples/pyomo/radertext/Ex2_5.py @@ -21,8 +21,8 @@ # Sets model.NumMonths = Param(within=NonNegativeIntegers) -model.EngineType= Set() -model.Month = RangeSet(1,model.NumMonths) +model.EngineType = Set() +model.Month = RangeSet(1, model.NumMonths) # Parameters model.Demand = Param(model.EngineType, model.Month, within=NonNegativeIntegers) @@ -40,31 +40,44 @@ # Objective def CalcCost(M): - return sum(M.Produce[e,t]*M.ProdCost[e] \ - for e in M.EngineType for t in M.Month) + \ - sum(M.Inventory[e,t]*M.InvCost \ - for e in M.EngineType for t in M.Month) + return sum( + M.Produce[e, t] * M.ProdCost[e] for e in M.EngineType for t in M.Month + ) + sum(M.Inventory[e, t] * M.InvCost for e in M.EngineType for t in M.Month) + + model.TotalCost = Objective(rule=CalcCost, sense=minimize) # Constraints -def EnsureBalance(M,e,t): +def EnsureBalance(M, e, t): if t != 1: - return M.Inventory[e,t] == M.Inventory[e, t-1] + M.Produce[e,t] \ - - M.Demand[e,t] + return ( + M.Inventory[e, t] + == M.Inventory[e, t - 1] + M.Produce[e, t] - M.Demand[e, t] + ) else: - return M.Inventory[e,t] == M.InitInv[e] + M.Produce[e,t] \ - - M.Demand[e,t] + return M.Inventory[e, t] == M.InitInv[e] + M.Produce[e, t] - M.Demand[e, t] + + model.InventoryBalance = Constraint(model.EngineType, model.Month, rule=EnsureBalance) -def EnsureLaborLimit(M,t): - return sum(M.Produce[e,t]*M.Labor[e] for e in M.EngineType) <= M.LaborBound + +def EnsureLaborLimit(M, t): + return sum(M.Produce[e, t] * M.Labor[e] for e in M.EngineType) <= M.LaborBound + + model.LimitLabor = Constraint(model.Month, rule=EnsureLaborLimit) -def EnsureProdLimit(M,t): - return sum(M.Produce[e,t] for e in M.EngineType) <= M.ProdBound + +def EnsureProdLimit(M, t): + return sum(M.Produce[e, t] for e in M.EngineType) <= M.ProdBound + + model.ProdLimit = Constraint(model.Month, rule=EnsureProdLimit) -def LeaveEnough(M,e,t): + +def LeaveEnough(M, e, t): if t == len(M.Month): - return M.Inventory[e,t] >= M.FinInv[e] + return M.Inventory[e, t] >= M.FinInv[e] + + model.FinalInventory = Constraint(model.EngineType, model.Month, rule=LeaveEnough) diff --git a/examples/pyomo/radertext/Ex2_6a.py b/examples/pyomo/radertext/Ex2_6a.py index 27609152f82..9d49b3bec22 100644 --- a/examples/pyomo/radertext/Ex2_6a.py +++ b/examples/pyomo/radertext/Ex2_6a.py @@ -21,7 +21,7 @@ # Sets and Set Parameters model.NumSensors = Param(within=NonNegativeIntegers) -model.Sensor = RangeSet(1,model.NumSensors) +model.Sensor = RangeSet(1, model.NumSensors) # Parameters model.xPos = Param(model.Sensor, within=NonNegativeIntegers) @@ -36,23 +36,36 @@ # Objective def CalcDist(M): return sum(M.xMax[s] + M.yMax[s] for s in M.Sensor) + + model.Dist = Objective(rule=CalcDist, sense=minimize) # Constraints -def xEnsureUp(s,M): + +def xEnsureUp(s, M): return M.xCentralSensor - M.xPos[s] <= M.xMax[s] + + model.xUpBound = Constraint(model.Sensor, rule=xEnsureUp) -def xEnsureLow(s,M): + +def xEnsureLow(s, M): return M.xCentralSensor - M.xPos[s] >= -M.xMax[s] + + model.xLowBound = Constraint(model.Sensor, rule=xEnsureLow) -def yEnsureUp(s,M): + +def yEnsureUp(s, M): return M.yCentralSensor - M.yPos[s] <= M.yMax[s] + + model.yUpBound = Constraint(model.Sensor, rule=yEnsureUp) -def yEnsureLow(s,M): + +def yEnsureLow(s, M): return M.yCentralSensor - M.yPos[s] >= -M.yMax[s] -model.yLowBound = Constraint(model.Sensor, rule=yEnsureLow) + +model.yLowBound = Constraint(model.Sensor, rule=yEnsureLow) diff --git a/examples/pyomo/radertext/Ex2_6b.py b/examples/pyomo/radertext/Ex2_6b.py index 282ffd7afe7..2f7964c8cb1 100644 --- a/examples/pyomo/radertext/Ex2_6b.py +++ b/examples/pyomo/radertext/Ex2_6b.py @@ -21,7 +21,7 @@ # Sets and Set Parameters model.NumSensors = Param(within=NonNegativeIntegers) -model.Sensor = RangeSet(1,model.NumSensors) +model.Sensor = RangeSet(1, model.NumSensors) # Parameters model.xPos = Param(model.Sensor, within=NonNegativeIntegers) @@ -37,26 +37,43 @@ # Objective def CalcDist(M): return M.Max + + model.Dist = Objective(rule=CalcDist, sense=minimize) # Constraints -def xEnsureUp(M,s): + +def xEnsureUp(M, s): return M.xCentralSensor - M.xPos[s] <= M.xMax[s] + + model.xUpBound = Constraint(model.Sensor, rule=xEnsureUp) -def xEnsureLow(M,s): + +def xEnsureLow(M, s): return M.xCentralSensor - M.xPos[s] >= -M.xMax[s] + + model.xLowBound = Constraint(model.Sensor, rule=xEnsureLow) -def yEnsureUp(M,s): + +def yEnsureUp(M, s): return M.yCentralSensor - M.yPos[s] <= M.yMax[s] + + model.yUpBound = Constraint(model.Sensor, rule=yEnsureUp) -def yEnsureLow(M,s): + +def yEnsureLow(M, s): return M.yCentralSensor - M.yPos[s] >= -M.yMax[s] + + model.yLowBound = Constraint(model.Sensor, rule=yEnsureLow) -def EnsureSensorBound(M,s): + +def EnsureSensorBound(M, s): return M.xMax[s] + M.yMax[s] <= M.Max + + model.MaxDist = Constraint(model.Sensor, rule=EnsureSensorBound) diff --git a/examples/pyomo/sos/DepotSiting.py b/examples/pyomo/sos/DepotSiting.py index 8f2420aa3e9..94edd6699da 100644 --- a/examples/pyomo/sos/DepotSiting.py +++ b/examples/pyomo/sos/DepotSiting.py @@ -26,7 +26,7 @@ # indicators of which sites are selected. constraints ensure only one site is selected, # and allow the binary integrality to be implicit. -model.SiteSelected = Var(model.Sites, bounds=(0,1)) +model.SiteSelected = Var(model.Sites, bounds=(0, 1)) # ensure that only one of the site selected variables is non-zero. model.SiteSelectedSOS = SOSConstraint(var=model.SiteSelected, sos=1) @@ -34,9 +34,19 @@ # ensure that one of the sites is selected (enforce binary). def enforce_site_selected_binary_rule(model): return sum_product(model.SiteSelected) == 1 + + model.EnforceSiteSelectedBinary = Constraint(rule=enforce_site_selected_binary_rule) # the objective is to minimize the cost to satisfy all customers. def minimize_cost_rule(model): - return sum([model.SatisfactionCost[c, s] * model.SiteSelected[s] for c in model.Customers for s in model.Sites]) + return sum( + [ + model.SatisfactionCost[c, s] * model.SiteSelected[s] + for c in model.Customers + for s in model.Sites + ] + ) + + model.MinimizeCost = Objective(rule=minimize_cost_rule, sense=minimize) diff --git a/examples/pyomo/sos/basic_sos2_example.py b/examples/pyomo/sos/basic_sos2_example.py index 5a079b8f45f..655169ffe54 100644 --- a/examples/pyomo/sos/basic_sos2_example.py +++ b/examples/pyomo/sos/basic_sos2_example.py @@ -23,38 +23,30 @@ # a .dat file. Thus, define all the "cruft" up here, so it's clearer how the # model is tied together down below. -def c_param_init ( model, v ): - return (-1, -1, -3, -2, -2)[ v -1 ] # -1 because Python is 0-based +def c_param_init(model, v): + return (-1, -1, -3, -2, -2)[v - 1] # -1 because Python is 0-based -def b_param_init ( model, c): - return (30, 30)[ c -1 ] # -1 because Python is 0-based +def b_param_init(model, c): + return (30, 30)[c - 1] # -1 because Python is 0-based -def A_param_init ( model, c, v): - data = ( - (-1, -1, 1, 1, 0), - ( 1, 0, 1, -3, 0), - ) - return data[ c -1 ][ v -1 ] # -1 because Python is 0-based +def A_param_init(model, c, v): + data = ((-1, -1, 1, 1, 0), (1, 0, 1, -3, 0)) + return data[c - 1][v - 1] # -1 because Python is 0-based -def obj_rule ( model ): - objective_expression = sum( - model.c[ i ] * model.x[ i ] - for i in model.variable_set - ) + +def obj_rule(model): + objective_expression = sum(model.c[i] * model.x[i] for i in model.variable_set) return objective_expression -def constraint_rule ( model, c): - constraint_equation = ( - model.b[ c ] >= sum( - model.A[c, i] * model.x[ i ] - for i in model.variable_set - ) +def constraint_rule(model, c): + constraint_equation = model.b[c] >= sum( + model.A[c, i] * model.x[i] for i in model.variable_set ) return constraint_equation @@ -71,25 +63,25 @@ def constraint_rule ( model, c): model = AbstractModel() M = model -M.variable_set = RangeSet(1, 5) +M.variable_set = RangeSet(1, 5) M.constraint_set = RangeSet(1, 2) -M.c = Param( M.variable_set, initialize=c_param_init ) +M.c = Param(M.variable_set, initialize=c_param_init) -M.A = Param( M.constraint_set, M.variable_set, initialize=A_param_init ) -M.b = Param( M.constraint_set, initialize=b_param_init ) +M.A = Param(M.constraint_set, M.variable_set, initialize=A_param_init) +M.b = Param(M.constraint_set, initialize=b_param_init) -M.x = Var( M.variable_set, within=PositiveReals ) +M.x = Var(M.variable_set, within=PositiveReals) -M.obj = Objective( rule=obj_rule, sense=minimize ) # min "c transpose" X +M.obj = Objective(rule=obj_rule, sense=minimize) # min "c transpose" X # At first, this is little more than a standard form Ax=b ... -M.constraints = Constraint( M.constraint_set, rule=constraint_rule ) +M.constraints = Constraint(M.constraint_set, rule=constraint_rule) # ... with a couple of extra constraints ... -M.x1_constraint = Constraint( rule=x1_constraint_rule ) -M.x2_constraint = Constraint( rule=x2_constraint_rule ) -M.x5_constraint = Constraint( rule=x5_constraint_rule ) +M.x1_constraint = Constraint(rule=x1_constraint_rule) +M.x2_constraint = Constraint(rule=x2_constraint_rule) +M.x5_constraint = Constraint(rule=x5_constraint_rule) # ... and finally, add the constraint for which this example was created -M.x_sos_vars = SOSConstraint( var=M.x, sos=2 ) +M.x_sos_vars = SOSConstraint(var=M.x, sos=2) diff --git a/examples/pyomo/sos/sos2_piecewise.py b/examples/pyomo/sos/sos2_piecewise.py index 55bf445c2c2..a3e08a18154 100644 --- a/examples/pyomo/sos/sos2_piecewise.py +++ b/examples/pyomo/sos/sos2_piecewise.py @@ -22,44 +22,63 @@ model = ConcreteModel() -model.index_set = Set(initialize=[1,2]) -DOMAIN_PTS = {1:[1,2,3], 2:[1,2,3]} -F = {1:[1,4,9],2:[1,4,9]} +model.index_set = Set(initialize=[1, 2]) +DOMAIN_PTS = {1: [1, 2, 3], 2: [1, 2, 3]} +F = {1: [1, 4, 9], 2: [1, 4, 9]} # Note we can also implement this like below -#F = lambda x: x**2 +# F = lambda x: x**2 # Update the return value for constraint2_rule if # F is defined using the function above # Indexing set required for the SOSConstraint declaration -def SOS_indices_init(model,t): - return [(t,i) for i in range(len(DOMAIN_PTS[t]))] -model.SOS_indices = Set(model.index_set,dimen=2, ordered=True, initialize=SOS_indices_init) +def SOS_indices_init(model, t): + return [(t, i) for i in range(len(DOMAIN_PTS[t]))] + + +model.SOS_indices = Set( + model.index_set, dimen=2, ordered=True, initialize=SOS_indices_init +) + def sos_var_indices_init(model): - return [(t,i) for t in model.index_set for i in range(len(DOMAIN_PTS[t]))] -model.sos_var_indices = Set(ordered=True, dimen=2,initialize=sos_var_indices_init) + return [(t, i) for t in model.index_set for i in range(len(DOMAIN_PTS[t]))] + -model.x = Var(model.index_set) # domain variable -model.Fx = Var(model.index_set) # range variable -model.y = Var(model.sos_var_indices,within=NonNegativeReals) # SOS2 variable +model.sos_var_indices = Set(ordered=True, dimen=2, initialize=sos_var_indices_init) + +model.x = Var(model.index_set) # domain variable +model.Fx = Var(model.index_set) # range variable +model.y = Var(model.sos_var_indices, within=NonNegativeReals) # SOS2 variable model.obj = Objective(expr=sum_product(model.Fx), sense=maximize) -def constraint1_rule(model,t): - return model.x[t] == sum(model.y[t,i]*DOMAIN_PTS[t][i] for i in range(len(DOMAIN_PTS[t])) ) -def constraint2_rule(model,t): + +def constraint1_rule(model, t): + return model.x[t] == sum( + model.y[t, i] * DOMAIN_PTS[t][i] for i in range(len(DOMAIN_PTS[t])) + ) + + +def constraint2_rule(model, t): # Uncomment below for F defined as dictionary - return model.Fx[t] == sum(model.y[t,i]*F[t][i] for i in range(len(DOMAIN_PTS[t])) ) + return model.Fx[t] == sum( + model.y[t, i] * F[t][i] for i in range(len(DOMAIN_PTS[t])) + ) # Uncomment below for F defined as lambda function - #return model.Fx[t] == sum(model.y[t,i]*F(DOMAIN_PTS[t][i]) for i in range(len(DOMAIN_PTS[t])) ) -def constraint3_rule(model,t): - return sum(model.y[t,j] for j in range(len(DOMAIN_PTS[t]))) == 1 - -model.constraint1 = Constraint(model.index_set,rule=constraint1_rule) -model.constraint2 = Constraint(model.index_set,rule=constraint2_rule) -model.constraint3 = Constraint(model.index_set,rule=constraint3_rule) -model.SOS_set_constraint = SOSConstraint(model.index_set, var=model.y, index=model.SOS_indices, sos=2) - -#Fix the answer for testing purposes -model.set_answer_constraint1 = Constraint(expr= model.x[1] == 2.5) -model.set_answer_constraint2 = Constraint(expr= model.x[2] == 2.0) + # return model.Fx[t] == sum(model.y[t,i]*F(DOMAIN_PTS[t][i]) for i in range(len(DOMAIN_PTS[t])) ) + + +def constraint3_rule(model, t): + return sum(model.y[t, j] for j in range(len(DOMAIN_PTS[t]))) == 1 + + +model.constraint1 = Constraint(model.index_set, rule=constraint1_rule) +model.constraint2 = Constraint(model.index_set, rule=constraint2_rule) +model.constraint3 = Constraint(model.index_set, rule=constraint3_rule) +model.SOS_set_constraint = SOSConstraint( + model.index_set, var=model.y, index=model.SOS_indices, sos=2 +) + +# Fix the answer for testing purposes +model.set_answer_constraint1 = Constraint(expr=model.x[1] == 2.5) +model.set_answer_constraint2 = Constraint(expr=model.x[2] == 2.0) diff --git a/examples/pyomo/suffixes/duals_pyomo.py b/examples/pyomo/suffixes/duals_pyomo.py index 41c8a147b79..9743add3ddd 100644 --- a/examples/pyomo/suffixes/duals_pyomo.py +++ b/examples/pyomo/suffixes/duals_pyomo.py @@ -21,8 +21,7 @@ ### # Declare an IMPORT Suffix to store the dual information that will -# be returned by the solver. When Suffix components are declared +# be returned by the solver. When Suffix components are declared # with an IMPORT direction, Pyomo solver interfaces will attempt to collect # this named information from a solver solution. model.dual = Suffix(direction=Suffix.IMPORT) - diff --git a/examples/pyomo/suffixes/duals_script.py b/examples/pyomo/suffixes/duals_script.py index 4488e83de21..a9db615cad3 100644 --- a/examples/pyomo/suffixes/duals_script.py +++ b/examples/pyomo/suffixes/duals_script.py @@ -28,15 +28,17 @@ ### Create the a solver plugin solver = 'gurobi' -solver_io = 'lp' # Uses the LP file interface -stream_solver = False # True prints solver output to screen -keepfiles = False # True prints intermediate file names (.nl,.sol,...) -opt = SolverFactory(solver,solver_io=solver_io) +solver_io = 'lp' # Uses the LP file interface +stream_solver = False # True prints solver output to screen +keepfiles = False # True prints intermediate file names (.nl,.sol,...) +opt = SolverFactory(solver, solver_io=solver_io) if opt is None: print("") - print("ERROR: Unable to create solver plugin for %s "\ - "using the %s interface" % (solver, solver_io)) + print( + "ERROR: Unable to create solver plugin for %s " + "using the %s interface" % (solver, solver_io) + ) print("") exit(1) @@ -47,11 +49,8 @@ ### Send the model to gurobi_ampl and collect the solution # The solver plugin will scan the model for all active suffixes # valid for importing, which it will store into the results object -results = opt.solve(model, - keepfiles=keepfiles, - tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) print("") print("Dual Solution") print("%s: %s" % (model.con, model.dual[model.con])) - diff --git a/examples/pyomo/suffixes/gurobi_ampl_basis.py b/examples/pyomo/suffixes/gurobi_ampl_basis.py index b44064bfbbc..cd8e4e8f129 100644 --- a/examples/pyomo/suffixes/gurobi_ampl_basis.py +++ b/examples/pyomo/suffixes/gurobi_ampl_basis.py @@ -30,13 +30,15 @@ # solver = 'gurobi_ampl' solver_io = 'nl' -stream_solver = True # True prints solver output to screen -keepfiles = False # True prints intermediate file names (.nl,.sol,...) -opt = SolverFactory(solver,solver_io=solver_io) +stream_solver = True # True prints solver output to screen +keepfiles = False # True prints intermediate file names (.nl,.sol,...) +opt = SolverFactory(solver, solver_io=solver_io) if opt is None: print("") - print("ERROR: Unable to create solver plugin for %s "\ - "using the %s interface" % (solver, solver_io)) + print( + "ERROR: Unable to create solver plugin for %s " + "using the %s interface" % (solver, solver_io) + ) print("") exit(1) @@ -60,10 +62,10 @@ # Create a trivial example model # model = ConcreteModel() -model.s = Set(initialize=[1,2,3]) -model.x = Var(model.s,within=NonNegativeReals) +model.s = Set(initialize=[1, 2, 3]) +model.x = Var(model.s, within=NonNegativeReals) model.obj = Objective(expr=sum_product(model.x)) -model.con = Constraint(model.s, rule=lambda model,i: model.x[i] >= i-1) +model.con = Constraint(model.s, rule=lambda model, i: model.x[i] >= i - 1) ### # @@ -79,8 +81,7 @@ # - 5: nonbasic at equal lower and upper bounds # - 6: nonbasic between bounds -model.sstatus = Suffix(direction=Suffix.IMPORT_EXPORT, - datatype=Suffix.INT) +model.sstatus = Suffix(direction=Suffix.IMPORT_EXPORT, datatype=Suffix.INT) model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) @@ -91,9 +92,7 @@ # solver that certain suffixes are requested by setting a # solver option (see the solver documentation). # -results = opt.solve(model, - keepfiles=keepfiles, - tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) # # Print the suffix values that were imported @@ -101,13 +100,10 @@ print("") print("Suffixes After First Solve:") for i in model.s: - print("%s.sstatus: %s" % (model.x[i].name, - model.sstatus.get(model.x[i]))) + print("%s.sstatus: %s" % (model.x[i].name, model.sstatus.get(model.x[i]))) for i in model.s: - print("%s.sstatus: %s" % (model.con[i].name, - model.sstatus.get(model.con[i]))) - print("%s.dual: %s" % (model.con[i].name, - model.dual.get(model.con[i]))) + print("%s.sstatus: %s" % (model.con[i].name, model.sstatus.get(model.con[i]))) + print("%s.dual: %s" % (model.con[i].name, model.dual.get(model.con[i]))) print("") # @@ -118,6 +114,4 @@ # iterations shown by the solver output that is due to the # extra warmstart information. # -results = opt.solve(model, - keepfiles=keepfiles, - tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) diff --git a/examples/pyomo/suffixes/gurobi_ampl_example.py b/examples/pyomo/suffixes/gurobi_ampl_example.py index 17c7aa0a3db..d133fa422dc 100644 --- a/examples/pyomo/suffixes/gurobi_ampl_example.py +++ b/examples/pyomo/suffixes/gurobi_ampl_example.py @@ -28,52 +28,55 @@ ### Create the gurobi_ampl solver plugin using the ASL interface solver = 'gurobi_ampl' solver_io = 'nl' -stream_solver = False # True prints solver output to screen -keepfiles = False # True prints intermediate file names (.nl,.sol,...) -opt = SolverFactory(solver,solver_io=solver_io) +stream_solver = False # True prints solver output to screen +keepfiles = False # True prints intermediate file names (.nl,.sol,...) +opt = SolverFactory(solver, solver_io=solver_io) if opt is None: print("") - print("ERROR: Unable to create solver plugin for %s "\ - "using the %s interface" % (solver, solver_io)) + print( + "ERROR: Unable to create solver plugin for %s " + "using the %s interface" % (solver, solver_io) + ) print("") exit(1) -opt.options['outlev'] = 1 # tell gurobi to be verbose with output +opt.options['outlev'] = 1 # tell gurobi to be verbose with output ### ### Create a trivial example model model = ConcreteModel() -model.s = Set(initialize=[1,2,3]) -model.x = Var(model.s,within=NonNegativeReals) +model.s = Set(initialize=[1, 2, 3]) +model.x = Var(model.s, within=NonNegativeReals) model.obj = Objective(expr=sum_product(model.x)) -model.con = Constraint(model.s, rule=lambda model,i: model.x[i] >= i-1) +model.con = Constraint(model.s, rule=lambda model, i: model.x[i] >= i - 1) ### ### Declare all suffixes # The variable solution status suffix # (this suffix can be sent to the solver and loaded from the solution) -sstatus_table={'bas':1, # basic - 'sup':2, # superbasic - 'low':3, # nonbasic <= (normally =) lower bound - 'upp':4, # nonbasic >= (normally =) upper bound - 'equ':5, # nonbasic at equal lower and upper bounds - 'btw':6} # nonbasic between bounds -model.sstatus = Suffix(direction=Suffix.IMPORT_EXPORT, - datatype=Suffix.INT) +sstatus_table = { + 'bas': 1, # basic + 'sup': 2, # superbasic + 'low': 3, # nonbasic <= (normally =) lower bound + 'upp': 4, # nonbasic >= (normally =) upper bound + 'equ': 5, # nonbasic at equal lower and upper bounds + 'btw': 6, +} # nonbasic between bounds +model.sstatus = Suffix(direction=Suffix.IMPORT_EXPORT, datatype=Suffix.INT) model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) # Report the best known bound on the objective function model.bestbound = Suffix(direction=Suffix.IMPORT) # A few Gurobi variable solution sensitivity suffixes -model.senslblo = Suffix(direction=Suffix.IMPORT) # smallest variable lower bound -model.senslbhi = Suffix(direction=Suffix.IMPORT) # greatest variable lower bound -model.sensublo = Suffix(direction=Suffix.IMPORT) # smallest variable upper bound -model.sensubhi = Suffix(direction=Suffix.IMPORT) # greatest variable upper bound +model.senslblo = Suffix(direction=Suffix.IMPORT) # smallest variable lower bound +model.senslbhi = Suffix(direction=Suffix.IMPORT) # greatest variable lower bound +model.sensublo = Suffix(direction=Suffix.IMPORT) # smallest variable upper bound +model.sensubhi = Suffix(direction=Suffix.IMPORT) # greatest variable upper bound # A Gurobi constraint solution sensitivity suffix -model.sensrhshi = Suffix(direction=Suffix.IMPORT) # greatest right-hand side value +model.sensrhshi = Suffix(direction=Suffix.IMPORT) # greatest right-hand side value ### # Tell gurobi_ampl to report solution sensitivities @@ -84,28 +87,30 @@ # Set one of the sstatus suffix values, which will be sent to the solver model.sstatus[model.x[1]] = sstatus_table['low'] + def print_model_suffixes(model): # print all suffix values for all model components in a nice table - print("\t",end='') - for name,suffix in active_import_suffix_generator(model): - print("%10s" % (name),end='') + print("\t", end='') + for name, suffix in active_import_suffix_generator(model): + print("%10s" % (name), end='') print("") for i in model.s: - print(model.x[i].name+"\t",end='') - for name,suffix in active_import_suffix_generator(model): - print("%10s" % (suffix.get(model.x[i])),end='') + print(model.x[i].name + "\t", end='') + for name, suffix in active_import_suffix_generator(model): + print("%10s" % (suffix.get(model.x[i])), end='') print("") for i in model.s: - print(model.con[i].name+"\t",end='') - for name,suffix in active_import_suffix_generator(model): - print("%10s" % (suffix.get(model.con[i])),end='') + print(model.con[i].name + "\t", end='') + for name, suffix in active_import_suffix_generator(model): + print("%10s" % (suffix.get(model.con[i])), end='') print("") - print(model.obj.name+"\t",end='') - for name,suffix in active_import_suffix_generator(model): - print("%10s" % (suffix.get(model.obj)),end='') + print(model.obj.name + "\t", end='') + for name, suffix in active_import_suffix_generator(model): + print("%10s" % (suffix.get(model.obj)), end='') print("") print("") + print("") print("Suffixes Before Solve:") print_model_suffixes(model) @@ -113,12 +118,9 @@ def print_model_suffixes(model): ### Send the model to gurobi_ampl and collect the solution # The solver plugin will scan the model for all active suffixes # valid for importing, which it will store into the results object -results = opt.solve(model, - keepfiles=keepfiles, - tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) ### print("") print("Suffixes After Solve:") print_model_suffixes(model) - diff --git a/examples/pyomo/suffixes/gurobi_ampl_iis.py b/examples/pyomo/suffixes/gurobi_ampl_iis.py index cac666202ad..ccba226db78 100644 --- a/examples/pyomo/suffixes/gurobi_ampl_iis.py +++ b/examples/pyomo/suffixes/gurobi_ampl_iis.py @@ -28,14 +28,16 @@ ### Create the gurobi_ampl solver plugin using the ASL interface solver = 'gurobi_ampl' solver_io = 'nl' -stream_solver = False # True prints solver output to screen -keepfiles = False # True prints intermediate file names (.nl,.sol,...) -opt = SolverFactory(solver,solver_io=solver_io) +stream_solver = False # True prints solver output to screen +keepfiles = False # True prints intermediate file names (.nl,.sol,...) +opt = SolverFactory(solver, solver_io=solver_io) if opt is None: print("") - print("ERROR: Unable to create solver plugin for %s "\ - "using the %s interface" % (solver, solver_io)) + print( + "ERROR: Unable to create solver plugin for %s " + "using the %s interface" % (solver, solver_io) + ) print("") exit(1) @@ -43,7 +45,7 @@ opt.options['outlev'] = 1 # tell gurobi to find an iis table for the infeasible model -opt.options['iisfind'] = 1 # tell gurobi to be verbose with output +opt.options['iisfind'] = 1 # tell gurobi to be verbose with output ### Create a trivial and infeasible example model model = ConcreteModel() @@ -59,11 +61,9 @@ ### Send the model to gurobi_ampl and collect the solution # The solver plugin will scan the model for all active suffixes # valid for importing, which it will store into the results object -results = opt.solve(model, - keepfiles=keepfiles, - tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) print("") print("IIS Results") for component, value in model.iis.items(): - print(component.name+" "+str(value)) + print(component.name + " " + str(value)) diff --git a/examples/pyomo/suffixes/ipopt_scaling.py b/examples/pyomo/suffixes/ipopt_scaling.py index b1a6733580d..c192a98dd98 100644 --- a/examples/pyomo/suffixes/ipopt_scaling.py +++ b/examples/pyomo/suffixes/ipopt_scaling.py @@ -26,14 +26,16 @@ ### Create the ipopt solver plugin using the ASL interface solver = 'ipopt' solver_io = 'nl' -stream_solver = False # True prints solver output to screen -keepfiles = False # True prints intermediate file names (.nl,.sol,...) -opt = SolverFactory(solver,solver_io=solver_io) +stream_solver = False # True prints solver output to screen +keepfiles = False # True prints intermediate file names (.nl,.sol,...) +opt = SolverFactory(solver, solver_io=solver_io) if opt is None: print("") - print("ERROR: Unable to create solver plugin for %s "\ - "using the %s interface" % (solver, solver_io)) + print( + "ERROR: Unable to create solver plugin for %s " + "using the %s interface" % (solver, solver_io) + ) print("") exit(1) ### @@ -44,15 +46,21 @@ ### Create the example model model = ConcreteModel() -model.s = Set(initialize=[1,2,3]) -model.y = Var(bounds=(1,5),initialize=1.0) -model.x = Var(model.s,bounds=(1,5),initialize=5.0) -model.obj = Objective(expr=model.y*model.x[3]*(model.y+model.x[1]+model.x[2]) + model.x[2]) -model.inequality = Constraint(expr=model.y*model.x[1]*model.x[2]*model.x[3] >= 25.0) -model.equality = Constraint(expr=model.y**2 + model.x[1]**2 + model.x[2]**2 + model.x[3]**2 == 40.0) +model.s = Set(initialize=[1, 2, 3]) +model.y = Var(bounds=(1, 5), initialize=1.0) +model.x = Var(model.s, bounds=(1, 5), initialize=5.0) +model.obj = Objective( + expr=model.y * model.x[3] * (model.y + model.x[1] + model.x[2]) + model.x[2] +) +model.inequality = Constraint( + expr=model.y * model.x[1] * model.x[2] * model.x[3] >= 25.0 +) +model.equality = Constraint( + expr=model.y**2 + model.x[1] ** 2 + model.x[2] ** 2 + model.x[3] ** 2 == 40.0 +) ### -### Declare the scaling_factor suffix +### Declare the scaling_factor suffix model.scaling_factor = Suffix(direction=Suffix.EXPORT) # set objective scaling factor model.scaling_factor[model.obj] = 4.23 @@ -66,7 +74,7 @@ ### ### Send the model to ipopt and collect the solution -results = opt.solve(model,keepfiles=keepfiles,tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) ### model.pprint() diff --git a/examples/pyomo/suffixes/ipopt_warmstart.py b/examples/pyomo/suffixes/ipopt_warmstart.py index d6379cb9cec..6975bbaaa62 100644 --- a/examples/pyomo/suffixes/ipopt_warmstart.py +++ b/examples/pyomo/suffixes/ipopt_warmstart.py @@ -30,30 +30,36 @@ ### Create the ipopt solver plugin using the ASL interface solver = 'ipopt' solver_io = 'nl' -stream_solver = False # True prints solver output to screen -keepfiles = False # True prints intermediate file names (.nl,.sol,...) -opt = SolverFactory(solver,solver_io=solver_io) +stream_solver = False # True prints solver output to screen +keepfiles = False # True prints intermediate file names (.nl,.sol,...) +opt = SolverFactory(solver, solver_io=solver_io) if opt is None: print("") - print("ERROR: Unable to create solver plugin for %s "\ - "using the %s interface" % (solver, solver_io)) + print( + "ERROR: Unable to create solver plugin for %s " + "using the %s interface" % (solver, solver_io) + ) print("") exit(1) ### ### Create the example model model = ConcreteModel() -model.x1 = Var(bounds=(1,5),initialize=1.0) -model.x2 = Var(bounds=(1,5),initialize=5.0) -model.x3 = Var(bounds=(1,5),initialize=5.0) -model.x4 = Var(bounds=(1,5),initialize=1.0) -model.obj = Objective(expr=model.x1*model.x4*(model.x1+model.x2+model.x3) + model.x3) -model.inequality = Constraint(expr=model.x1*model.x2*model.x3*model.x4 >= 25.0) -model.equality = Constraint(expr=model.x1**2 + model.x2**2 + model.x3**2 + model.x4**2 == 40.0) +model.x1 = Var(bounds=(1, 5), initialize=1.0) +model.x2 = Var(bounds=(1, 5), initialize=5.0) +model.x3 = Var(bounds=(1, 5), initialize=5.0) +model.x4 = Var(bounds=(1, 5), initialize=1.0) +model.obj = Objective( + expr=model.x1 * model.x4 * (model.x1 + model.x2 + model.x3) + model.x3 +) +model.inequality = Constraint(expr=model.x1 * model.x2 * model.x3 * model.x4 >= 25.0) +model.equality = Constraint( + expr=model.x1**2 + model.x2**2 + model.x3**2 + model.x4**2 == 40.0 +) ### -### Declare all suffixes +### Declare all suffixes # Ipopt bound multipliers (obtained from solution) model.ipopt_zL_out = Suffix(direction=Suffix.IMPORT) model.ipopt_zU_out = Suffix(direction=Suffix.IMPORT) @@ -67,24 +73,23 @@ ### Send the model to ipopt and collect the solution print("") print("INITIAL SOLVE") -results = opt.solve(model,keepfiles=keepfiles,tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) ### ### Print Solution -print(" %7s %12s %12s" % ("Value","ipopt_zL_out","ipopt_zU_out")) -for v in [model.x1,model.x2,model.x3,model.x4]: - print("%s %7g %12g %12g" % (v, - value(v), - model.ipopt_zL_out[v], - model.ipopt_zU_out[v])) -print("inequality.dual = "+str(model.dual[model.inequality])) -print("equality.dual = "+str(model.dual[model.equality])) +print(" %7s %12s %12s" % ("Value", "ipopt_zL_out", "ipopt_zU_out")) +for v in [model.x1, model.x2, model.x3, model.x4]: + print( + "%s %7g %12g %12g" % (v, value(v), model.ipopt_zL_out[v], model.ipopt_zU_out[v]) + ) +print("inequality.dual = " + str(model.dual[model.inequality])) +print("equality.dual = " + str(model.dual[model.equality])) ### ### Set Ipopt options for warm-start # The current values on the ipopt_zU_out and -# ipopt_zL_out suffixes will be used as initial +# ipopt_zL_out suffixes will be used as initial # conditions for the bound multipliers to solve # the new problem model.ipopt_zL_in.update(model.ipopt_zL_out) @@ -96,20 +101,19 @@ ### ### Send the model and suffix data to ipopt and collect the solution -print("") +print("") print("WARM-STARTED SOLVE") # The solver plugin will scan the model for all active suffixes # valid for importing, which it will store into the results object -results = opt.solve(model,keepfiles=keepfiles,tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) ### ### Print Solution -print(" %7s %12s %12s" % ("Value","ipopt_zL_out","ipopt_zU_out")) -for v in [model.x1,model.x2,model.x3,model.x4]: - print("%s %7g %12g %12g" % (v, - value(v), - model.ipopt_zL_out[v], - model.ipopt_zU_out[v])) -print("inequality.dual = "+str(model.dual[model.inequality])) -print("equality.dual = "+str(model.dual[model.equality])) +print(" %7s %12s %12s" % ("Value", "ipopt_zL_out", "ipopt_zU_out")) +for v in [model.x1, model.x2, model.x3, model.x4]: + print( + "%s %7g %12g %12g" % (v, value(v), model.ipopt_zL_out[v], model.ipopt_zU_out[v]) + ) +print("inequality.dual = " + str(model.dual[model.inequality])) +print("equality.dual = " + str(model.dual[model.equality])) ### diff --git a/examples/pyomo/suffixes/sipopt_hicks.py b/examples/pyomo/suffixes/sipopt_hicks.py index 0c610f1de8a..dbf4e07b8f7 100644 --- a/examples/pyomo/suffixes/sipopt_hicks.py +++ b/examples/pyomo/suffixes/sipopt_hicks.py @@ -20,7 +20,7 @@ # Execution of this script requires that the ipopt_sens # solver (distributed with Ipopt) is in the current search # path for executables on this system. Optionally required -# are the numpy and matplotlib python modules (needed for +# are the numpy and matplotlib python modules (needed for # viewing results). import pyomo.environ @@ -30,9 +30,9 @@ ### Create the ipopt_sens solver plugin using the ASL interface solver = 'ipopt_sens' solver_io = 'nl' -stream_solver = False # True prints solver output to screen -keepfiles = False # True prints intermediate file names (.nl,.sol,...) -opt = SolverFactory(solver,solver_io=solver_io) +stream_solver = False # True prints solver output to screen +keepfiles = False # True prints intermediate file names (.nl,.sol,...) +opt = SolverFactory(solver, solver_io=solver_io) ### if opt is None: @@ -58,7 +58,7 @@ n = 5.0 alpha1 = 1.0e6 alpha2 = 2.0e3 -alpha3 = 1.e-3 +alpha3 = 1.0e-3 c_des = 0.0944 t_des = 0.7766 u_des = 340.0 @@ -66,65 +66,129 @@ t_init = 0.7293 u_init = 390.0 theta = 20.0 -yc = tc/(jj*cf) -yf = tf/(jj*cf) +yc = tc / (jj * cf) +yf = tf / (jj * cf) model = ConcreteModel() model.c_init_var = Var() model.t_init_var = Var() -model.cdot = Var(FE,CP) -model.tdot = Var(FE,CP) +model.cdot = Var(FE, CP) +model.tdot = Var(FE, CP) + + def c_init_rule(m, i, j): - return float(i)/nfe*(c_des-c_init) + c_init -model.c = Var(FE,CP, within=NonNegativeReals, initialize=c_init_rule) + return float(i) / nfe * (c_des - c_init) + c_init + + +model.c = Var(FE, CP, within=NonNegativeReals, initialize=c_init_rule) + + def t_init_rule(m, i, j): - return float(i)/nfe*(t_des-t_init) + t_init -model.t = Var(FE,CP, within=NonNegativeReals, initialize=t_init_rule) -model.u = Var(FE, within=NonNegativeReals, initialize=1.0) + return float(i) / nfe * (t_des - t_init) + t_init + + +model.t = Var(FE, CP, within=NonNegativeReals, initialize=t_init_rule) +model.u = Var(FE, within=NonNegativeReals, initialize=1.0) a_init = {} -a_init[0,0] = 0.19681547722366 -a_init[0,1] = 0.39442431473909 -a_init[0,2] = 0.37640306270047 -a_init[1,0] = -0.06553542585020 -a_init[1,1] = 0.29207341166523 -a_init[1,2] = 0.51248582618842 -a_init[2,0] = 0.02377097434822 -a_init[2,1] = -0.04154875212600 -a_init[2,2] = 0.11111111111111 +a_init[0, 0] = 0.19681547722366 +a_init[0, 1] = 0.39442431473909 +a_init[0, 2] = 0.37640306270047 +a_init[1, 0] = -0.06553542585020 +a_init[1, 1] = 0.29207341166523 +a_init[1, 2] = 0.51248582618842 +a_init[2, 0] = 0.02377097434822 +a_init[2, 1] = -0.04154875212600 +a_init[2, 2] = 0.11111111111111 + +model.a = Param(FE, CP, initialize=a_init) -model.a = Param(FE,CP, initialize=a_init) +h = [1.0 / nfe] * nfe -h = [1.0/nfe]*nfe def cdot_ode_rule(m, i, j): - return m.cdot[i,j] == (1.0-m.c[i,j])/theta-k10*exp(-n/m.t[i,j])*m.c[i,j] + return ( + m.cdot[i, j] + == (1.0 - m.c[i, j]) / theta - k10 * exp(-n / m.t[i, j]) * m.c[i, j] + ) + + model.cdot_ode = Constraint(FE, CP, rule=cdot_ode_rule) + def tdot_ode_rule(m, i, j): - return m.tdot[i,j] == (yf-m.t[i,j])/theta+k10*exp(-n/m.t[i,j])*m.c[i,j]-alpha*m.u[i]*(m.t[i,j]-yc) + return m.tdot[i, j] == (yf - m.t[i, j]) / theta + k10 * exp(-n / m.t[i, j]) * m.c[ + i, j + ] - alpha * m.u[i] * (m.t[i, j] - yc) + + model.tdot_ode = Constraint(FE, CP, rule=tdot_ode_rule) -def fecolc_rule(m, i,j): - if i==0: - return m.c[i,j] == m.c_init_var + time*h[i]*sum(m.a[k,j]*m.cdot[i,k] for k in CP) + +def fecolc_rule(m, i, j): + if i == 0: + return m.c[i, j] == m.c_init_var + time * h[i] * sum( + m.a[k, j] * m.cdot[i, k] for k in CP + ) else: - return m.c[i,j] == m.c[i-1,ncp-1] + time*h[i]*sum(m.a[k,j]*m.cdot[i,k] for k in CP) + return m.c[i, j] == m.c[i - 1, ncp - 1] + time * h[i] * sum( + m.a[k, j] * m.cdot[i, k] for k in CP + ) + + model.fecolc = Constraint(FE, CP, rule=fecolc_rule) -model.c_init_def = Constraint(expr= model.c_init_var == c_init) -model.t_init_def = Constraint(expr= model.t_init_var == t_init) +model.c_init_def = Constraint(expr=model.c_init_var == c_init) +model.t_init_def = Constraint(expr=model.t_init_var == t_init) + def fecolt_rule(m, i, j): - if i==0: - return m.t[i,j] == m.t_init_var + time*h[i]*sum(m.a[k,j]*m.tdot[i,k] for k in CP) + if i == 0: + return m.t[i, j] == m.t_init_var + time * h[i] * sum( + m.a[k, j] * m.tdot[i, k] for k in CP + ) else: - return m.t[i,j] == m.t[i-1,ncp-1] + time*h[i]*sum(m.a[k,j]*m.tdot[i,k] for k in CP) + return m.t[i, j] == m.t[i - 1, ncp - 1] + time * h[i] * sum( + m.a[k, j] * m.tdot[i, k] for k in CP + ) + + model.fecolt = Constraint(FE, CP, rule=fecolt_rule) + def obj_rule(m): - return \ - sum(h[i]*sum((alpha1*(m.c[i,j]-c_des)**2+ alpha2*(m.t[i,j]-t_des)**2+alpha3*(m.u[i]-u_des)**2 )*m.a[j,ncp-1] for j in CP) for i in range(2,nfe)) + \ - h[0]*sum((alpha1*((m.c_init_var+time*h[0]*sum( m.a[k,j]*m.cdot[0,k] for k in CP)) - c_des)**2 + alpha2*((m.t_init_var+time*h[0]*sum(m.a[k,j]*m.tdot[0,k]for k in CP))-t_des)**2 + alpha3*(m.u[0]-u_des)**2)*m.a[j,ncp-1] for j in CP) + return sum( + h[i] + * sum( + ( + alpha1 * (m.c[i, j] - c_des) ** 2 + + alpha2 * (m.t[i, j] - t_des) ** 2 + + alpha3 * (m.u[i] - u_des) ** 2 + ) + * m.a[j, ncp - 1] + for j in CP + ) + for i in range(2, nfe) + ) + h[0] * sum( + ( + alpha1 + * ( + (m.c_init_var + time * h[0] * sum(m.a[k, j] * m.cdot[0, k] for k in CP)) + - c_des + ) + ** 2 + + alpha2 + * ( + (m.t_init_var + time * h[0] * sum(m.a[k, j] * m.tdot[0, k] for k in CP)) + - t_des + ) + ** 2 + + alpha3 * (m.u[0] - u_des) ** 2 + ) + * m.a[j, ncp - 1] + for j in CP + ) + + model.cost = Objective(rule=obj_rule) ### @@ -132,24 +196,24 @@ def obj_rule(m): model.sens_state_0 = Suffix(direction=Suffix.EXPORT) model.sens_state_1 = Suffix(direction=Suffix.EXPORT) model.sens_state_value_1 = Suffix(direction=Suffix.EXPORT) -model.sens_sol_state_1 = Suffix(direction=Suffix.IMPORT) -model.sens_init_constr = Suffix(direction=Suffix.EXPORT) +model.sens_sol_state_1 = Suffix(direction=Suffix.IMPORT) +model.sens_init_constr = Suffix(direction=Suffix.EXPORT) ### ### set sIPOPT data opt.options['run_sens'] = 'yes' model.sens_state_0[model.c_init_var] = 1 model.sens_state_0[model.t_init_var] = 2 -model.sens_state_1[model.c[4,0]] = 1 -model.sens_state_1[model.t[4,0]] = 2 -model.sens_state_value_1[model.c[4,0]] = 0.135 -model.sens_state_value_1[model.t[4,0]] = 0.745 +model.sens_state_1[model.c[4, 0]] = 1 +model.sens_state_1[model.t[4, 0]] = 2 +model.sens_state_value_1[model.c[4, 0]] = 0.135 +model.sens_state_value_1[model.t[4, 0]] = 0.745 model.sens_init_constr[model.c_init_def] = 1 model.sens_init_constr[model.t_init_def] = 1 ### ### Send the model to ipopt_sens and collect the solution -results = opt.solve(model,keepfiles=keepfiles,tee=stream_solver) +results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver) ### # Plot the results @@ -162,43 +226,46 @@ def obj_rule(m): print("") exit(1) + def collocation_points(n_fe, n_cp, h): t = 0.0 r1 = 0.15505102572168 r2 = 0.64494897427832 r3 = 1.0 for i in range(n_fe): - yield t+h[i]*r1 - yield t+h[i]*r2 - yield t+h[i]*r3 - t += h[i] + yield t + h[i] * r1 + yield t + h[i] * r2 + yield t + h[i] * r3 + t += h[i] + def collocation_idx(n_fe, n_cp): for i in range(n_fe): - yield i,0 - yield i,1 - yield i,2 + yield i, 0 + yield i, 1 + yield i, 2 + times = np.array([i for i in collocation_points(nfe, ncp, h)]) -cnominal = np.zeros((nfe*ncp,1)) -cperturbed = np.zeros((nfe*ncp,1)) -tnominal = np.zeros((nfe*ncp,1)) -tperturbed = np.zeros((nfe*ncp,1)) -for k,(i,j) in enumerate(collocation_idx(nfe, ncp)): - cnominal[k] = value(model.c[i,j]) - tnominal[k] = value(model.t[i,j]) - cperturbed[k] = value(model.sens_sol_state_1[model.c[i,j]]) - tperturbed[k] = value(model.sens_sol_state_1[model.t[i,j]]) - -plt.subplot(2,1,1) +cnominal = np.zeros((nfe * ncp, 1)) +cperturbed = np.zeros((nfe * ncp, 1)) +tnominal = np.zeros((nfe * ncp, 1)) +tperturbed = np.zeros((nfe * ncp, 1)) +for k, (i, j) in enumerate(collocation_idx(nfe, ncp)): + cnominal[k] = value(model.c[i, j]) + tnominal[k] = value(model.t[i, j]) + cperturbed[k] = value(model.sens_sol_state_1[model.c[i, j]]) + tperturbed[k] = value(model.sens_sol_state_1[model.t[i, j]]) + +plt.subplot(2, 1, 1) plt.plot(times, cnominal, label='c_nominal') -#plt.hold(True) +# plt.hold(True) plt.plot(times, cperturbed, label='c_perturbed') -plt.xlim([min(times),max(times)]) +plt.xlim([min(times), max(times)]) plt.legend(loc=0) -plt.subplot(2,1,2) +plt.subplot(2, 1, 2) plt.plot(times, tnominal, label='t_nominal') plt.plot(times, tperturbed, label='t_perturbed') -plt.xlim([min(times),max(times)]) +plt.xlim([min(times), max(times)]) plt.legend(loc=0) plt.show() diff --git a/examples/pyomo/suffixes/sipopt_parametric.py b/examples/pyomo/suffixes/sipopt_parametric.py index d18f750392c..29bba934bd8 100644 --- a/examples/pyomo/suffixes/sipopt_parametric.py +++ b/examples/pyomo/suffixes/sipopt_parametric.py @@ -28,9 +28,9 @@ ### Create the ipopt_sens solver plugin using the ASL interface solver = 'ipopt_sens' solver_io = 'nl' -stream_solver = True # True prints solver output to screen -keepfiles = False # True prints intermediate file names (.nl,.sol,...) -opt = SolverFactory(solver,solver_io=solver_io) +stream_solver = True # True prints solver output to screen +keepfiles = False # True prints intermediate file names (.nl,.sol,...) +opt = SolverFactory(solver, solver_io=solver_io) ### if opt is None: @@ -40,9 +40,9 @@ exit(1) ### Set this data -nominal_eta1 = 4.5 +nominal_eta1 = 4.5 perturbed_eta1 = 4.0 -nominal_eta2 = 1.0 +nominal_eta2 = 1.0 perturbed_eta2 = 1.0 ### Create the model @@ -55,9 +55,11 @@ model.eta1 = Var() model.eta2 = Var() # constraints + objective -model.const1 = Constraint(expr=6*model.x1+3*model.x2+2*model.x3 - model.eta1 == 0) -model.const2 = Constraint(expr=model.eta2*model.x1+model.x2-model.x3-1 == 0) -model.cost = Objective(expr=model.x1**2 + model.x2**2 + model.x3**2) +model.const1 = Constraint( + expr=6 * model.x1 + 3 * model.x2 + 2 * model.x3 - model.eta1 == 0 +) +model.const2 = Constraint(expr=model.eta2 * model.x1 + model.x2 - model.x3 - 1 == 0) +model.cost = Objective(expr=model.x1**2 + model.x2**2 + model.x3**2) model.consteta1 = Constraint(expr=model.eta1 == nominal_eta1) model.consteta2 = Constraint(expr=model.eta2 == nominal_eta2) ### @@ -66,8 +68,8 @@ model.sens_state_0 = Suffix(direction=Suffix.EXPORT) model.sens_state_1 = Suffix(direction=Suffix.EXPORT) model.sens_state_value_1 = Suffix(direction=Suffix.EXPORT) -model.sens_sol_state_1 = Suffix(direction=Suffix.IMPORT) -model.sens_init_constr = Suffix(direction=Suffix.EXPORT) +model.sens_sol_state_1 = Suffix(direction=Suffix.IMPORT) +model.sens_init_constr = Suffix(direction=Suffix.EXPORT) ### ### set sIPOPT data diff --git a/examples/pyomo/transform/scaling_ex.py b/examples/pyomo/transform/scaling_ex.py index 4de84c036bc..a5960393e75 100644 --- a/examples/pyomo/transform/scaling_ex.py +++ b/examples/pyomo/transform/scaling_ex.py @@ -15,22 +15,25 @@ # create the original unscaled model ### model = pe.ConcreteModel() -model.x = pe.Var([1,2,3], bounds=(-10,10), initialize=5.0) -model.z = pe.Var(bounds=(10,20)) +model.x = pe.Var([1, 2, 3], bounds=(-10, 10), initialize=5.0) +model.z = pe.Var(bounds=(10, 20)) model.obj = pe.Objective(expr=model.z + model.x[1]) # demonstrate scaling of duals as well model.dual = pe.Suffix(direction=pe.Suffix.IMPORT) model.rc = pe.Suffix(direction=pe.Suffix.IMPORT) - + + def con_rule(m, i): if i == 1: - return m.x[1] + 2*m.x[2] + 1*m.x[3] == 4.0 + 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 + 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 = pe.Constraint([1,2,3], rule=con_rule) + return m.x[1] + 3.0 * m.x[2] + 1 * m.x[3] == 5.0 + + +model.con = pe.Constraint([1, 2, 3], rule=con_rule) model.zcon = pe.Constraint(expr=model.z >= model.x[2]) ### @@ -40,7 +43,7 @@ def con_rule(m, i): model.scaling_factor[model.obj] = 2.0 model.scaling_factor[model.x] = 0.5 model.scaling_factor[model.z] = -10.0 -model.scaling_factor[model.con[1]] = 0.5 +model.scaling_factor[model.con[1]] = 0.5 model.scaling_factor[model.con[2]] = 2.0 model.scaling_factor[model.con[3]] = -5.0 model.scaling_factor[model.zcon] = -3.0 @@ -67,7 +70,7 @@ def con_rule(m, i): if compare_solutions: # compare the solution of the original model with a clone of the # original that has a backmapped solution from the scaled model - + # solve the original (unscaled) model original_model = model.clone() pe.SolverFactory('glpk').solve(original_model) @@ -90,6 +93,3 @@ def con_rule(m, i): bv = cuid.find_component_on(backmapped_unscaled_model) print('%s\t%.16f\t%.16f' % (v.local_name, pe.value(v), pe.value(bv))) print('=====================================================') - - - diff --git a/examples/pyomo/tutorials/data.py b/examples/pyomo/tutorials/data.py index cf2a5d61972..d065c9ff9bc 100644 --- a/examples/pyomo/tutorials/data.py +++ b/examples/pyomo/tutorials/data.py @@ -56,7 +56,7 @@ # # An indexed set # -model.G = Set(model.A,model.B) +model.G = Set(model.A, model.B) # # A simple set # @@ -95,8 +95,8 @@ # # Initializing a parameter with two indices # -model.U = Param(model.I,model.A) -model.T = Param(model.A,model.I) +model.U = Param(model.I, model.A) +model.T = Param(model.A, model.I) # # Initializing a parameter with missing data # @@ -131,4 +131,3 @@ ## instance = model.create_instance("data.dat") instance.pprint() - diff --git a/examples/pyomo/tutorials/excel.py b/examples/pyomo/tutorials/excel.py index 6e8f86d2d24..127db722c07 100644 --- a/examples/pyomo/tutorials/excel.py +++ b/examples/pyomo/tutorials/excel.py @@ -19,8 +19,8 @@ ## # # Pyomo makes a fundamental distinction between an abstract model and a -# problem instance. The Pyomo AbstractModel() class is used to manage the -# declaration of model components (e.g. sets and variables), and to +# problem instance. The Pyomo AbstractModel() class is used to manage the +# declaration of model components (e.g. sets and variables), and to # generate a problem instance. # model = AbstractModel() @@ -51,12 +51,12 @@ # # An indexed set -# +# model.F = Set(model.A) # # An indexed set -# -model.G = Set(model.A,model.B) +# +model.G = Set(model.A, model.B) # # A simple set # @@ -90,8 +90,8 @@ # # Initializing a parameter with two indices # -model.U = Param(model.I,model.A) -model.T = Param(model.A,model.I) +model.U = Param(model.I, model.A) +model.T = Param(model.A, model.I) # # Initializing a parameter with missing data # @@ -108,12 +108,12 @@ model.P = Param(model.J, within=Reals) model.PP = Param(model.J, within=Reals) model.O = Param(model.J, within=Reals) - + ## -## Process an input file and confirm that we get appropriate +## Process an input file and confirm that we get appropriate ## set instances. ## -#model.pprint() +# model.pprint() data = DataPortal(model=model) data.load(filename="excel.xls", range="Atable", format='set', set='A') @@ -124,19 +124,18 @@ data.load(filename="excel.xls", range="Itable", format='set', set='I') data.load(filename="excel.xls", range="Zparam", format='param', param='Z') data.load(filename="excel.xls", range="Ytable", index='A', param='Y') -data.load(filename="excel.xls", range="XWtable", index='A', param=['X','W']) +data.load(filename="excel.xls", range="XWtable", index='A', param=['X', 'W']) data.load(filename="excel.xls", range="Ttable", param='T', format='transposed_array') data.load(filename="excel.xls", range="Utable", param='U', format='array') data.load(filename="excel.xls", range="Stable", index='A', param='S') -data.load(filename="excel.xls", range="RQtable", index='H', param=('R','Q')) -data.load(filename="excel.xls", range="POtable", index='J', param=('P','O')) -data.load(filename="excel.xls", range="PPtable", index=('A','B'), param="PP") +data.load(filename="excel.xls", range="RQtable", index='H', param=('R', 'Q')) +data.load(filename="excel.xls", range="POtable", index='J', param=('P', 'O')) +data.load(filename="excel.xls", range="PPtable", index=('A', 'B'), param="PP") -#try: +# try: # data.read() -#except pyomo.ApplicationError: +# except pyomo.ApplicationError: # sys.exit(0) - + instance = model.create_instance(data) instance.pprint() - diff --git a/examples/pyomo/tutorials/param.py b/examples/pyomo/tutorials/param.py index d3f1af8d1f5..8612a5ebe13 100644 --- a/examples/pyomo/tutorials/param.py +++ b/examples/pyomo/tutorials/param.py @@ -42,7 +42,7 @@ # # Initializing a parameter with two indices # -model.X = Param(model.A,model.B) +model.X = Param(model.A, model.B) ## ## Parameter Data @@ -56,7 +56,9 @@ def W_init(model, i, j): # # Create the value of model.W[i,j] # - return i*j + return i * j + + model.W = Param(model.A, model.B, initialize=W_init) # # Note that the parameter model.W is not created when this object is @@ -67,10 +69,10 @@ def W_init(model, i, j): # a parameter. These default values may be overriden by later construction # steps, or by data in an input file: # -V_init={} -V_init[1]=1 -V_init[2]=2 -V_init[3]=9 +V_init = {} +V_init[1] = 1 +V_init[2] = 2 +V_init[3] = 9 model.V = Param(model.B, initialize=V_init) # # Note that parameter V is initialized with a dictionary, which maps @@ -93,6 +95,8 @@ def W_init(model, i, j): # def S_validate(model, value): return value in model.A + + model.S = Param(validate=S_validate) ## @@ -109,10 +113,10 @@ def S_validate(model, value): # every parameter value is nonzero, but the parameter is stored with a sparse # representation. # -R_init={} -R_init[2,1]=1 -R_init[2,2]=1 -R_init[2,3]=1 +R_init = {} +R_init[2, 1] = 1 +R_init[2, 2] = 1 +R_init[2, 3] = 1 model.R = Param(model.A, model.B, default=99.0, initialize=R_init) # # Note that the parameter default value can also be specified in an input diff --git a/examples/pyomo/tutorials/set.py b/examples/pyomo/tutorials/set.py index 4fbfdfe3f2b..1deddb7ca03 100644 --- a/examples/pyomo/tutorials/set.py +++ b/examples/pyomo/tutorials/set.py @@ -32,7 +32,7 @@ # to the Set() object: # model.B = Set() -model.C = Set(model.A,model.B) +model.C = Set(model.A, model.B) # # Set declarations can also use standard set operations to declare # a set in a constructive fashion: @@ -60,12 +60,14 @@ # element: # def I_init(model): - ans=[] + ans = [] for a in model.A: for b in model.B: - ans.append( (a,b) ) + ans.append((a, b)) return ans -model.I = Set(within=model.A*model.B, initialize=I_init) + + +model.I = Set(within=model.A * model.B, initialize=I_init) # # Note that the set model.I is not created when this set object is # constructed. Instead, I_init() is called during the construction of a @@ -75,14 +77,14 @@ def I_init(model): # model.J = Set() model.J.construct() -model.J.add(1,4,9) +model.J.add(1, 4, 9) # # The _initialize_ option can also be used to specify the values in # a set. These default values may be overriden by later construction # steps, or by data in an input file: # -model.K = Set(initialize=[1,4,9]) -model.K_2 = Set(initialize=[(1,4),(9,16)],dimen=2) +model.K = Set(initialize=[1, 4, 9]) +model.K_2 = Set(initialize=[(1, 4), (9, 16)], dimen=2) # # Validation of set data is supported in two different ways. First, a # superset can be specified with the _within_ option: @@ -94,12 +96,14 @@ def I_init(model): # def M_validate(model, value): return value in model.A + + model.M = Set(validate=M_validate) # # Although the _within_ option is convenient, it can force the creation of # a temporary set. For example, consider the declaration # -model.N = Set(within=model.A*model.B) +model.N = Set(within=model.A * model.B) # # In this example, the cross-product of sets A and B is needed to validate # the members of set C. Pyomo creates this set implicitly and uses @@ -108,6 +112,8 @@ def M_validate(model, value): # def O_validate(model, value): return value[0] in model.A and value[1] in model.B + + model.O = Set(validate=O_validate) ## @@ -119,8 +125,10 @@ def O_validate(model, value): # array index: # def P_init(model, i, j): - return range(0,i*j) -model.P = Set(model.B,model.B,initialize=P_init) + return range(0, i * j) + + +model.P = Set(model.B, model.B, initialize=P_init) # # A set array CANNOT be explicitly constructed by adding set elements # to individual arrays. For example, the following is invalid: @@ -146,11 +154,11 @@ def P_init(model, i, j): # a set array. These default values are defined in a dictionary, which # specifies how each array element is initialized: # -R_init={} -R_init[2] = [1,3,5] -R_init[3] = [2,4,6] -R_init[4] = [3,5,7] -model.R = Set(model.B,initialize=R_init) +R_init = {} +R_init[2] = [1, 3, 5] +R_init[3] = [2, 4, 6] +R_init[4] = [3, 5, 7] +model.R = Set(model.B, initialize=R_init) # # Validation of a set array is supported with the _within_ option. The # elements of all sets in the array must be in this set: @@ -162,6 +170,8 @@ def P_init(model, i, j): # def T_validate(model, value): return value in model.A + + model.T = Set(model.B, validate=M_validate) ## @@ -178,12 +188,14 @@ def T_validate(model, value): # called repeatedly to construct each element in the set: # def U_init(model, z): - if z==6: + if z == 6: return Set.End - if z==1: + if z == 1: return 1 else: - return model.U[z-1]*z + return model.U[z - 1] * z + + model.U = Set(ordered=True, initialize=U_init) # # This example can be generalized to array sets. Note that in this case @@ -193,12 +205,14 @@ def U_init(model, z): # (inclusive). # def V_init(model, z, i): - if z==6: + if z == 6: return Set.End - if i==1: + if i == 1: return z - return model.V[i-1][z]+z-1 -model.V = Set(RangeSet(1,4), initialize=V_init, ordered=True) + return model.V[i - 1][z] + z - 1 + + +model.V = Set(RangeSet(1, 4), initialize=V_init, ordered=True) ## ## Process an input file and confirm that we get appropriate diff --git a/examples/pyomo/tutorials/table.py b/examples/pyomo/tutorials/table.py index a3221343422..16951352ee1 100644 --- a/examples/pyomo/tutorials/table.py +++ b/examples/pyomo/tutorials/table.py @@ -19,8 +19,8 @@ ## # # Pyomo makes a fundamental distinction between an abstract model and a -# problem instance. The Pyomo AbstractModel() class is used to manage the -# declaration of model components (e.g. sets and variables), and to +# problem instance. The Pyomo AbstractModel() class is used to manage the +# declaration of model components (e.g. sets and variables), and to # generate a problem instance. # model = AbstractModel() @@ -51,12 +51,12 @@ # # An indexed set -# +# model.F = Set(model.A) # # An indexed set -# -model.G = Set(model.A,model.B) +# +model.G = Set(model.A, model.B) # # A simple set # @@ -90,8 +90,8 @@ # # Initializing a parameter with two indices # -model.U = Param(model.I,model.A) -model.T = Param(model.A,model.I) +model.U = Param(model.I, model.A) +model.T = Param(model.A, model.I) # # Initializing a parameter with missing data # @@ -108,9 +108,9 @@ model.P = Param(model.J, within=Reals) model.PP = Param(model.J, within=Reals) model.O = Param(model.J, within=Reals) - + ## -## Process an input file and confirm that we get appropriate +## Process an input file and confirm that we get appropriate ## set instances. ## data = DataPortal() @@ -122,14 +122,13 @@ data.load(filename="tab/I.tab", format='set', set='I') data.load(filename="tab/Z.tab", format='param', param="Z") data.load(filename="tab/Y.tab", index='A', param='Y') -data.load(filename="tab/XW.tab", index='A', param=['X','W']) +data.load(filename="tab/XW.tab", index='A', param=['X', 'W']) data.load(filename="tab/T.tab", param="T", format="transposed_array") data.load(filename="tab/U.tab", param="U", format="array") data.load(filename="tab/S.tab", index='A', param='S') -data.load(filename="tab/RQ.tab", index="H", param=["R","Q"]) -data.load(filename="tab/PO.tab", index="J", param=["P","O"]) +data.load(filename="tab/RQ.tab", index="H", param=["R", "Q"]) +data.load(filename="tab/PO.tab", index="J", param=["P", "O"]) data.load(filename="tab/PP.tab", param="PP") instance = model.create_instance(data) instance.pprint() - diff --git a/examples/pyomobook/abstract-ch/AbstHLinScript.py b/examples/pyomobook/abstract-ch/AbstHLinScript.py index 54dd0e280a3..adf700bfd5c 100644 --- a/examples/pyomobook/abstract-ch/AbstHLinScript.py +++ b/examples/pyomobook/abstract-ch/AbstHLinScript.py @@ -12,26 +12,34 @@ model.b = pyo.Param() model.u = pyo.Param(model.A) + def xbounds_rule(model, i): return (0, model.u[i]) + + model.x = pyo.Var(model.A, bounds=xbounds_rule) + def obj_rule(model): - return sum(model.h[i] * (1 - model.u[i]/model.d[i]**2) * model.x[i] for i in model.A) + return sum( + model.h[i] * (1 - model.u[i] / model.d[i] ** 2) * model.x[i] for i in model.A + ) + model.z = pyo.Objective(rule=obj_rule, sense=pyo.maximize) + def budget_rule(model): return pyo.summation(model.c, model.x) <= model.b + model.budgetconstr = pyo.Constraint(rule=budget_rule) # @tail: opt = pyo.SolverFactory('glpk') instance = model.create_instance("AbstractH.dat") -results = opt.solve(instance) # solves and updates instance +results = opt.solve(instance) # solves and updates instance instance.display() # @:tail - diff --git a/examples/pyomobook/abstract-ch/AbstractH.py b/examples/pyomobook/abstract-ch/AbstractH.py index b436fef1d8b..da9f0a4931c 100644 --- a/examples/pyomobook/abstract-ch/AbstractH.py +++ b/examples/pyomobook/abstract-ch/AbstractH.py @@ -11,16 +11,25 @@ model.b = pyo.Param() model.u = pyo.Param(model.A) + def xbounds_rule(model, i): return (0, model.u[i]) + + model.x = pyo.Var(model.A, bounds=xbounds_rule) + def obj_rule(model): - return sum(model.h[i] * \ - (model.x[i] - (model.x[i]/model.d[i])**2) \ - for i in model.A) + return sum( + model.h[i] * (model.x[i] - (model.x[i] / model.d[i]) ** 2) for i in model.A + ) + + model.z = pyo.Objective(rule=obj_rule, sense=pyo.maximize) + def budget_rule(model): - return sum(model.c[i]*model.x[i] for i in model.A) <= model.b + return sum(model.c[i] * model.x[i] for i in model.A) <= model.b + + model.budgetconstr = pyo.Constraint(rule=budget_rule) diff --git a/examples/pyomobook/abstract-ch/AbstractHLinear.py b/examples/pyomobook/abstract-ch/AbstractHLinear.py index e175a376e40..f184de0461c 100644 --- a/examples/pyomobook/abstract-ch/AbstractHLinear.py +++ b/examples/pyomobook/abstract-ch/AbstractHLinear.py @@ -11,19 +11,27 @@ model.b = pyo.Param() model.u = pyo.Param(model.A) + def xbounds_rule(model, i): return (0, model.u[i]) + + model.x = pyo.Var(model.A, bounds=xbounds_rule) # @obj: def obj_rule(model): - return sum(model.h[i] * \ - (1 - model.u[i]/model.d[i]**2) * model.x[i] \ - for i in model.A) + return sum( + model.h[i] * (1 - model.u[i] / model.d[i] ** 2) * model.x[i] for i in model.A + ) + + # @:obj model.z = pyo.Objective(rule=obj_rule, sense=pyo.maximize) + def budget_rule(model): return pyo.summation(model.c, model.x) <= model.b + + model.budgetconstr = pyo.Constraint(rule=budget_rule) diff --git a/examples/pyomobook/abstract-ch/abstract5.py b/examples/pyomobook/abstract-ch/abstract5.py index c2df442f6d7..3a06256dff8 100644 --- a/examples/pyomobook/abstract-ch/abstract5.py +++ b/examples/pyomobook/abstract-ch/abstract5.py @@ -11,11 +11,16 @@ model.x = pyo.Var(model.N, within=pyo.NonNegativeReals) + def obj_rule(model): - return sum(model.c[i]*model.x[i] for i in model.N) + return sum(model.c[i] * model.x[i] for i in model.N) + + model.obj = pyo.Objective(rule=obj_rule) + def con_rule(model, m): - return sum(model.a[i,m]*model.x[i] for i in model.N) \ - >= model.b[m] + return sum(model.a[i, m] * model.x[i] for i in model.N) >= model.b[m] + + model.con = pyo.Constraint(model.M, rule=con_rule) diff --git a/examples/pyomobook/abstract-ch/abstract6.py b/examples/pyomobook/abstract-ch/abstract6.py index f35971ccb72..d11a4652f64 100644 --- a/examples/pyomobook/abstract-ch/abstract6.py +++ b/examples/pyomobook/abstract-ch/abstract6.py @@ -11,11 +11,16 @@ Model.x = pyo.Var(Model.N, within=pyo.NonNegativeReals) + def obj_rule(Model): - return sum(Model.c[i]*Model.x[i] for i in Model.N) + return sum(Model.c[i] * Model.x[i] for i in Model.N) + + Model.obj = pyo.Objective(rule=obj_rule) + def con_rule(Model, m): - return sum(Model.a[i,m]*Model.x[i] for i in Model.N) \ - >= Model.b[m] + return sum(Model.a[i, m] * Model.x[i] for i in Model.N) >= Model.b[m] + + Model.con = pyo.Constraint(Model.M, rule=con_rule) diff --git a/examples/pyomobook/abstract-ch/abstract7.py b/examples/pyomobook/abstract-ch/abstract7.py index 9b87353eb59..d6a278deed3 100644 --- a/examples/pyomobook/abstract-ch/abstract7.py +++ b/examples/pyomobook/abstract-ch/abstract7.py @@ -9,6 +9,8 @@ def pyomo_preprocess(options=None): print("Here are the options that were provided:") if options is not None: options.display() + + # @:preprocess # @create_model: @@ -17,6 +19,8 @@ def pyomo_create_model(options=None, model_options=None): abstract6 = __import__('abstract6') sys.path.remove(abspath(dirname(__file__))) return abstract6.Model + + # @:create_model # @create_modeldata: @@ -24,52 +28,63 @@ def pyomo_create_dataportal(options=None, model=None): data = pyo.DataPortal(model=model) data.load(filename='abstract6.dat') return data + + # @:create_modeldata # @print_model: def pyomo_print_model(options=None, model=None): if options['runtime']['logging']: model.pprint() + + # @:print_model # @modify_instance: -def pyomo_modify_instance(options=None, model=None, - instance=None): +def pyomo_modify_instance(options=None, model=None, instance=None): instance.x[1].value = 0.0 instance.x[1].fixed = True + + # @:modify_instance # @print_instance: def pyomo_print_instance(options=None, instance=None): if options['runtime']['logging']: instance.pprint() + + # @:print_instance # @save_instance: def pyomo_save_instance(options=None, instance=None): - OUTPUT = open('abstract7.pyomo','w') + OUTPUT = open('abstract7.pyomo', 'w') OUTPUT.write(str(pickle.dumps(instance))) OUTPUT.close() + + # @:save_instance # @print_results: -def pyomo_print_results(options=None, instance=None, - results=None): +def pyomo_print_results(options=None, instance=None, results=None): print(results) + + # @:print_results # @save_results: -def pyomo_save_results(options=None, instance=None, - results=None): - OUTPUT = open('abstract7.results','w') +def pyomo_save_results(options=None, instance=None, results=None): + OUTPUT = open('abstract7.results', 'w') OUTPUT.write(str(results)) OUTPUT.close() + + # @:save_results # @postprocess: -def pyomo_postprocess(options=None, instance=None, - results=None): - instance.solutions.load_from(results, \ - allow_consistent_values_for_fixed_vars=True) - print("Solution value "+str(pyo.value(instance.obj))) +def pyomo_postprocess(options=None, instance=None, results=None): + instance.solutions.load_from(results, allow_consistent_values_for_fixed_vars=True) + print("Solution value " + str(pyo.value(instance.obj))) + + # @:postprocess diff --git a/examples/pyomobook/abstract-ch/bad1.py b/examples/pyomobook/abstract-ch/bad1.py index 0589c2065da..4d18cdb9bb2 100644 --- a/examples/pyomobook/abstract-ch/bad1.py +++ b/examples/pyomobook/abstract-ch/bad1.py @@ -2,11 +2,14 @@ import pyomo.environ as pyo model = pyo.AbstractModel() -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.x = pyo.Var(model.A) + def x_rule(M): return sum(M.x[i] for i in model.A) >= 0 + + model.c = pyo.Constraint(rule=x_rule) instance = model.create_instance() diff --git a/examples/pyomobook/abstract-ch/bad2.py b/examples/pyomobook/abstract-ch/bad2.py index 02bc62f8f45..31fdb2e8326 100644 --- a/examples/pyomobook/abstract-ch/bad2.py +++ b/examples/pyomobook/abstract-ch/bad2.py @@ -3,14 +3,17 @@ model = pyo.AbstractModel() model.q = pyo.Param(initialize=0, mutable=True) -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.x = pyo.Var(model.A) + def x_rule(model): if model.q > 0: return sum(model.x[i] for i in model.A) >= 1 else: return sum(model.x[i] for i in model.A) >= 0 + + model.c = pyo.Constraint(rule=x_rule) instance = model.create_instance() diff --git a/examples/pyomobook/abstract-ch/buildactions.py b/examples/pyomobook/abstract-ch/buildactions.py index c675b09635f..ad918e2b5f2 100644 --- a/examples/pyomobook/abstract-ch/buildactions.py +++ b/examples/pyomobook/abstract-ch/buildactions.py @@ -3,34 +3,52 @@ model = pyo.AbstractModel() -model.N = pyo.Set() # Set of warehouses -model.M = pyo.Set() # Set of customers -model.d = pyo.Param(model.N,model.M) +model.N = pyo.Set() # Set of warehouses +model.M = pyo.Set() # Set of customers +model.d = pyo.Param(model.N, model.M) model.P = pyo.Param() -model.x = pyo.Var(model.N, model.M, bounds=(0,1)) +model.x = pyo.Var(model.N, model.M, bounds=(0, 1)) model.y = pyo.Var(model.N, within=pyo.Binary) + def checkPN_rule(model): return model.P <= len(model.N) + + model.checkPN = pyo.BuildCheck(rule=checkPN_rule) + def obj_rule(model): - return sum(model.d[n,m]*model.x[n,m] for n in model.N for m in model.M) + return sum(model.d[n, m] * model.x[n, m] for n in model.N for m in model.M) + + model.obj = pyo.Objective(rule=obj_rule) + def one_per_cust_rule(model, m): - return sum(model.x[n,m] for n in model.N) == 1 + return sum(model.x[n, m] for n in model.N) == 1 + + model.one_per_cust = pyo.Constraint(model.M, rule=one_per_cust_rule) + def warehouse_active_rule(model, n, m): - return model.x[n,m] <= model.y[n] + return model.x[n, m] <= model.y[n] + + model.warehouse_active = pyo.Constraint(model.N, model.M, rule=warehouse_active_rule) + def num_warehouses_rule(model): return sum(model.y[n] for n in model.N) <= model.P + + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) + def printM_rule(model): model.M.pprint() + + model.printM = pyo.BuildAction(rule=printM_rule) diff --git a/examples/pyomobook/abstract-ch/concrete1.py b/examples/pyomobook/abstract-ch/concrete1.py index a01ef4476cf..0ad41c79ea3 100644 --- a/examples/pyomobook/abstract-ch/concrete1.py +++ b/examples/pyomobook/abstract-ch/concrete1.py @@ -3,6 +3,6 @@ model = pyo.ConcreteModel() model.x_1 = pyo.Var(within=pyo.NonNegativeIntegers) model.x_2 = pyo.Var(within=pyo.NonNegativeIntegers) -model.obj = pyo.Objective(expr=model.x_1 + 2*model.x_2) -model.con1 = pyo.Constraint(expr=3*model.x_1 + 4*model.x_2 >= 1) -model.con2 = pyo.Constraint(expr=2*model.x_1 + 5*model.x_2 >= 2) +model.obj = pyo.Objective(expr=model.x_1 + 2 * model.x_2) +model.con1 = pyo.Constraint(expr=3 * model.x_1 + 4 * model.x_2 >= 1) +model.con2 = pyo.Constraint(expr=2 * model.x_1 + 5 * model.x_2 >= 2) diff --git a/examples/pyomobook/abstract-ch/concrete2.py b/examples/pyomobook/abstract-ch/concrete2.py index 30ca1e78c92..6aee434d556 100644 --- a/examples/pyomobook/abstract-ch/concrete2.py +++ b/examples/pyomobook/abstract-ch/concrete2.py @@ -1,8 +1,7 @@ import pyomo.environ as pyo model = pyo.ConcreteModel() -model.x = pyo.Var([1,2], within=pyo.NonNegativeReals) -model.obj = pyo.Objective(expr=model.x[1] + 2*model.x[2]) -model.con1 = pyo.Constraint(expr=3*model.x[1] + 4*model.x[2]>=1) -model.con2 = pyo.Constraint(expr=2*model.x[1] + 5*model.x[2]>=2) - +model.x = pyo.Var([1, 2], within=pyo.NonNegativeReals) +model.obj = pyo.Objective(expr=model.x[1] + 2 * model.x[2]) +model.con1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1) +model.con2 = pyo.Constraint(expr=2 * model.x[1] + 5 * model.x[2] >= 2) diff --git a/examples/pyomobook/abstract-ch/diet1.py b/examples/pyomobook/abstract-ch/diet1.py index eece699292f..eb8b071cdb5 100644 --- a/examples/pyomobook/abstract-ch/diet1.py +++ b/examples/pyomobook/abstract-ch/diet1.py @@ -2,7 +2,7 @@ import pyomo.environ as pyo infinity = float('inf') -MAX_FOOD_SUPPLY = 20.0 # There is a finite food supply +MAX_FOOD_SUPPLY = 20.0 # There is a finite food supply model = pyo.AbstractModel() @@ -11,8 +11,12 @@ model.FOOD = pyo.Set() model.cost = pyo.Param(model.FOOD, within=pyo.PositiveReals) model.f_min = pyo.Param(model.FOOD, within=pyo.NonNegativeReals, default=0.0) -def f_max_validate (model, value, j): + + +def f_max_validate(model, value, j): return model.f_max[j] > model.f_min[j] + + model.f_max = pyo.Param(model.FOOD, validate=f_max_validate, default=MAX_FOOD_SUPPLY) model.NUTR = pyo.Set() @@ -22,29 +26,50 @@ def f_max_validate (model, value, j): # -------------------------------------------------------- + def Buy_bounds(model, i): return (model.f_min[i], model.f_max[i]) + + model.Buy = pyo.Var(model.FOOD, bounds=Buy_bounds, within=pyo.NonNegativeIntegers) # -------------------------------------------------------- + def Total_Cost_rule(model): return sum(model.cost[j] * model.Buy[j] for j in model.FOOD) + + model.Total_Cost = pyo.Objective(rule=Total_Cost_rule, sense=pyo.minimize) # -------------------------------------------------------- + def Entree_rule(model): - entrees = ['Cheeseburger', 'Ham Sandwich', 'Hamburger', 'Fish Sandwich', 'Chicken Sandwich'] + entrees = [ + 'Cheeseburger', + 'Ham Sandwich', + 'Hamburger', + 'Fish Sandwich', + 'Chicken Sandwich', + ] return sum(model.Buy[e] for e in entrees) >= 1 + + model.Entree = pyo.Constraint(rule=Entree_rule) + def Side_rule(model): sides = ['Fries', 'Sausage Biscuit'] return sum(model.Buy[s] for s in sides) >= 1 + + model.Side = pyo.Constraint(rule=Side_rule) + def Drink_rule(model): drinks = ['Lowfat Milk', 'Orange Juice'] return sum(model.Buy[d] for d in drinks) >= 1 + + model.Drink = pyo.Constraint(rule=Drink_rule) diff --git a/examples/pyomobook/abstract-ch/param2.py b/examples/pyomobook/abstract-ch/param2.py index a747c945523..d51cbeffe84 100644 --- a/examples/pyomobook/abstract-ch/param2.py +++ b/examples/pyomobook/abstract-ch/param2.py @@ -11,4 +11,4 @@ keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) diff --git a/examples/pyomobook/abstract-ch/param2a.py b/examples/pyomobook/abstract-ch/param2a.py index c0adf31e0f4..fe928eb4197 100644 --- a/examples/pyomobook/abstract-ch/param2a.py +++ b/examples/pyomobook/abstract-ch/param2a.py @@ -11,4 +11,4 @@ keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) diff --git a/examples/pyomobook/abstract-ch/param3.py b/examples/pyomobook/abstract-ch/param3.py index 45233df17c9..64efba5c5ad 100644 --- a/examples/pyomobook/abstract-ch/param3.py +++ b/examples/pyomobook/abstract-ch/param3.py @@ -14,12 +14,12 @@ print('B') keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) print('C') keys = instance.C.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.C[key]))) + print(str(key) + " " + str(pyo.value(instance.C[key]))) print('D') keys = instance.D.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.D[key]))) + print(str(key) + " " + str(pyo.value(instance.D[key]))) diff --git a/examples/pyomobook/abstract-ch/param3a.py b/examples/pyomobook/abstract-ch/param3a.py index 0cb63a261e8..857d96f8318 100644 --- a/examples/pyomobook/abstract-ch/param3a.py +++ b/examples/pyomobook/abstract-ch/param3a.py @@ -14,12 +14,12 @@ print('B') keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) print('C') keys = instance.C.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.C[key]))) + print(str(key) + " " + str(pyo.value(instance.C[key]))) print('D') keys = instance.D.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.D[key]))) + print(str(key) + " " + str(pyo.value(instance.D[key]))) diff --git a/examples/pyomobook/abstract-ch/param3b.py b/examples/pyomobook/abstract-ch/param3b.py index bf0d2f01d01..655694c33dd 100644 --- a/examples/pyomobook/abstract-ch/param3b.py +++ b/examples/pyomobook/abstract-ch/param3b.py @@ -14,12 +14,12 @@ print('B') keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) print('C') keys = instance.C.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.C[key]))) + print(str(key) + " " + str(pyo.value(instance.C[key]))) print('D') keys = instance.D.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.D[key]))) + print(str(key) + " " + str(pyo.value(instance.D[key]))) diff --git a/examples/pyomobook/abstract-ch/param3c.py b/examples/pyomobook/abstract-ch/param3c.py index b6dec1d6c7d..7d58b8b6a39 100644 --- a/examples/pyomobook/abstract-ch/param3c.py +++ b/examples/pyomobook/abstract-ch/param3c.py @@ -14,12 +14,12 @@ print('B') keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) print('C') keys = instance.C.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.C[key]))) + print(str(key) + " " + str(pyo.value(instance.C[key]))) print('D') keys = instance.D.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.D[key]))) + print(str(key) + " " + str(pyo.value(instance.D[key]))) diff --git a/examples/pyomobook/abstract-ch/param4.py b/examples/pyomobook/abstract-ch/param4.py index 7c2a4831219..c902b9034ad 100644 --- a/examples/pyomobook/abstract-ch/param4.py +++ b/examples/pyomobook/abstract-ch/param4.py @@ -12,4 +12,4 @@ print('B') keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) diff --git a/examples/pyomobook/abstract-ch/param5.py b/examples/pyomobook/abstract-ch/param5.py index d95fb008edd..488e1debda8 100644 --- a/examples/pyomobook/abstract-ch/param5.py +++ b/examples/pyomobook/abstract-ch/param5.py @@ -11,4 +11,4 @@ keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) diff --git a/examples/pyomobook/abstract-ch/param5a.py b/examples/pyomobook/abstract-ch/param5a.py index cfb96982542..7e814b917cc 100644 --- a/examples/pyomobook/abstract-ch/param5a.py +++ b/examples/pyomobook/abstract-ch/param5a.py @@ -11,4 +11,4 @@ keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) diff --git a/examples/pyomobook/abstract-ch/param6.py b/examples/pyomobook/abstract-ch/param6.py index 2dea55274a9..d9c49a548b2 100644 --- a/examples/pyomobook/abstract-ch/param6.py +++ b/examples/pyomobook/abstract-ch/param6.py @@ -14,12 +14,12 @@ keys = instance.B.keys() print('B') for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) print('C') keys = instance.C.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.C[key]))) + print(str(key) + " " + str(pyo.value(instance.C[key]))) print('D') keys = instance.D.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.D[key]))) + print(str(key) + " " + str(pyo.value(instance.D[key]))) diff --git a/examples/pyomobook/abstract-ch/param6a.py b/examples/pyomobook/abstract-ch/param6a.py index e8053c21d24..e9aca384ee6 100644 --- a/examples/pyomobook/abstract-ch/param6a.py +++ b/examples/pyomobook/abstract-ch/param6a.py @@ -14,12 +14,12 @@ keys = instance.B.keys() print('B') for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) print('C') keys = instance.C.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.C[key]))) + print(str(key) + " " + str(pyo.value(instance.C[key]))) print('D') keys = instance.D.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.D[key]))) + print(str(key) + " " + str(pyo.value(instance.D[key]))) diff --git a/examples/pyomobook/abstract-ch/param7a.py b/examples/pyomobook/abstract-ch/param7a.py index 06f72298f1a..2a18cceabf6 100644 --- a/examples/pyomobook/abstract-ch/param7a.py +++ b/examples/pyomobook/abstract-ch/param7a.py @@ -11,4 +11,4 @@ keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) diff --git a/examples/pyomobook/abstract-ch/param7b.py b/examples/pyomobook/abstract-ch/param7b.py index 142fabf12d5..acf02ddd62f 100644 --- a/examples/pyomobook/abstract-ch/param7b.py +++ b/examples/pyomobook/abstract-ch/param7b.py @@ -11,4 +11,4 @@ keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) diff --git a/examples/pyomobook/abstract-ch/param8a.py b/examples/pyomobook/abstract-ch/param8a.py index 8c22d7e7da0..e68378961ed 100644 --- a/examples/pyomobook/abstract-ch/param8a.py +++ b/examples/pyomobook/abstract-ch/param8a.py @@ -11,4 +11,4 @@ keys = instance.B.keys() for key in sorted(keys): - print(str(key)+" "+str(pyo.value(instance.B[key]))) + print(str(key) + " " + str(pyo.value(instance.B[key]))) diff --git a/examples/pyomobook/abstract-ch/postprocess_fn.py b/examples/pyomobook/abstract-ch/postprocess_fn.py index acae5543a5d..f96a5b4dac1 100644 --- a/examples/pyomobook/abstract-ch/postprocess_fn.py +++ b/examples/pyomobook/abstract-ch/postprocess_fn.py @@ -1,7 +1,7 @@ import csv -def pyomo_postprocess(options=None, instance=None, - results=None): + +def pyomo_postprocess(options=None, instance=None, results=None): # # Collect the data # @@ -12,8 +12,7 @@ def pyomo_postprocess(options=None, instance=None, data[i] = {} for var in results.solution[i].variable: vars.add(var) - data[i][var] = \ - results.solution[i].variable[var]['Value'] + data[i][var] = results.solution[i].variable[var]['Value'] for obj in results.solution[i].objective: f[i] = results.solution[i].objective[obj]['Value'] break @@ -25,15 +24,14 @@ def pyomo_postprocess(options=None, instance=None, rows = [] vars = list(vars) vars.sort() - rows.append(['obj']+vars) + rows.append(['obj'] + vars) for i in range(len(results.solution)): row = [f[i]] for var in vars: - row.append( data[i].get(var,None) ) + row.append(data[i].get(var, None)) rows.append(row) print("Creating results file results.csv") OUTPUT = open('results.csv', 'w') writer = csv.writer(OUTPUT) writer.writerows(rows) OUTPUT.close() - diff --git a/examples/pyomobook/abstract-ch/set1.py b/examples/pyomobook/abstract-ch/set1.py index 1e7c5e7b22e..ee281bd10bd 100644 --- a/examples/pyomobook/abstract-ch/set1.py +++ b/examples/pyomobook/abstract-ch/set1.py @@ -10,4 +10,4 @@ print(sorted(list(instance.A.data()))) print(sorted((instance.B.data()))) -print(sorted(list((instance.C.data())), key=lambda x:x if type(x) is str else str(x))) +print(sorted(list((instance.C.data())), key=lambda x: x if type(x) is str else str(x))) diff --git a/examples/pyomobook/abstract-ch/set3.py b/examples/pyomobook/abstract-ch/set3.py index a1d9a01774a..7661963d19d 100644 --- a/examples/pyomobook/abstract-ch/set3.py +++ b/examples/pyomobook/abstract-ch/set3.py @@ -6,10 +6,14 @@ model.A = pyo.Set() model.B = pyo.Set(model.A) # @:decl -model.C = pyo.Set(model.A,model.A) +model.C = pyo.Set(model.A, model.A) instance = model.create_instance('set3.dat') -print(sorted(list(instance.A.data()), key=lambda x:x if type(x) is str else str(x))) -print(sorted(list(instance.B[1].data()), key=lambda x:x if type(x) is str else str(x))) -print(sorted(list(instance.B['aaa'].data()), key=lambda x:x if type(x) is str else str(x))) +print(sorted(list(instance.A.data()), key=lambda x: x if type(x) is str else str(x))) +print(sorted(list(instance.B[1].data()), key=lambda x: x if type(x) is str else str(x))) +print( + sorted( + list(instance.B['aaa'].data()), key=lambda x: x if type(x) is str else str(x) + ) +) diff --git a/examples/pyomobook/abstract-ch/set5.py b/examples/pyomobook/abstract-ch/set5.py index bd95871c95e..9f79870d3ff 100644 --- a/examples/pyomobook/abstract-ch/set5.py +++ b/examples/pyomobook/abstract-ch/set5.py @@ -9,5 +9,5 @@ instance = model.create_instance('set5.dat') -for tpl in sorted(list(instance.A.data()), key=lambda x:tuple(map(str,x))): +for tpl in sorted(list(instance.A.data()), key=lambda x: tuple(map(str, x))): print(tpl) diff --git a/examples/pyomobook/abstract-ch/wl_abstract.py b/examples/pyomobook/abstract-ch/wl_abstract.py index 40b1729d696..067a06b57e0 100644 --- a/examples/pyomobook/abstract-ch/wl_abstract.py +++ b/examples/pyomobook/abstract-ch/wl_abstract.py @@ -7,28 +7,39 @@ model.M = pyo.Set() # @:setdecl # @paramdecl: -model.d = pyo.Param(model.N,model.M) +model.d = pyo.Param(model.N, model.M) model.P = pyo.Param() # @:paramdecl # @vardecl: -model.x = pyo.Var(model.N, model.M, bounds=(0,1)) +model.x = pyo.Var(model.N, model.M, bounds=(0, 1)) model.y = pyo.Var(model.N, within=pyo.Binary) # @:vardecl + def obj_rule(model): - return sum(model.d[n,m]*model.x[n,m] for n in model.N for m in model.M) + return sum(model.d[n, m] * model.x[n, m] for n in model.N for m in model.M) + + model.obj = pyo.Objective(rule=obj_rule) # @deliver: def one_per_cust_rule(model, m): - return sum(model.x[n,m] for n in model.N) == 1 + return sum(model.x[n, m] for n in model.N) == 1 + + model.one_per_cust = pyo.Constraint(model.M, rule=one_per_cust_rule) # @:deliver + def warehouse_active_rule(model, n, m): - return model.x[n,m] <= model.y[n] + return model.x[n, m] <= model.y[n] + + model.warehouse_active = pyo.Constraint(model.N, model.M, rule=warehouse_active_rule) + def num_warehouses_rule(model): return sum(model.y[n] for n in model.N) <= model.P + + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) diff --git a/examples/pyomobook/abstract-ch/wl_abstract_script.py b/examples/pyomobook/abstract-ch/wl_abstract_script.py index b070e01820b..0b042405714 100644 --- a/examples/pyomobook/abstract-ch/wl_abstract_script.py +++ b/examples/pyomobook/abstract-ch/wl_abstract_script.py @@ -6,26 +6,38 @@ model.N = pyo.Set() model.M = pyo.Set() -model.d = pyo.Param(model.N,model.M) +model.d = pyo.Param(model.N, model.M) model.P = pyo.Param() -model.x = pyo.Var(model.N, model.M, bounds=(0,1)) +model.x = pyo.Var(model.N, model.M, bounds=(0, 1)) model.y = pyo.Var(model.N, within=pyo.Binary) + def obj_rule(model): - return sum(model.d[n,m]*model.x[n,m] for n in model.N for m in model.M) + return sum(model.d[n, m] * model.x[n, m] for n in model.N for m in model.M) + + model.obj = pyo.Objective(rule=obj_rule) + def one_per_cust_rule(model, m): - return sum(model.x[n,m] for n in model.N) == 1 + return sum(model.x[n, m] for n in model.N) == 1 + + model.one_per_cust = pyo.Constraint(model.M, rule=one_per_cust_rule) + def warehouse_active_rule(model, n, m): - return model.x[n,m] <= model.y[n] + return model.x[n, m] <= model.y[n] + + model.warehouse_active = pyo.Constraint(model.N, model.M, rule=warehouse_active_rule) + def num_warehouses_rule(model): return sum(model.y[n] for n in model.N) <= model.P + + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) # @abstractsolve: diff --git a/examples/pyomobook/blocks-ch/blocks_gen.py b/examples/pyomobook/blocks-ch/blocks_gen.py index 5b98366febc..109e881cad5 100644 --- a/examples/pyomobook/blocks-ch/blocks_gen.py +++ b/examples/pyomobook/blocks-ch/blocks_gen.py @@ -10,22 +10,31 @@ model = pyo.ConcreteModel() model.TIME = pyo.Set(initialize=time, ordered=True) model.GEN_UNITS = pyo.Set(initialize=genset, ordered=True) -def generator_rule(b,g): + + +def generator_rule(b, g): m = b.model() b.MaxPower = pyo.Param(within=pyo.NonNegativeReals, initialize=maxpower) b.RampLimit = pyo.Param(within=pyo.NonNegativeReals, initialize=ramplimit) - b.Power = pyo.Var(m.TIME, bounds=(0,b.MaxPower), initialize=gennom) + b.Power = pyo.Var(m.TIME, bounds=(0, b.MaxPower), initialize=gennom) b.UnitOn = pyo.Var(m.TIME, within=pyo.Binary) + def limit_ramp(_b, t): if t == min(_b.model().TIME): return pyo.Constraint.Skip - return pyo.inequality(-_b.RampLimit, _b.Power[t] - _b.Power[t-1], _b.RampLimit) + return pyo.inequality( + -_b.RampLimit, _b.Power[t] - _b.Power[t - 1], _b.RampLimit + ) + b.limit_ramp = pyo.Constraint(m.TIME, rule=limit_ramp) - b.CostCoef = pyo.Param([1,2]) - def Cost(_b,t): - return sum(_b.CostCoef[i]*_b.Power[t]**i for i in _b.CostCoef) + b.CostCoef = pyo.Param([1, 2]) + + def Cost(_b, t): + return sum(_b.CostCoef[i] * _b.Power[t] ** i for i in _b.CostCoef) + b.Cost = pyo.Expression(m.TIME, rule=Cost) - + + model.Generator = pyo.Block(model.GEN_UNITS, rule=generator_rule) # @:usepassedblock @@ -37,24 +46,32 @@ def Cost(_b,t): model.TIME = pyo.Set(initialize=time, ordered=True) model.GEN_UNITS = pyo.Set(initialize=genset, ordered=True) -def generator_rule(b,g): + +def generator_rule(b, g): m = b.model() gen = pyo.Block(concrete=True) gen.MaxPower = pyo.Param(within=pyo.NonNegativeReals, initialize=maxpower) gen.RampLimit = pyo.Param(within=pyo.NonNegativeReals, initialize=ramplimit) - gen.Power = pyo.Var(m.TIME, bounds=(0,gen.MaxPower), initialize=gennom) + gen.Power = pyo.Var(m.TIME, bounds=(0, gen.MaxPower), initialize=gennom) gen.UnitOn = pyo.Var(m.TIME, within=pyo.Binary) + def limit_ramp(_b, t): if t == m.TIME.first(): return pyo.Constraint.Skip - return pyo.inequality(-_b.RampLimit, _b.Power[t] - _b.Power[t-1], _b.RampLimit) + return pyo.inequality( + -_b.RampLimit, _b.Power[t] - _b.Power[t - 1], _b.RampLimit + ) + gen.limit_ramp = pyo.Constraint(m.TIME, rule=limit_ramp) - gen.CostCoef = pyo.Param([1,2]) - def Cost(_b,t): - return sum(_b.CostCoef[i]*_b.Power[t]**i for i in _b.CostCoef) + gen.CostCoef = pyo.Param([1, 2]) + + def Cost(_b, t): + return sum(_b.CostCoef[i] * _b.Power[t] ** i for i in _b.CostCoef) + gen.Cost = pyo.Expression(m.TIME, rule=Cost) return gen + model.Generator = pyo.Block(model.GEN_UNITS, rule=generator_rule) # @:buildnewblock diff --git a/examples/pyomobook/blocks-ch/blocks_intro.py b/examples/pyomobook/blocks-ch/blocks_intro.py index bff67528f71..0e75e1d641f 100644 --- a/examples/pyomobook/blocks-ch/blocks_intro.py +++ b/examples/pyomobook/blocks-ch/blocks_intro.py @@ -9,29 +9,29 @@ model.b.I = pyo.RangeSet(model.P) model.b.x = pyo.Var(model.b.I) model.b.y = pyo.Var(model.S) -model.b.b = pyo.Block([1,2]) +model.b.b = pyo.Block([1, 2]) model.b.b[1].x = pyo.Var() model.b.b[2].x = pyo.Var() # @:hierarchy # @hierarchyprint: -print(model.x.local_name) # x -print(model.x.name) # x -print(model.b.x.local_name) # x -print(model.b.x.name) # b.x -print(model.b.b[1].x.local_name) # x -print(model.b.b[1].x.name) # b.b[1].x +print(model.x.local_name) # x +print(model.x.name) # x +print(model.b.x.local_name) # x +print(model.b.x.name) # b.x +print(model.b.b[1].x.local_name) # x +print(model.b.b[1].x.name) # b.b[1].x # @:hierarchyprint # @hierarchymove: model.b.b[1].x.parent_component() # is model.b.b[1].x -model.b.b[1].x.parent_block() # is model.b.b[1] -model.b.b[1].x.model() # is model -model.b.b[1].component('x') # is model.b.b[1].x -model.b.x[1].parent_component() # is model.b.x -model.b.x[1].parent_block() # is model.b -model.b.x[1].model() # is model -model.b.component('x') # is model.b.x +model.b.b[1].x.parent_block() # is model.b.b[1] +model.b.b[1].x.model() # is model +model.b.b[1].component('x') # is model.b.b[1].x +model.b.x[1].parent_component() # is model.b.x +model.b.x[1].parent_block() # is model.b +model.b.x[1].model() # is model +model.b.component('x') # is model.b.x # @:hierarchymove model = None @@ -53,11 +53,14 @@ model.P = pyo.Param(initialize=3) model.T = pyo.RangeSet(model.P) + def xyb_rule(b, t): b.x = pyo.Var() b.I = pyo.RangeSet(t) b.y = pyo.Var(b.I) b.c = pyo.Constraint(expr=b.x == 1 - sum(b.y[i] for i in b.I)) + + model.xyb = pyo.Block(model.T, rule=xyb_rule) # @:blockrule model.pprint() @@ -71,9 +74,13 @@ def xyb_rule(b, t): b.x = pyo.Var() b.I = pyo.RangeSet(t) b.y = pyo.Var(b.I, initialize=1.0) + def _b_c_rule(_b): return _b.x == 1.0 - sum(_b.y[i] for i in _b.I) + b.c = pyo.Constraint(rule=_b_c_rule) + + model.xyb = pyo.Block(model.T, rule=xyb_rule) # @:blockrule2 model.pprint() @@ -85,8 +92,8 @@ def _b_c_rule(_b): # @blockvalues1: for t in model.xyb: - for i in model.xyb[t].y: - print("%s %f" % (model.xyb[t].y[i], pyo.value(model.xyb[t].y[i]))) + for i in model.xyb[t].y: + print("%s %f" % (model.xyb[t].y[i], pyo.value(model.xyb[t].y[i]))) # @:blockvalues1 # @blockvalues2: diff --git a/examples/pyomobook/blocks-ch/blocks_lotsizing.py b/examples/pyomobook/blocks-ch/blocks_lotsizing.py index e5f42c199d4..2f0e237d915 100644 --- a/examples/pyomobook/blocks-ch/blocks_lotsizing.py +++ b/examples/pyomobook/blocks-ch/blocks_lotsizing.py @@ -1,16 +1,16 @@ import pyomo.environ as pyo model = pyo.ConcreteModel() -model.T = pyo.RangeSet(5) # time periods +model.T = pyo.RangeSet(5) # time periods -i0 = 5.0 # initial inventory -c = 4.6 # setup cost -h_pos = 0.7 # inventory holding cost -h_neg = 1.2 # shortage cost -P = 5.0 # maximum production amount +i0 = 5.0 # initial inventory +c = 4.6 # setup cost +h_pos = 0.7 # inventory holding cost +h_neg = 1.2 # shortage cost +P = 5.0 # maximum production amount # demand during period t -d = {1: 5.0, 2:7.0, 3:6.2, 4:3.1, 5:1.7} +d = {1: 5.0, 2: 7.0, 3: 6.2, 4: 3.1, 5: 1.7} # @blockrule: # create a block for a single time period @@ -27,6 +27,8 @@ def lotsizing_block_rule(b, t): b.inventory = pyo.Constraint(expr=b.i == b.i0 + b.x - d[t]) b.pos_neg = pyo.Constraint(expr=b.i == b.i_pos - b.i_neg) b.prod_indicator = pyo.Constraint(expr=b.x <= P * b.y) + + model.lsb = pyo.Block(model.T, rule=lotsizing_block_rule) # @:blockrule @@ -34,12 +36,18 @@ def lotsizing_block_rule(b, t): def i_linking_rule(m, t): if t == m.T.first(): return m.lsb[t].i0 == i0 - return m.lsb[t].i0 == m.lsb[t-1].i + return m.lsb[t].i0 == m.lsb[t - 1].i + + model.i_linking = pyo.Constraint(model.T, rule=i_linking_rule) # construct the objective function over all the blocks def obj_rule(m): - return sum(c*m.lsb[t].y + h_pos*m.lsb[t].i_pos + h_neg*m.lsb[t].i_neg for t in m.T) + return sum( + c * m.lsb[t].y + h_pos * m.lsb[t].i_pos + h_neg * m.lsb[t].i_neg for t in m.T + ) + + model.obj = pyo.Objective(rule=obj_rule) ### solve the problem @@ -48,4 +56,4 @@ def obj_rule(m): # print the results for t in model.T: - print('Period: {0}, Prod. Amount: {1}'.format(t, pyo.value(model.lsb[t].x))) + print('Period: {0}, Prod. Amount: {1}'.format(t, pyo.value(model.lsb[t].x))) diff --git a/examples/pyomobook/blocks-ch/lotsizing.py b/examples/pyomobook/blocks-ch/lotsizing.py index 9d73ef9a72d..8ccdd150ff6 100644 --- a/examples/pyomobook/blocks-ch/lotsizing.py +++ b/examples/pyomobook/blocks-ch/lotsizing.py @@ -1,16 +1,16 @@ import pyomo.environ as pyo model = pyo.ConcreteModel() -model.T = pyo.RangeSet(5) # time periods +model.T = pyo.RangeSet(5) # time periods -i0 = 5.0 # initial inventory -c = 4.6 # setup cost -h_pos = 0.7 # inventory holding cost -h_neg = 1.2 # shortage cost -P = 5.0 # maximum production amount +i0 = 5.0 # initial inventory +c = 4.6 # setup cost +h_pos = 0.7 # inventory holding cost +h_neg = 1.2 # shortage cost +P = 5.0 # maximum production amount # demand during period t -d = {1: 5.0, 2:7.0, 3:6.2, 4:3.1, 5:1.7} +d = {1: 5.0, 2: 7.0, 3: 6.2, 4: 3.1, 5: 1.7} # @vars: # define the variables @@ -25,21 +25,30 @@ def inventory_rule(m, t): if t == m.T.first(): return m.i[t] == i0 + m.x[t] - d[t] - return m.i[t] == m.i[t-1] + m.x[t] - d[t] + return m.i[t] == m.i[t - 1] + m.x[t] - d[t] + + model.inventory = pyo.Constraint(model.T, rule=inventory_rule) + def pos_neg_rule(m, t): return m.i[t] == m.i_pos[t] - m.i_neg[t] + + model.pos_neg = pyo.Constraint(model.T, rule=pos_neg_rule) # create the big-M constraint for the production indicator variable -def prod_indicator_rule(m,t): - return m.x[t] <= P*m.y[t] +def prod_indicator_rule(m, t): + return m.x[t] <= P * m.y[t] + + model.prod_indicator = pyo.Constraint(model.T, rule=prod_indicator_rule) # define the cost function def obj_rule(m): - return sum(c*m.y[t] + h_pos*m.i_pos[t] + h_neg*m.i_neg[t] for t in m.T) + return sum(c * m.y[t] + h_pos * m.i_pos[t] + h_neg * m.i_neg[t] for t in m.T) + + model.obj = pyo.Objective(rule=obj_rule) # solve the problem @@ -48,5 +57,4 @@ def obj_rule(m): # print the results for t in model.T: - print('Period: {0}, Prod. Amount: {1}'.format(t, pyo.value(model.x[t]))) - + print('Period: {0}, Prod. Amount: {1}'.format(t, pyo.value(model.x[t]))) diff --git a/examples/pyomobook/blocks-ch/lotsizing_no_time.py b/examples/pyomobook/blocks-ch/lotsizing_no_time.py index 5abc8baf24b..901467a0cbb 100644 --- a/examples/pyomobook/blocks-ch/lotsizing_no_time.py +++ b/examples/pyomobook/blocks-ch/lotsizing_no_time.py @@ -1,17 +1,17 @@ import pyomo.environ as pyo model = pyo.ConcreteModel() -model.T = pyo.RangeSet(5) # time periods +model.T = pyo.RangeSet(5) # time periods model.S = pyo.RangeSet(5) -i0 = 5.0 # initial inventory -c = 4.6 # setup cost -h_pos = 0.7 # inventory holding cost -h_neg = 1.2 # shortage cost -P = 5.0 # maximum production amount +i0 = 5.0 # initial inventory +c = 4.6 # setup cost +h_pos = 0.7 # inventory holding cost +h_neg = 1.2 # shortage cost +P = 5.0 # maximum production amount # demand during period t -d = {1: 5.0, 2:7.0, 3:6.2, 4:3.1, 5:1.7} +d = {1: 5.0, 2: 7.0, 3: 6.2, 4: 3.1, 5: 1.7} # @vars: # define the variables diff --git a/examples/pyomobook/blocks-ch/lotsizing_uncertain.py b/examples/pyomobook/blocks-ch/lotsizing_uncertain.py index 3c9e09bd79a..6d16de7e3a7 100644 --- a/examples/pyomobook/blocks-ch/lotsizing_uncertain.py +++ b/examples/pyomobook/blocks-ch/lotsizing_uncertain.py @@ -1,23 +1,23 @@ import pyomo.environ as pyo model = pyo.ConcreteModel() -model.T = pyo.RangeSet(5) # time periods +model.T = pyo.RangeSet(5) # time periods model.S = pyo.RangeSet(5) -i0 = 5.0 # initial inventory -c = 4.6 # setup cost -h_pos = 0.7 # inventory holding cost -h_neg = 1.2 # shortage cost -P = 5.0 # maximum production amount +i0 = 5.0 # initial inventory +c = 4.6 # setup cost +h_pos = 0.7 # inventory holding cost +h_neg = 1.2 # shortage cost +P = 5.0 # maximum production amount # demand during period t -d = {1: 5.0, 2:7.0, 3:6.2, 4:3.1, 5:1.7} +d = {1: 5.0, 2: 7.0, 3: 6.2, 4: 3.1, 5: 1.7} # @vars: # define the variables model.y = pyo.Var(model.T, model.S, domain=pyo.Binary) model.x = pyo.Var(model.T, model.S, domain=pyo.NonNegativeReals) -model.i = pyo.Var(model.T, model.S,) +model.i = pyo.Var(model.T, model.S) model.i_pos = pyo.Var(model.T, model.S, domain=pyo.NonNegativeReals) model.i_neg = pyo.Var(model.T, model.S, domain=pyo.NonNegativeReals) # @:vars diff --git a/examples/pyomobook/dae-ch/dae_tester_model.py b/examples/pyomobook/dae-ch/dae_tester_model.py index a6664f74575..9e0da9f4a62 100644 --- a/examples/pyomobook/dae-ch/dae_tester_model.py +++ b/examples/pyomobook/dae-ch/dae_tester_model.py @@ -3,7 +3,7 @@ import pyomo.dae as dae m = pyo.ConcreteModel() -m.t = dae.ContinuousSet(bounds=(0,1)) +m.t = dae.ContinuousSet(bounds=(0, 1)) m.x1 = pyo.Var(m.t) # @second-deriv: @@ -20,8 +20,8 @@ print(len(m.x1)) m = pyo.ConcreteModel() -m.t1 = dae.ContinuousSet(bounds=(0,1)) -m.t2 = dae.ContinuousSet(bounds=(0,1)) +m.t1 = dae.ContinuousSet(bounds=(0, 1)) +m.t2 = dae.ContinuousSet(bounds=(0, 1)) m.x1 = pyo.Var(m.t1, m.t2) m.dx1dt2 = dae.DerivativeVar(m.x1, wrt=(m.t1, m.t2)) @@ -39,8 +39,8 @@ print(len(m.x1)) m = pyo.ConcreteModel() -m.t1 = dae.ContinuousSet(bounds=(0,1)) -m.t2 = dae.ContinuousSet(bounds=(0,1)) +m.t1 = dae.ContinuousSet(bounds=(0, 1)) +m.t2 = dae.ContinuousSet(bounds=(0, 1)) m.x1 = pyo.Var(m.t1, m.t2) m.dx1dt2 = dae.DerivativeVar(m.x1, wrt=(m.t1, m.t2)) @@ -58,14 +58,14 @@ print(len(m.x1)) m = pyo.ConcreteModel() -m.t1 = dae.ContinuousSet(bounds=(0,1)) -m.t2 = dae.ContinuousSet(bounds=(0,1)) +m.t1 = dae.ContinuousSet(bounds=(0, 1)) +m.t2 = dae.ContinuousSet(bounds=(0, 1)) m.x1 = pyo.Var(m.t1, m.t2) m.dx1dt2 = dae.DerivativeVar(m.x1, wrt=(m.t1, m.t2)) # @finite-colloc: -# Apply a combination of finite difference and +# Apply a combination of finite difference and # collocation schemes discretizer1 = pyo.TransformationFactory('dae.finite_difference') discretizer2 = pyo.TransformationFactory('dae.collocation') diff --git a/examples/pyomobook/dae-ch/path_constraint.py b/examples/pyomobook/dae-ch/path_constraint.py index d0d96740b68..ae0cf6d0983 100644 --- a/examples/pyomobook/dae-ch/path_constraint.py +++ b/examples/pyomobook/dae-ch/path_constraint.py @@ -22,13 +22,14 @@ # @import: import pyomo.environ as pyo import pyomo.dae as dae + # @:import m = pyo.ConcreteModel() # @contset: m.tf = pyo.Param(initialize=1) -m.t = dae.ContinuousSet(bounds=(0,m.tf)) +m.t = dae.ContinuousSet(bounds=(0, m.tf)) # @:contset # @vardecl: @@ -45,22 +46,33 @@ # @diffeq: def _x1dot(m, t): return m.dx1[t] == m.x2[t] + + m.x1dotcon = pyo.Constraint(m.t, rule=_x1dot) + def _x2dot(m, t): - return m.dx2[t] == -m.x2[t] + m.u[t] + return m.dx2[t] == -m.x2[t] + m.u[t] + + m.x2dotcon = pyo.Constraint(m.t, rule=_x2dot) + def _x3dot(m, t): - return m.dx3[t] == m.x1[t]**2 + m.x2[t]**2 + 0.005*m.u[t]**2 + return m.dx3[t] == m.x1[t] ** 2 + m.x2[t] ** 2 + 0.005 * m.u[t] ** 2 + + m.x3dotcon = pyo.Constraint(m.t, rule=_x3dot) # @:diffeq # @objpath: m.obj = pyo.Objective(expr=m.x3[m.tf]) + def _con(m, t): - return m.x2[t] - 8*(t - 0.5)**2 + 0.5 <= 0 + return m.x2[t] - 8 * (t - 0.5) ** 2 + 0.5 <= 0 + + m.con = pyo.Constraint(m.t, rule=_con) # @:objpath diff --git a/examples/pyomobook/dae-ch/plot_path_constraint.py b/examples/pyomobook/dae-ch/plot_path_constraint.py index 56197b0dab3..4c04bc1b6b6 100644 --- a/examples/pyomobook/dae-ch/plot_path_constraint.py +++ b/examples/pyomobook/dae-ch/plot_path_constraint.py @@ -1,15 +1,17 @@ # @plot_path: def plotter(subplot, x, *y, **kwds): plt.subplot(subplot) - for i,_y in enumerate(y): - plt.plot(list(x), [value(_y[t]) for t in x], 'brgcmk'[i%6]) + for i, _y in enumerate(y): + plt.plot(list(x), [value(_y[t]) for t in x], 'brgcmk'[i % 6]) if kwds.get('points', False): plt.plot(list(x), [value(_y[t]) for t in x], 'o') - plt.title(kwds.get('title','')) + plt.title(kwds.get('title', '')) plt.legend(tuple(_y.name for _y in y)) plt.xlabel(x.name) + import matplotlib.pyplot as plt + plotter(121, m.t, m.x1, m.x2, title='Differential Variables') plotter(122, m.t, m.u, title='Control Variable', points=True) plt.show() diff --git a/examples/pyomobook/dae-ch/run_path_constraint.py b/examples/pyomobook/dae-ch/run_path_constraint.py index 983658198f7..b819d6a7127 100644 --- a/examples/pyomobook/dae-ch/run_path_constraint.py +++ b/examples/pyomobook/dae-ch/run_path_constraint.py @@ -5,12 +5,11 @@ # Discretize model using Orthogonal Collocation # @disc: discretizer = pyo.TransformationFactory('dae.collocation') -discretizer.apply_to(m,nfe=7,ncp=6,scheme='LAGRANGE-RADAU') +discretizer.apply_to(m, nfe=7, ncp=6, scheme='LAGRANGE-RADAU') # @:disc # @reduce: discretizer.reduce_collocation_points(m, var=m.u, ncp=1, contset=m.t) # @:reduce -solver=pyo.SolverFactory('ipopt') +solver = pyo.SolverFactory('ipopt') solver.solve(m, tee=True) - diff --git a/examples/pyomobook/gdp-ch/gdp_uc.py b/examples/pyomobook/gdp-ch/gdp_uc.py index bcb15e75683..3bea0d13807 100644 --- a/examples/pyomobook/gdp-ch/gdp_uc.py +++ b/examples/pyomobook/gdp-ch/gdp_uc.py @@ -16,64 +16,79 @@ model.StartUpRampLimit = pyo.Param(model.GENERATORS, within=pyo.NonNegativeReals) model.ShutDownRampLimit = pyo.Param(model.GENERATORS, within=pyo.NonNegativeReals) -def Power_bound(m,g,t): + +def Power_bound(m, g, t): return (0, m.MaxPower[g]) + + model.Power = pyo.Var(model.GENERATORS, model.TIME, bounds=Power_bound) + def GenOn(b, g, t): m = b.model() b.power_limit = pyo.Constraint( - expr=pyo.inequality(m.MinPower[g], m.Power[g,t], m.MaxPower[g]) ) + expr=pyo.inequality(m.MinPower[g], m.Power[g, t], m.MaxPower[g]) + ) if t == m.TIME.first(): return b.ramp_limit = pyo.Constraint( - expr=pyo.inequality(-m.RampDownLimit[g], - m.Power[g,t] - m.Power[g,t-1], - m.RampUpLimit[g]) + expr=pyo.inequality( + -m.RampDownLimit[g], m.Power[g, t] - m.Power[g, t - 1], m.RampUpLimit[g] + ) ) + + model.GenOn = Disjunct(model.GENERATORS, model.TIME, rule=GenOn) + def GenOff(b, g, t): m = b.model() - b.power_limit = pyo.Constraint( - expr=m.Power[g,t] == 0 ) + b.power_limit = pyo.Constraint(expr=m.Power[g, t] == 0) if t == m.TIME.first(): return - b.ramp_limit = pyo.Constraint( - expr=m.Power[g,t-1] <= m.ShutDownRampLimit[g] ) + b.ramp_limit = pyo.Constraint(expr=m.Power[g, t - 1] <= m.ShutDownRampLimit[g]) + + model.GenOff = Disjunct(model.GENERATORS, model.TIME, rule=GenOff) + def GenStartUp(b, g, t): m = b.model() - b.power_limit = pyo.Constraint( - expr=m.Power[g,t] <= m.StartUpRampLimit[g] ) + b.power_limit = pyo.Constraint(expr=m.Power[g, t] <= m.StartUpRampLimit[g]) + + model.GenStartup = Disjunct(model.GENERATORS, model.TIME, rule=GenStartUp) # @:disjuncts # @disjunction: def bind_generators(m, g, t): - return [m.GenOn[g, t], m.GenOff[g, t], m.GenStartup[g, t]] -model.bind_generators = Disjunction( - model.GENERATORS, model.TIME, rule=bind_generators) + return [m.GenOn[g, t], m.GenOff[g, t], m.GenStartup[g, t]] + + +model.bind_generators = Disjunction(model.GENERATORS, model.TIME, rule=bind_generators) # @:disjunction # @logic: def onState(m, g, t): if t == m.TIME.first(): return pyo.LogicalConstraint.Skip - return m.GenOn[g, t].indicator_var.implies(pyo.lor( - m.GenOn[g, t-1].indicator_var, - m.GenStartup[g, t-1].indicator_var)) -model.onState = pyo.LogicalConstraint( - model.GENERATORS, model.TIME, rule=onState) + return m.GenOn[g, t].indicator_var.implies( + pyo.lor(m.GenOn[g, t - 1].indicator_var, m.GenStartup[g, t - 1].indicator_var) + ) + + +model.onState = pyo.LogicalConstraint(model.GENERATORS, model.TIME, rule=onState) + def startupState(m, g, t): if t == m.TIME.first(): return pyo.LogicalConstraint.Skip - return m.GenStartup[g, t].indicator_var.implies( - m.GenOff[g, t-1].indicator_var) + return m.GenStartup[g, t].indicator_var.implies(m.GenOff[g, t - 1].indicator_var) + + model.startupState = pyo.LogicalConstraint( - model.GENERATORS, model.TIME, rule=startupState) + model.GENERATORS, model.TIME, rule=startupState +) # @:logic # @@ -83,6 +98,7 @@ def startupState(m, g, t): def obj(m): return sum(m.Power[g, t] for g in m.GENERATORS for t in m.TIME) + @model.Constraint(model.GENERATORS) def nontrivial(m, g): - return sum(m.Power[g, t] for t in m.TIME) >= len(m.TIME)/2 * m.MinPower[g] + return sum(m.Power[g, t] for t in m.TIME) >= len(m.TIME) / 2 * m.MinPower[g] diff --git a/examples/pyomobook/gdp-ch/scont.py b/examples/pyomobook/gdp-ch/scont.py index 82ca4051985..b5b2dca55f7 100644 --- a/examples/pyomobook/gdp-ch/scont.py +++ b/examples/pyomobook/gdp-ch/scont.py @@ -2,35 +2,41 @@ import pyomo.environ as pyo from pyomo.gdp import Disjunct, Disjunction -L = [1,2,3] -U = [2,4,6] -index = [0,1,2] +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)) +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) + def D_rule(m, k): return [m.d_0[k], m.d_nonzero[k]] + + model.D = Disjunction(index, rule=D_rule) # Minimize the number of x variables that are nonzero -model.o = pyo.Objective( - expr=sum(model.x_nonzero[k] for k in index)) +model.o = pyo.Objective(expr=sum(model.x_nonzero[k] for k in index)) # Satisfy a demand that is met by these variables -model.c = pyo.Constraint( - expr=sum(model.x[k] for k in index) >= 7) +model.c = pyo.Constraint(expr=sum(model.x[k] for k in index) >= 7) diff --git a/examples/pyomobook/gdp-ch/scont2.py b/examples/pyomobook/gdp-ch/scont2.py index 9ec593a9a7a..e4af27badac 100644 --- a/examples/pyomobook/gdp-ch/scont2.py +++ b/examples/pyomobook/gdp-ch/scont2.py @@ -1,11 +1,14 @@ import pyomo.environ as pyo import scont + model = scont.model # @action: def transform_gdp(m): - xfrm = pyo.TransformationFactory('gdp.bigm') - xfrm.apply_to(m) + xfrm = pyo.TransformationFactory('gdp.bigm') + xfrm.apply_to(m) + + model.transform_gdp = pyo.BuildAction(rule=transform_gdp) # @:action diff --git a/examples/pyomobook/gdp-ch/scont_script.py b/examples/pyomobook/gdp-ch/scont_script.py index 89b6c70b5dc..22c9b88ad0c 100644 --- a/examples/pyomobook/gdp-ch/scont_script.py +++ b/examples/pyomobook/gdp-ch/scont_script.py @@ -13,4 +13,5 @@ print(status) import verify_scont + verify_scont.verify_model(model) diff --git a/examples/pyomobook/gdp-ch/verify_scont.py b/examples/pyomobook/gdp-ch/verify_scont.py index 07e0202f931..db44024fe66 100644 --- a/examples/pyomobook/gdp-ch/verify_scont.py +++ b/examples/pyomobook/gdp-ch/verify_scont.py @@ -1,33 +1,39 @@ import os + def verify(obj, x, iv): assert obj == 2 for i in range(3): - assert sorted([iv[i,0],iv[i,1]]) == [0,1] - assert iv[i,0] == (0 if x[i] else 1) - assert iv[i,1] == (1 if x[i] else 0) + assert sorted([iv[i, 0], iv[i, 1]]) == [0, 1] + assert iv[i, 0] == (0 if x[i] else 1) + assert iv[i, 1] == (1 if x[i] else 0) assert sum(x.values()) >= 7 fname = os.path.basename(__file__) if fname.endswith('.pyc'): fname = fname[:-1] print("%s: OK: result validated" % (fname,)) + def verify_file(fname): import yaml - ans = yaml.load(open(fname,'r'), Loader=yaml.FullLoader) + + ans = yaml.load(open(fname, 'r'), Loader=yaml.FullLoader) assert ans['Solution'][0]['number of solutions'] == 1 obj = ans['Solution'][1]['Objective']['o']['Value'] - ZERO={'Value':0} + ZERO = {'Value': 0} x = {} iv = {} for i in range(3): - x[i] = ans['Solution'][1]['Variable'].get('x[%s]'%i, ZERO)['Value'] - iv[i,0] = ans['Solution'][1]['Variable'].get( - 'd_0[%s].binary_indicator_var'%i, ZERO)['Value'] - iv[i,1] = ans['Solution'][1]['Variable'].get( - 'd_nonzero[%s].binary_indicator_var'%i, ZERO)['Value'] + x[i] = ans['Solution'][1]['Variable'].get('x[%s]' % i, ZERO)['Value'] + iv[i, 0] = ans['Solution'][1]['Variable'].get( + 'd_0[%s].binary_indicator_var' % i, ZERO + )['Value'] + iv[i, 1] = ans['Solution'][1]['Variable'].get( + 'd_nonzero[%s].binary_indicator_var' % i, ZERO + )['Value'] verify(obj, x, iv) + def verify_model(model): assert len(model.solutions) == 1 obj = model.o() @@ -35,10 +41,12 @@ def verify_model(model): iv = {} for i in range(3): x[i] = model.x[i]() - iv[i,0] = model.d_0[i].binary_indicator_var() - iv[i,1] = model.d_nonzero[i].binary_indicator_var() + iv[i, 0] = model.d_0[i].binary_indicator_var() + iv[i, 1] = model.d_nonzero[i].binary_indicator_var() verify(obj, x, iv) + if __name__ == '__main__': import sys + verify_file(sys.argv[1]) diff --git a/examples/pyomobook/intro-ch/abstract5.py b/examples/pyomobook/intro-ch/abstract5.py index cd3a6f60370..2184ed7b3aa 100644 --- a/examples/pyomobook/intro-ch/abstract5.py +++ b/examples/pyomobook/intro-ch/abstract5.py @@ -10,11 +10,16 @@ model.x = pyo.Var(model.N, within=pyo.NonNegativeReals) + def obj_rule(model): - return sum(model.c[i]*model.x[i] for i in model.N) + return sum(model.c[i] * model.x[i] for i in model.N) + + model.obj = pyo.Objective(rule=obj_rule) + def con_rule(model, m): - return sum(model.a[m,i]*model.x[i] for i in model.N) \ - >= model.b[m] + return sum(model.a[m, i] * model.x[i] for i in model.N) >= model.b[m] + + model.con = pyo.Constraint(model.M, rule=con_rule) diff --git a/examples/pyomobook/intro-ch/coloring_concrete.py b/examples/pyomobook/intro-ch/coloring_concrete.py index c08471c6e17..107a31668c4 100644 --- a/examples/pyomobook/intro-ch/coloring_concrete.py +++ b/examples/pyomobook/intro-ch/coloring_concrete.py @@ -7,21 +7,42 @@ # # Define data for the graph of interest. -vertices = set(['Ar', 'Bo', 'Br', 'Ch', 'Co', 'Ec', - 'FG', 'Gu', 'Pa', 'Pe', 'Su', 'Ur', 'Ve']) - -edges = set([('FG','Su'), ('FG','Br'), ('Su','Gu'), - ('Su','Br'), ('Gu','Ve'), ('Gu','Br'), - ('Ve','Co'), ('Ve','Br'), ('Co','Ec'), - ('Co','Pe'), ('Co','Br'), ('Ec','Pe'), - ('Pe','Ch'), ('Pe','Bo'), ('Pe','Br'), - ('Ch','Ar'), ('Ch','Bo'), ('Ar','Ur'), - ('Ar','Br'), ('Ar','Pa'), ('Ar','Bo'), - ('Ur','Br'), ('Bo','Pa'), ('Bo','Br'), - ('Pa','Br')]) +vertices = set( + ['Ar', 'Bo', 'Br', 'Ch', 'Co', 'Ec', 'FG', 'Gu', 'Pa', 'Pe', 'Su', 'Ur', 'Ve'] +) + +edges = set( + [ + ('FG', 'Su'), + ('FG', 'Br'), + ('Su', 'Gu'), + ('Su', 'Br'), + ('Gu', 'Ve'), + ('Gu', 'Br'), + ('Ve', 'Co'), + ('Ve', 'Br'), + ('Co', 'Ec'), + ('Co', 'Pe'), + ('Co', 'Br'), + ('Ec', 'Pe'), + ('Pe', 'Ch'), + ('Pe', 'Bo'), + ('Pe', 'Br'), + ('Ch', 'Ar'), + ('Ch', 'Bo'), + ('Ar', 'Ur'), + ('Ar', 'Br'), + ('Ar', 'Pa'), + ('Ar', 'Bo'), + ('Ur', 'Br'), + ('Bo', 'Pa'), + ('Bo', 'Br'), + ('Pa', 'Br'), + ] +) ncolors = 4 -colors = range(1, ncolors+1) +colors = range(1, ncolors + 1) # Python import statement @@ -37,23 +58,20 @@ # Each node is colored with one color model.node_coloring = pyo.ConstraintList() for v in vertices: - model.node_coloring.add( - sum(model.x[v,c] for c in colors) == 1) + model.node_coloring.add(sum(model.x[v, c] for c in colors) == 1) # Nodes that share an edge cannot be colored the same model.edge_coloring = pyo.ConstraintList() -for v,w in edges: +for v, w in edges: for c in colors: - model.edge_coloring.add( - model.x[v,c] + model.x[w,c] <= 1) + model.edge_coloring.add(model.x[v, c] + model.x[w, c] <= 1) # Provide a lower bound on the minimum number of colors # that are needed model.min_coloring = pyo.ConstraintList() for v in vertices: for c in colors: - model.min_coloring.add( - model.y >= c * model.x[v,c]) + model.min_coloring.add(model.y >= c * model.x[v, c]) # Minimize the number of colors that are needed model.obj = pyo.Objective(expr=model.y) diff --git a/examples/pyomobook/intro-ch/concrete1.py b/examples/pyomobook/intro-ch/concrete1.py index eaf190f38bb..a39ca1d41cd 100644 --- a/examples/pyomobook/intro-ch/concrete1.py +++ b/examples/pyomobook/intro-ch/concrete1.py @@ -3,6 +3,6 @@ model = pyo.ConcreteModel() model.x_1 = pyo.Var(within=pyo.NonNegativeReals) model.x_2 = pyo.Var(within=pyo.NonNegativeReals) -model.obj = pyo.Objective(expr=model.x_1 + 2*model.x_2) -model.con1 = pyo.Constraint(expr=3*model.x_1 + 4*model.x_2 >= 1) -model.con2 = pyo.Constraint(expr=2*model.x_1 + 5*model.x_2 >= 2) +model.obj = pyo.Objective(expr=model.x_1 + 2 * model.x_2) +model.con1 = pyo.Constraint(expr=3 * model.x_1 + 4 * model.x_2 >= 1) +model.con2 = pyo.Constraint(expr=2 * model.x_1 + 5 * model.x_2 >= 2) diff --git a/examples/pyomobook/intro-ch/concrete1_generic.py b/examples/pyomobook/intro-ch/concrete1_generic.py index 712d218b854..de648470469 100644 --- a/examples/pyomobook/intro-ch/concrete1_generic.py +++ b/examples/pyomobook/intro-ch/concrete1_generic.py @@ -5,11 +5,16 @@ model.x = pyo.Var(mydata.N, within=pyo.NonNegativeReals) + def obj_rule(model): - return sum(mydata.c[i]*model.x[i] for i in mydata.N) + return sum(mydata.c[i] * model.x[i] for i in mydata.N) + + model.obj = pyo.Objective(rule=obj_rule) + def con_rule(model, m): - return sum(mydata.a[m,i]*model.x[i] for i in mydata.N) \ - >= mydata.b[m] + return sum(mydata.a[m, i] * model.x[i] for i in mydata.N) >= mydata.b[m] + + model.con = pyo.Constraint(mydata.M, rule=con_rule) diff --git a/examples/pyomobook/intro-ch/mydata.py b/examples/pyomobook/intro-ch/mydata.py index 9a001ced84e..83aa26bacd9 100644 --- a/examples/pyomobook/intro-ch/mydata.py +++ b/examples/pyomobook/intro-ch/mydata.py @@ -1,5 +1,5 @@ -N = [1,2] -M = [1,2] -c = {1:1, 2:2} -a = {(1,1):3, (1,2):4, (2,1):2, (2,2):5} -b = {1:1, 2:2} +N = [1, 2] +M = [1, 2] +c = {1: 1, 2: 2} +a = {(1, 1): 3, (1, 2): 4, (2, 1): 2, (2, 2): 5} +b = {1: 1, 2: 2} diff --git a/examples/pyomobook/mpec-ch/ex1a.py b/examples/pyomobook/mpec-ch/ex1a.py index cec5cc539f9..30cd2842556 100644 --- a/examples/pyomobook/mpec-ch/ex1a.py +++ b/examples/pyomobook/mpec-ch/ex1a.py @@ -6,11 +6,13 @@ model = pyo.ConcreteModel() -model.x = pyo.Var( range(1,n+1) ) +model.x = pyo.Var(range(1, n + 1)) + +model.f = pyo.Objective(expr=sum(i * (model.x[i] - 1) ** 2 for i in range(1, n + 1))) -model.f = pyo.Objective(expr=sum(i*(model.x[i]-1)**2 - for i in range(1,n+1)) ) def compl_(model, i): - return complements(model.x[i] >= 0, model.x[i+1] >= 0) -model.compl = Complementarity( range(1,n), rule=compl_ ) + return complements(model.x[i] >= 0, model.x[i + 1] >= 0) + + +model.compl = Complementarity(range(1, n), rule=compl_) diff --git a/examples/pyomobook/mpec-ch/ex1b.py b/examples/pyomobook/mpec-ch/ex1b.py index 8ae412ce5bd..9592c81c4f6 100644 --- a/examples/pyomobook/mpec-ch/ex1b.py +++ b/examples/pyomobook/mpec-ch/ex1b.py @@ -6,13 +6,12 @@ model = pyo.ConcreteModel() -model.x = pyo.Var( range(1,n+1) ) +model.x = pyo.Var(range(1, n + 1)) -model.f = pyo.Objective(expr=sum(i*(model.x[i]-1)**2 - for i in range(1,n+1)) ) +model.f = pyo.Objective(expr=sum(i * (model.x[i] - 1) ** 2 for i in range(1, n + 1))) model.compl = ComplementarityList() -model.compl.add(complements(model.x[1]>=0, model.x[2]>=0)) -model.compl.add(complements(model.x[2]>=0, model.x[3]>=0)) -model.compl.add(complements(model.x[3]>=0, model.x[4]>=0)) -model.compl.add(complements(model.x[4]>=0, model.x[5]>=0)) +model.compl.add(complements(model.x[1] >= 0, model.x[2] >= 0)) +model.compl.add(complements(model.x[2] >= 0, model.x[3] >= 0)) +model.compl.add(complements(model.x[3] >= 0, model.x[4] >= 0)) +model.compl.add(complements(model.x[4] >= 0, model.x[5] >= 0)) diff --git a/examples/pyomobook/mpec-ch/ex1c.py b/examples/pyomobook/mpec-ch/ex1c.py index f255f13aa08..aad9c9b0d47 100644 --- a/examples/pyomobook/mpec-ch/ex1c.py +++ b/examples/pyomobook/mpec-ch/ex1c.py @@ -6,14 +6,16 @@ model = pyo.ConcreteModel() -model.x = pyo.Var( range(1,n+1) ) +model.x = pyo.Var(range(1, n + 1)) + +model.f = pyo.Objective(expr=sum(i * (model.x[i] - 1) ** 2 for i in range(1, n + 1))) -model.f = pyo.Objective(expr=sum(i*(model.x[i]-1)**2 - for i in range(1,n+1)) ) def compl_(model): yield complements(model.x[1] >= 0, model.x[2] >= 0) yield complements(model.x[2] >= 0, model.x[3] >= 0) yield complements(model.x[3] >= 0, model.x[4] >= 0) yield complements(model.x[4] >= 0, model.x[5] >= 0) -model.compl = ComplementarityList( rule=compl_ ) + + +model.compl = ComplementarityList(rule=compl_) diff --git a/examples/pyomobook/mpec-ch/ex1d.py b/examples/pyomobook/mpec-ch/ex1d.py index 7607513e18f..fa5247ff831 100644 --- a/examples/pyomobook/mpec-ch/ex1d.py +++ b/examples/pyomobook/mpec-ch/ex1d.py @@ -6,13 +6,15 @@ model = pyo.ConcreteModel() -model.x = pyo.Var( range(1,n+1) ) +model.x = pyo.Var(range(1, n + 1)) + +model.f = pyo.Objective(expr=sum(i * (model.x[i] - 1) ** 2 for i in range(1, n + 1))) -model.f = pyo.Objective(expr=sum(i*(model.x[i]-1)**2 - for i in range(1,n+1)) ) def compl_(model, i): if i == n: return Complementarity.Skip - return complements(model.x[i] >= 0, model.x[i+1] >= 0) -model.compl = Complementarity( range(1,n+1), rule=compl_ ) + return complements(model.x[i] >= 0, model.x[i + 1] >= 0) + + +model.compl = Complementarity(range(1, n + 1), rule=compl_) diff --git a/examples/pyomobook/mpec-ch/ex1e.py b/examples/pyomobook/mpec-ch/ex1e.py index 9d3ffcc5487..bf714411396 100644 --- a/examples/pyomobook/mpec-ch/ex1e.py +++ b/examples/pyomobook/mpec-ch/ex1e.py @@ -6,11 +6,10 @@ model = pyo.ConcreteModel() -model.x = pyo.Var( range(1,n+1) ) +model.x = pyo.Var(range(1, n + 1)) -model.f = pyo.Objective(expr=sum(i*(model.x[i]-1)**2 - for i in range(1,n+1)) ) +model.f = pyo.Objective(expr=sum(i * (model.x[i] - 1) ** 2 for i in range(1, n + 1))) model.compl = ComplementarityList( - rule=(complements(model.x[i] >= 0, model.x[i+1] >= 0) - for i in range(1,n)) ) + rule=(complements(model.x[i] >= 0, model.x[i + 1] >= 0) for i in range(1, n)) +) diff --git a/examples/pyomobook/mpec-ch/ex2.py b/examples/pyomobook/mpec-ch/ex2.py index 93919398b2c..c192ccc7a34 100644 --- a/examples/pyomobook/mpec-ch/ex2.py +++ b/examples/pyomobook/mpec-ch/ex2.py @@ -8,11 +8,9 @@ model.x = pyo.Var(within=pyo.NonNegativeReals) model.y = pyo.Var(within=pyo.NonNegativeReals) -model.f1 = pyo.Objective(expr=2*model.x - model.y) +model.f1 = pyo.Objective(expr=2 * model.x - model.y) -model.compl = Complementarity( - expr=complements(0 <= model.y, - model.y >= model.x)) +model.compl = Complementarity(expr=complements(0 <= model.y, model.y >= model.x)) # @transform: xfrm = pyo.TransformationFactory("mpec.simple_nonlinear") diff --git a/examples/pyomobook/mpec-ch/munson1.py b/examples/pyomobook/mpec-ch/munson1.py index 3287a8269c1..c7d171eb416 100644 --- a/examples/pyomobook/mpec-ch/munson1.py +++ b/examples/pyomobook/mpec-ch/munson1.py @@ -9,14 +9,10 @@ model.x2 = pyo.Var() model.x3 = pyo.Var() -model.f1 = Complementarity(expr=complements( - model.x1 >= 0, - model.x1 + 2*model.x2 + 3*model.x3 >= 1)) +model.f1 = Complementarity( + expr=complements(model.x1 >= 0, model.x1 + 2 * model.x2 + 3 * model.x3 >= 1) +) -model.f2 = Complementarity(expr=complements( - model.x2 >= 0, - model.x2 - model.x3 >= -1)) +model.f2 = Complementarity(expr=complements(model.x2 >= 0, model.x2 - model.x3 >= -1)) -model.f3 = Complementarity(expr=complements( - model.x3 >= 0, - model.x1 + model.x2 >= -1)) +model.f3 = Complementarity(expr=complements(model.x3 >= 0, model.x1 + model.x2 >= -1)) diff --git a/examples/pyomobook/mpec-ch/ralph1.py b/examples/pyomobook/mpec-ch/ralph1.py index 121b08b5d9c..1d44a303b84 100644 --- a/examples/pyomobook/mpec-ch/ralph1.py +++ b/examples/pyomobook/mpec-ch/ralph1.py @@ -4,11 +4,9 @@ model = pyo.ConcreteModel() -model.x = pyo.Var( within=pyo.NonNegativeReals ) -model.y = pyo.Var( within=pyo.NonNegativeReals ) +model.x = pyo.Var(within=pyo.NonNegativeReals) +model.y = pyo.Var(within=pyo.NonNegativeReals) -model.f1 = pyo.Objective( expr=2*model.x - model.y ) +model.f1 = pyo.Objective(expr=2 * model.x - model.y) -model.compl = Complementarity( - expr=complements(0 <= model.y, - model.y >= model.x) ) +model.compl = Complementarity(expr=complements(0 <= model.y, model.y >= model.x)) diff --git a/examples/pyomobook/nonlinear-ch/deer/DeerProblem.py b/examples/pyomobook/nonlinear-ch/deer/DeerProblem.py index 6841e3b81b5..c076a7f4687 100644 --- a/examples/pyomobook/nonlinear-ch/deer/DeerProblem.py +++ b/examples/pyomobook/nonlinear-ch/deer/DeerProblem.py @@ -3,24 +3,24 @@ model = pyo.AbstractModel() -model.p1 = pyo.Param(); -model.p2 = pyo.Param(); -model.p3 = pyo.Param(); -model.p4 = pyo.Param(); -model.p5 = pyo.Param(); -model.p6 = pyo.Param(); -model.p7 = pyo.Param(); -model.p8 = pyo.Param(); -model.p9 = pyo.Param(); -model.ps = pyo.Param(); - -model.f = pyo.Var(initialize = 20, within=pyo.PositiveReals) -model.d = pyo.Var(initialize = 20, within=pyo.PositiveReals) -model.b = pyo.Var(initialize = 20, within=pyo.PositiveReals) - -model.hf = pyo.Var(initialize = 20, within=pyo.PositiveReals) -model.hd = pyo.Var(initialize = 20, within=pyo.PositiveReals) -model.hb = pyo.Var(initialize = 20, within=pyo.PositiveReals) +model.p1 = pyo.Param() +model.p2 = pyo.Param() +model.p3 = pyo.Param() +model.p4 = pyo.Param() +model.p5 = pyo.Param() +model.p6 = pyo.Param() +model.p7 = pyo.Param() +model.p8 = pyo.Param() +model.p9 = pyo.Param() +model.ps = pyo.Param() + +model.f = pyo.Var(initialize=20, within=pyo.PositiveReals) +model.d = pyo.Var(initialize=20, within=pyo.PositiveReals) +model.b = pyo.Var(initialize=20, within=pyo.PositiveReals) + +model.hf = pyo.Var(initialize=20, within=pyo.PositiveReals) +model.hd = pyo.Var(initialize=20, within=pyo.PositiveReals) +model.hb = pyo.Var(initialize=20, within=pyo.PositiveReals) model.br = pyo.Var(initialize=1.5, within=pyo.PositiveReals) @@ -28,35 +28,58 @@ def obj_rule(m): - return 10*m.hb + m.hd + m.hf + return 10 * m.hb + m.hd + m.hf + + model.obj = pyo.Objective(rule=obj_rule, sense=pyo.maximize) + def f_bal_rule(m): - return m.f == m.p1*m.br*(m.p2/10.0*m.f + m.p3*m.d) - m.hf + return m.f == m.p1 * m.br * (m.p2 / 10.0 * m.f + m.p3 * m.d) - m.hf + + model.f_bal = pyo.Constraint(rule=f_bal_rule) + def d_bal_rule(m): - return m.d == m.p4*m.d + m.p5/2.0*m.f - m.hd + return m.d == m.p4 * m.d + m.p5 / 2.0 * m.f - m.hd + + model.d_bal = pyo.Constraint(rule=d_bal_rule) + def b_bal_rule(m): - return m.b == m.p6*m.b + m.p5/2.0*m.f - m.hb + return m.b == m.p6 * m.b + m.p5 / 2.0 * m.f - m.hb + + model.b_bal = pyo.Constraint(rule=b_bal_rule) + def food_cons_rule(m): - return m.c == m.p7*m.b + m.p8*m.d + m.p9*m.f + return m.c == m.p7 * m.b + m.p8 * m.d + m.p9 * m.f + + model.food_cons = pyo.Constraint(rule=food_cons_rule) + def supply_rule(m): return m.c <= m.ps + + model.supply = pyo.Constraint(rule=supply_rule) + def birth_rule(m): - return m.br == 1.1 + 0.8*(m.ps - m.c)/m.ps + return m.br == 1.1 + 0.8 * (m.ps - m.c) / m.ps + + model.birth = pyo.Constraint(rule=birth_rule) + def minbuck_rule(m): - return m.b >= 1.0/5.0*(0.4*m.f + m.d) + return m.b >= 1.0 / 5.0 * (0.4 * m.f + m.d) + + model.minbuck = pyo.Constraint(rule=minbuck_rule) # create the ConcreteModel @@ -65,4 +88,3 @@ def minbuck_rule(m): pyo.assert_optimal_termination(status) instance.pprint() - diff --git a/examples/pyomobook/nonlinear-ch/disease_est/disease_estimation.py b/examples/pyomobook/nonlinear-ch/disease_est/disease_estimation.py index 6ea87cc069b..4eb859dc349 100644 --- a/examples/pyomobook/nonlinear-ch/disease_est/disease_estimation.py +++ b/examples/pyomobook/nonlinear-ch/disease_est/disease_estimation.py @@ -8,31 +8,46 @@ model.P_REP_CASES = pyo.Param(model.S_SI) model.P_POP = pyo.Param() -model.I = pyo.Var(model.S_SI, bounds=(0,model.P_POP), initialize=1) -model.S = pyo.Var(model.S_SI, bounds=(0,model.P_POP), initialize=300) +model.I = pyo.Var(model.S_SI, bounds=(0, model.P_POP), initialize=1) +model.S = pyo.Var(model.S_SI, bounds=(0, model.P_POP), initialize=300) model.beta = pyo.Var(bounds=(0.05, 70)) model.alpha = pyo.Var(bounds=(0.5, 1.5)) model.eps_I = pyo.Var(model.S_SI, initialize=0.0) + def _objective(model): - return sum((model.eps_I[i])**2 for i in model.S_SI) + return sum((model.eps_I[i]) ** 2 for i in model.S_SI) + + model.objective = pyo.Objective(rule=_objective, sense=pyo.minimize) + def _InfDynamics(model, i): if i != 1: - return model.I[i] == (model.beta * model.S[i-1] * model.I[i-1]**model.alpha)/model.P_POP + return ( + model.I[i] + == (model.beta * model.S[i - 1] * model.I[i - 1] ** model.alpha) + / model.P_POP + ) return pyo.Constraint.Skip + model.InfDynamics = pyo.Constraint(model.S_SI, rule=_InfDynamics) + def _SusDynamics(model, i): if i != 1: - return model.S[i] == model.S[i-1] - model.I[i] + return model.S[i] == model.S[i - 1] - model.I[i] return pyo.Constraint.Skip + + model.SusDynamics = pyo.Constraint(model.S_SI, rule=_SusDynamics) + def _Data(model, i): - return model.P_REP_CASES[i] == model.I[i]+model.eps_I[i] + return model.P_REP_CASES[i] == model.I[i] + model.eps_I[i] + + model.Data = pyo.Constraint(model.S_SI, rule=_Data) # create the ConcreteModel diff --git a/examples/pyomobook/nonlinear-ch/multimodal/multimodal_init1.py b/examples/pyomobook/nonlinear-ch/multimodal/multimodal_init1.py index 896828ed785..c435cafc3d5 100644 --- a/examples/pyomobook/nonlinear-ch/multimodal/multimodal_init1.py +++ b/examples/pyomobook/nonlinear-ch/multimodal/multimodal_init1.py @@ -3,11 +3,14 @@ from math import pi model = pyo.ConcreteModel() -model.x = pyo.Var(initialize = 0.25, bounds=(0,4)) -model.y = pyo.Var(initialize = 0.25, bounds=(0,4)) +model.x = pyo.Var(initialize=0.25, bounds=(0, 4)) +model.y = pyo.Var(initialize=0.25, bounds=(0, 4)) + def multimodal(m): - return (2-pyo.cos(pi*m.x)-pyo.cos(pi*m.y)) * (m.x**2) * (m.y**2) + return (2 - pyo.cos(pi * m.x) - pyo.cos(pi * m.y)) * (m.x**2) * (m.y**2) + + model.obj = pyo.Objective(rule=multimodal, sense=pyo.minimize) status = pyo.SolverFactory('ipopt').solve(model) diff --git a/examples/pyomobook/nonlinear-ch/multimodal/multimodal_init2.py b/examples/pyomobook/nonlinear-ch/multimodal/multimodal_init2.py index f3fecdc22b2..aa0dbae1e66 100644 --- a/examples/pyomobook/nonlinear-ch/multimodal/multimodal_init2.py +++ b/examples/pyomobook/nonlinear-ch/multimodal/multimodal_init2.py @@ -3,12 +3,15 @@ model = pyo.ConcreteModel() # @init: -model.x = pyo.Var(initialize = 2.1, bounds=(0,4)) -model.y = pyo.Var(initialize = 2.1, bounds=(0,4)) +model.x = pyo.Var(initialize=2.1, bounds=(0, 4)) +model.y = pyo.Var(initialize=2.1, bounds=(0, 4)) # @:init + def multimodal(m): - return (2-pyo.cos(pi*m.x)-pyo.cos(pi*m.y)) * (m.x**2) * (m.y**2) + return (2 - pyo.cos(pi * m.x) - pyo.cos(pi * m.y)) * (m.x**2) * (m.y**2) + + model.obj = pyo.Objective(rule=multimodal, sense=pyo.minimize) status = pyo.SolverFactory('ipopt').solve(model) diff --git a/examples/pyomobook/nonlinear-ch/react_design/ReactorDesign.py b/examples/pyomobook/nonlinear-ch/react_design/ReactorDesign.py index 6b3eef5e519..814b4a5938e 100644 --- a/examples/pyomobook/nonlinear-ch/react_design/ReactorDesign.py +++ b/examples/pyomobook/nonlinear-ch/react_design/ReactorDesign.py @@ -1,6 +1,7 @@ import pyomo.environ import pyomo.environ as pyo + def create_model(k1, k2, k3, caf): # create the concrete model model = pyo.ConcreteModel() @@ -13,30 +14,38 @@ def create_model(k1, k2, k3, caf): model.cd = pyo.Var(initialize=1000.0, within=pyo.PositiveReals) # create the objective - model.obj = pyo.Objective(expr = model.cb, sense=pyo.maximize) + model.obj = pyo.Objective(expr=model.cb, sense=pyo.maximize) # create the constraints - model.ca_bal = pyo.Constraint(expr = (0 == model.sv * caf \ - - model.sv * model.ca - k1 * model.ca \ - - 2.0 * k3 * model.ca ** 2.0)) - - model.cb_bal = pyo.Constraint(expr=(0 == -model.sv * model.cb \ - + k1 * model.ca - k2 * model.cb)) - - model.cc_bal = pyo.Constraint(expr=(0 == -model.sv * model.cc \ - + k2 * model.cb)) - - model.cd_bal = pyo.Constraint(expr=(0 == -model.sv * model.cd \ - + k3 * model.ca ** 2.0)) + model.ca_bal = pyo.Constraint( + expr=( + 0 + == model.sv * caf + - model.sv * model.ca + - k1 * model.ca + - 2.0 * k3 * model.ca**2.0 + ) + ) + + model.cb_bal = pyo.Constraint( + expr=(0 == -model.sv * model.cb + k1 * model.ca - k2 * model.cb) + ) + + model.cc_bal = pyo.Constraint(expr=(0 == -model.sv * model.cc + k2 * model.cb)) + + model.cd_bal = pyo.Constraint( + expr=(0 == -model.sv * model.cd + k3 * model.ca**2.0) + ) return model -if __name__ =='__main__': + +if __name__ == '__main__': # solve a single instance of the problem - k1 = 5.0/6.0 # min^-1 - k2 = 5.0/3.0 # min^-1 - k3 = 1.0/6000.0 # m^3/(gmol min) - caf = 10000.0 # gmol/m^3 + k1 = 5.0 / 6.0 # min^-1 + k2 = 5.0 / 3.0 # min^-1 + k3 = 1.0 / 6000.0 # m^3/(gmol min) + caf = 10000.0 # gmol/m^3 m = create_model(k1, k2, k3, caf) status = pyo.SolverFactory('ipopt').solve(m) diff --git a/examples/pyomobook/nonlinear-ch/react_design/ReactorDesignTable.py b/examples/pyomobook/nonlinear-ch/react_design/ReactorDesignTable.py index 4c0d84754a8..a242c85fbc2 100644 --- a/examples/pyomobook/nonlinear-ch/react_design/ReactorDesignTable.py +++ b/examples/pyomobook/nonlinear-ch/react_design/ReactorDesignTable.py @@ -2,21 +2,20 @@ from ReactorDesign import create_model # set the data (native Python data) -k1 = 5.0/6.0 # min^-1 -k2 = 5.0/3.0 # min^-1 -k3 = 1.0/6000.0 # m^3/(gmol min) +k1 = 5.0 / 6.0 # min^-1 +k2 = 5.0 / 3.0 # min^-1 +k3 = 1.0 / 6000.0 # m^3/(gmol min) # solve the model for different values of caf and report results print('{:>10s}\t{:>10s}\t{:>10s}'.format('CAf', 'SV', 'CB')) -for cafi in range(1,11): - caf = cafi*1000.0 # gmol/m^3 +for cafi in range(1, 11): + caf = cafi * 1000.0 # gmol/m^3 # create the model with the new data # note, we could do this more efficiently with # mutable parameters m = create_model(k1, k2, k3, caf) - + # solve the problem status = pyo.SolverFactory('ipopt').solve(m) - print("{:10g}\t{:10g}\t{:10g}".\ - format(caf, pyo.value(m.sv), pyo.value(m.cb))) + print("{:10g}\t{:10g}\t{:10g}".format(caf, pyo.value(m.sv), pyo.value(m.cb))) diff --git a/examples/pyomobook/nonlinear-ch/rosen/rosenbrock.py b/examples/pyomobook/nonlinear-ch/rosen/rosenbrock.py index 4724f1be191..e1633e2df69 100644 --- a/examples/pyomobook/nonlinear-ch/rosen/rosenbrock.py +++ b/examples/pyomobook/nonlinear-ch/rosen/rosenbrock.py @@ -6,9 +6,11 @@ model.x = pyo.Var(initialize=1.5) model.y = pyo.Var(initialize=1.5) + def rosenbrock(model): - return (1.0 - model.x)**2 \ - + 100.0*(model.y - model.x**2)**2 + return (1.0 - model.x) ** 2 + 100.0 * (model.y - model.x**2) ** 2 + + model.obj = pyo.Objective(rule=rosenbrock, sense=pyo.minimize) status = pyo.SolverFactory('ipopt').solve(model) diff --git a/examples/pyomobook/optimization-ch/ConcHLinScript.py b/examples/pyomobook/optimization-ch/ConcHLinScript.py index 7095069ed48..8481a83afbf 100644 --- a/examples/pyomobook/optimization-ch/ConcHLinScript.py +++ b/examples/pyomobook/optimization-ch/ConcHLinScript.py @@ -1,24 +1,25 @@ # ConcHLinScript.py - Linear (H) as a script import pyomo.environ as pyo + def IC_model_linear(A, h, d, c, b, u): model = pyo.ConcreteModel(name="Linear (H)") def x_bounds(m, i): - return (0,u[i]) + return (0, u[i]) model.x = pyo.Var(A, bounds=x_bounds) def obj_rule(model): - return sum(h[i]*(1 - u[i]/d[i]**2) * model.x[i] for i in A) + return sum(h[i] * (1 - u[i] / d[i] ** 2) * model.x[i] for i in A) model.z = pyo.Objective(rule=obj_rule, sense=pyo.maximize) - model.budgetconstr = \ - pyo.Constraint(expr = sum(c[i] * model.x[i] for i in A) <= b) + model.budgetconstr = pyo.Constraint(expr=sum(c[i] * model.x[i] for i in A) <= b) return model + # Main script # @main: @@ -32,7 +33,7 @@ def obj_rule(model): model = IC_model_linear(A, h, d, c, b, u) opt = pyo.SolverFactory('glpk') -results = opt.solve(model) # solves and updates model +results = opt.solve(model) # solves and updates model pyo.assert_optimal_termination(results) model.display() diff --git a/examples/pyomobook/optimization-ch/ConcreteH.py b/examples/pyomobook/optimization-ch/ConcreteH.py index dfb08816d98..ddeabf59c3e 100644 --- a/examples/pyomobook/optimization-ch/ConcreteH.py +++ b/examples/pyomobook/optimization-ch/ConcreteH.py @@ -3,23 +3,26 @@ # @fct: import pyomo.environ as pyo + def IC_model(A, h, d, c, b, u): - model = pyo.ConcreteModel(name = "(H)") + model = pyo.ConcreteModel(name="(H)") def x_bounds(m, i): - return (0,u[i]) + return (0, u[i]) + model.x = pyo.Var(A, bounds=x_bounds) def z_rule(model): - return sum(h[i] * (model.x[i] - (model.x[i]/d[i])**2) - for i in A) + return sum(h[i] * (model.x[i] - (model.x[i] / d[i]) ** 2) for i in A) + model.z = pyo.Objective(rule=z_rule, sense=pyo.maximize) - model.budgetconstr = pyo.Constraint(\ - expr = sum(c[i]*model.x[i] for i in A) <= b) - + model.budgetconstr = pyo.Constraint(expr=sum(c[i] * model.x[i] for i in A) <= b) + return model + + # @:fct if __name__ == "__main__": diff --git a/examples/pyomobook/optimization-ch/ConcreteHLinear.py b/examples/pyomobook/optimization-ch/ConcreteHLinear.py index 8a4210ded07..4aadd59a3f6 100644 --- a/examples/pyomobook/optimization-ch/ConcreteHLinear.py +++ b/examples/pyomobook/optimization-ch/ConcreteHLinear.py @@ -10,18 +10,21 @@ b = 12 u = {'I_C_Scoops': 100, 'Peanuts': 40.6} + def x_bounds(m, i): - return (0,u[i]) + return (0, u[i]) + + model.x = pyo.Var(A, bounds=x_bounds) # @obj: def obj_rule(model): - return sum(h[i]*(1 - u[i]/d[i]**2) * model.x[i] \ - for i in A) + return sum(h[i] * (1 - u[i] / d[i] ** 2) * model.x[i] for i in A) + + # @:obj model.z = pyo.Objective(rule=obj_rule, sense=pyo.maximize) -model.budgetconstr = \ - pyo.Constraint(expr = sum(c[i]*model.x[i] for i in A) <= b) +model.budgetconstr = pyo.Constraint(expr=sum(c[i] * model.x[i] for i in A) <= b) model.pprint() diff --git a/examples/pyomobook/optimization-ch/IC_model_dict.py b/examples/pyomobook/optimization-ch/IC_model_dict.py index 17e5d2293e0..4c54ef83701 100644 --- a/examples/pyomobook/optimization-ch/IC_model_dict.py +++ b/examples/pyomobook/optimization-ch/IC_model_dict.py @@ -3,11 +3,12 @@ # @fct: import pyomo.environ as pyo + def IC_model_dict(ICD): # ICD is a dictionary with the data for the problem - model = pyo.ConcreteModel(name = "(H)") - + model = pyo.ConcreteModel(name="(H)") + model.A = pyo.Set(initialize=ICD["A"]) model.h = pyo.Param(model.A, initialize=ICD["h"]) @@ -18,20 +19,24 @@ def IC_model_dict(ICD): def xbounds_rule(model, i): return (0, model.u[i]) + model.x = pyo.Var(model.A, bounds=xbounds_rule) def obj_rule(model): - return sum(model.h[i] * \ - (model.x[i] - (model.x[i]/model.d[i])**2)\ - for i in model.A) - model.z = pyo.Objective(rule=obj_rule,sense=pyo.maximize) + return sum( + model.h[i] * (model.x[i] - (model.x[i] / model.d[i]) ** 2) for i in model.A + ) + + model.z = pyo.Objective(rule=obj_rule, sense=pyo.maximize) def budget_rule(model): - return sum(model.c[i]*model.x[i]\ - for i in model.A) <= model.b + return sum(model.c[i] * model.x[i] for i in model.A) <= model.b + model.budgetconstr = pyo.Constraint(rule=budget_rule) return model + + # @:fct if __name__ == "__main__": diff --git a/examples/pyomobook/overview-ch/var_obj_con_snippet.py b/examples/pyomobook/overview-ch/var_obj_con_snippet.py index 78cc0461c98..49bb7c1276b 100644 --- a/examples/pyomobook/overview-ch/var_obj_con_snippet.py +++ b/examples/pyomobook/overview-ch/var_obj_con_snippet.py @@ -3,7 +3,7 @@ model = pyo.ConcreteModel() # @body: model.x = pyo.Var() -model.y = pyo.Var(bounds=(-2,4)) +model.y = pyo.Var(bounds=(-2, 4)) model.z = pyo.Var(initialize=1.0, within=pyo.NonNegativeReals) model.obj = pyo.Objective(expr=model.x**2 + model.y + model.z) diff --git a/examples/pyomobook/overview-ch/wl_abstract.py b/examples/pyomobook/overview-ch/wl_abstract.py index 40b1729d696..067a06b57e0 100644 --- a/examples/pyomobook/overview-ch/wl_abstract.py +++ b/examples/pyomobook/overview-ch/wl_abstract.py @@ -7,28 +7,39 @@ model.M = pyo.Set() # @:setdecl # @paramdecl: -model.d = pyo.Param(model.N,model.M) +model.d = pyo.Param(model.N, model.M) model.P = pyo.Param() # @:paramdecl # @vardecl: -model.x = pyo.Var(model.N, model.M, bounds=(0,1)) +model.x = pyo.Var(model.N, model.M, bounds=(0, 1)) model.y = pyo.Var(model.N, within=pyo.Binary) # @:vardecl + def obj_rule(model): - return sum(model.d[n,m]*model.x[n,m] for n in model.N for m in model.M) + return sum(model.d[n, m] * model.x[n, m] for n in model.N for m in model.M) + + model.obj = pyo.Objective(rule=obj_rule) # @deliver: def one_per_cust_rule(model, m): - return sum(model.x[n,m] for n in model.N) == 1 + return sum(model.x[n, m] for n in model.N) == 1 + + model.one_per_cust = pyo.Constraint(model.M, rule=one_per_cust_rule) # @:deliver + def warehouse_active_rule(model, n, m): - return model.x[n,m] <= model.y[n] + return model.x[n, m] <= model.y[n] + + model.warehouse_active = pyo.Constraint(model.N, model.M, rule=warehouse_active_rule) + def num_warehouses_rule(model): return sum(model.y[n] for n in model.N) <= model.P + + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) diff --git a/examples/pyomobook/overview-ch/wl_abstract_script.py b/examples/pyomobook/overview-ch/wl_abstract_script.py index b070e01820b..0b042405714 100644 --- a/examples/pyomobook/overview-ch/wl_abstract_script.py +++ b/examples/pyomobook/overview-ch/wl_abstract_script.py @@ -6,26 +6,38 @@ model.N = pyo.Set() model.M = pyo.Set() -model.d = pyo.Param(model.N,model.M) +model.d = pyo.Param(model.N, model.M) model.P = pyo.Param() -model.x = pyo.Var(model.N, model.M, bounds=(0,1)) +model.x = pyo.Var(model.N, model.M, bounds=(0, 1)) model.y = pyo.Var(model.N, within=pyo.Binary) + def obj_rule(model): - return sum(model.d[n,m]*model.x[n,m] for n in model.N for m in model.M) + return sum(model.d[n, m] * model.x[n, m] for n in model.N for m in model.M) + + model.obj = pyo.Objective(rule=obj_rule) + def one_per_cust_rule(model, m): - return sum(model.x[n,m] for n in model.N) == 1 + return sum(model.x[n, m] for n in model.N) == 1 + + model.one_per_cust = pyo.Constraint(model.M, rule=one_per_cust_rule) + def warehouse_active_rule(model, n, m): - return model.x[n,m] <= model.y[n] + return model.x[n, m] <= model.y[n] + + model.warehouse_active = pyo.Constraint(model.N, model.M, rule=warehouse_active_rule) + def num_warehouses_rule(model): return sum(model.y[n] for n in model.N) <= model.P + + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) # @abstractsolve: diff --git a/examples/pyomobook/overview-ch/wl_concrete.py b/examples/pyomobook/overview-ch/wl_concrete.py index de3e76cd15c..29316304f0a 100644 --- a/examples/pyomobook/overview-ch/wl_concrete.py +++ b/examples/pyomobook/overview-ch/wl_concrete.py @@ -2,28 +2,33 @@ # ConcreteModel version of warehouse location problem import pyomo.environ as pyo + def create_warehouse_model(N, M, d, P): model = pyo.ConcreteModel(name="(WL)") - model.x = pyo.Var(N, M, bounds=(0,1)) + model.x = pyo.Var(N, M, bounds=(0, 1)) model.y = pyo.Var(N, within=pyo.Binary) def obj_rule(mdl): - return sum(d[n,m]*mdl.x[n,m] for n in N for m in M) + return sum(d[n, m] * mdl.x[n, m] for n in N for m in M) + model.obj = pyo.Objective(rule=obj_rule) -# @deliver: + # @deliver: def demand_rule(mdl, m): - return sum(mdl.x[n,m] for n in N) == 1 + return sum(mdl.x[n, m] for n in N) == 1 + model.demand = pyo.Constraint(M, rule=demand_rule) -# @:deliver + # @:deliver def warehouse_active_rule(mdl, n, m): - return mdl.x[n,m] <= mdl.y[n] + return mdl.x[n, m] <= mdl.y[n] + model.warehouse_active = pyo.Constraint(N, M, rule=warehouse_active_rule) def num_warehouses_rule(mdl): return sum(mdl.y[n] for n in N) <= P + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) return model diff --git a/examples/pyomobook/overview-ch/wl_concrete_script.py b/examples/pyomobook/overview-ch/wl_concrete_script.py index 8bf8b8e0669..278937f5aed 100644 --- a/examples/pyomobook/overview-ch/wl_concrete_script.py +++ b/examples/pyomobook/overview-ch/wl_concrete_script.py @@ -1,8 +1,8 @@ -# wl_concrete_script.py +# wl_concrete_script.py # Solve an instance of the warehouse location problem # Import Pyomo environment and model -import pyomo.environ as pyo +import pyomo.environ as pyo from wl_concrete import create_warehouse_model # Establish the data for this model (this could also be @@ -11,18 +11,20 @@ N = ['Harlingen', 'Memphis', 'Ashland'] M = ['NYC', 'LA', 'Chicago', 'Houston'] -d = {('Harlingen', 'NYC'): 1956, \ - ('Harlingen', 'LA'): 1606, \ - ('Harlingen', 'Chicago'): 1410, \ - ('Harlingen', 'Houston'): 330, \ - ('Memphis', 'NYC'): 1096, \ - ('Memphis', 'LA'): 1792, \ - ('Memphis', 'Chicago'): 531, \ - ('Memphis', 'Houston'): 567, \ - ('Ashland', 'NYC'): 485, \ - ('Ashland', 'LA'): 2322, \ - ('Ashland', 'Chicago'): 324, \ - ('Ashland', 'Houston'): 1236 } +d = { + ('Harlingen', 'NYC'): 1956, + ('Harlingen', 'LA'): 1606, + ('Harlingen', 'Chicago'): 1410, + ('Harlingen', 'Houston'): 330, + ('Memphis', 'NYC'): 1096, + ('Memphis', 'LA'): 1792, + ('Memphis', 'Chicago'): 531, + ('Memphis', 'Houston'): 567, + ('Ashland', 'NYC'): 485, + ('Ashland', 'LA'): 2322, + ('Ashland', 'Chicago'): 324, + ('Ashland', 'Houston'): 1236, +} P = 2 # Create the Pyomo model @@ -34,5 +36,5 @@ pyo.assert_optimal_termination(res) # @output: -model.y.pprint() # Print the optimal warehouse locations +model.y.pprint() # Print the optimal warehouse locations # @:output diff --git a/examples/pyomobook/overview-ch/wl_excel.py b/examples/pyomobook/overview-ch/wl_excel.py index 6183eb987c0..1c4ad997225 100644 --- a/examples/pyomobook/overview-ch/wl_excel.py +++ b/examples/pyomobook/overview-ch/wl_excel.py @@ -8,7 +8,7 @@ N = list(df.index.map(str)) M = list(df.columns.map(str)) -d = {(r, c):df.at[r,c] for r in N for c in M} +d = {(r, c): df.at[r, c] for r in N for c in M} P = 2 # create the Pyomo model @@ -19,5 +19,5 @@ solver.solve(model) # @output: -model.y.pprint() # print the optimal warehouse locations +model.y.pprint() # print the optimal warehouse locations # @:output diff --git a/examples/pyomobook/overview-ch/wl_list.py b/examples/pyomobook/overview-ch/wl_list.py index a419429a0f5..64db76be548 100644 --- a/examples/pyomobook/overview-ch/wl_list.py +++ b/examples/pyomobook/overview-ch/wl_list.py @@ -7,37 +7,39 @@ N = ['Harlingen', 'Memphis', 'Ashland'] M = ['NYC', 'LA', 'Chicago', 'Houston'] # @:data -d = {('Harlingen', 'NYC'): 1956, \ - ('Harlingen', 'LA'): 1606, \ - ('Harlingen', 'Chicago'): 1410, \ - ('Harlingen', 'Houston'): 330, \ - ('Memphis', 'NYC'): 1096, \ - ('Memphis', 'LA'): 1792, \ - ('Memphis', 'Chicago'): 531, \ - ('Memphis', 'Houston'): 567, \ - ('Ashland', 'NYC'): 485, \ - ('Ashland', 'LA'): 2322, \ - ('Ashland', 'Chicago'): 324, \ - ('Ashland', 'Houston'): 1236 } +d = { + ('Harlingen', 'NYC'): 1956, + ('Harlingen', 'LA'): 1606, + ('Harlingen', 'Chicago'): 1410, + ('Harlingen', 'Houston'): 330, + ('Memphis', 'NYC'): 1096, + ('Memphis', 'LA'): 1792, + ('Memphis', 'Chicago'): 531, + ('Memphis', 'Houston'): 567, + ('Ashland', 'NYC'): 485, + ('Ashland', 'LA'): 2322, + ('Ashland', 'Chicago'): 324, + ('Ashland', 'Houston'): 1236, +} P = 2 # @vars: -model.x = pyo.Var(N, M, bounds=(0,1)) +model.x = pyo.Var(N, M, bounds=(0, 1)) model.y = pyo.Var(N, within=pyo.Binary) # @:vars # @obj: -model.obj = pyo.Objective(expr=sum(d[n,m]*model.x[n,m] for n in N for m in M)) +model.obj = pyo.Objective(expr=sum(d[n, m] * model.x[n, m] for n in N for m in M)) # @:obj # @conslist: model.demand = pyo.ConstraintList() for m in M: - model.demand.add(sum(model.x[n,m] for n in N) == 1) + model.demand.add(sum(model.x[n, m] for n in N) == 1) model.warehouse_active = pyo.ConstraintList() for n in N: for m in M: - model.warehouse_active.add(model.x[n,m] <= model.y[n]) + model.warehouse_active.add(model.x[n, m] <= model.y[n]) # @:conslist # @scalarcon: diff --git a/examples/pyomobook/overview-ch/wl_mutable.py b/examples/pyomobook/overview-ch/wl_mutable.py index 281b46b7ab5..e5c4f5e9dbb 100644 --- a/examples/pyomobook/overview-ch/wl_mutable.py +++ b/examples/pyomobook/overview-ch/wl_mutable.py @@ -1,29 +1,34 @@ # wl_mutable.py: warehouse location problem with mutable param import pyomo.environ as pyo + def create_warehouse_model(N, M, d, P): model = pyo.ConcreteModel(name="(WL)") - model.x = pyo.Var(N, M, bounds=(0,1)) + model.x = pyo.Var(N, M, bounds=(0, 1)) model.y = pyo.Var(N, within=pyo.Binary) model.P = pyo.Param(initialize=P, mutable=True) def obj_rule(mdl): - return sum(d[n,m]*mdl.x[n,m] for n in N for m in M) + return sum(d[n, m] * mdl.x[n, m] for n in N for m in M) + model.obj = pyo.Objective(rule=obj_rule) -# @deliver: + # @deliver: def demand_rule(mdl, m): - return sum(mdl.x[n,m] for n in N) == 1 + return sum(mdl.x[n, m] for n in N) == 1 + model.demand = pyo.Constraint(M, rule=demand_rule) -# @:deliver + # @:deliver def warehouse_active_rule(mdl, n, m): - return mdl.x[n,m] <= mdl.y[n] + return mdl.x[n, m] <= mdl.y[n] + model.warehouse_active = pyo.Constraint(N, M, rule=warehouse_active_rule) def num_warehouses_rule(mdl): return sum(mdl.y[n] for n in N) <= mdl.P + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) return model diff --git a/examples/pyomobook/overview-ch/wl_mutable_excel.py b/examples/pyomobook/overview-ch/wl_mutable_excel.py index a1a27a0a1f4..0906fbb25b3 100644 --- a/examples/pyomobook/overview-ch/wl_mutable_excel.py +++ b/examples/pyomobook/overview-ch/wl_mutable_excel.py @@ -8,7 +8,7 @@ N = list(df.index.map(str)) M = list(df.columns.map(str)) -d = {(r, c):df.at[r,c] for r in N for c in M} +d = {(r, c): df.at[r, c] for r in N for c in M} P = 2 # create the Pyomo model @@ -18,10 +18,8 @@ solver = pyo.SolverFactory('glpk') # loop over values for mutable parameter P -for n in range(1,10): +for n in range(1, 10): model.P = n res = solver.solve(model) pyo.assert_optimal_termination(res) - print('# warehouses:', n, \ - 'delivery cost:', pyo.value(model.obj)) - + print('# warehouses:', n, 'delivery cost:', pyo.value(model.obj)) diff --git a/examples/pyomobook/overview-ch/wl_scalar.py b/examples/pyomobook/overview-ch/wl_scalar.py index 11aa3c3f13b..ac10fbe8265 100644 --- a/examples/pyomobook/overview-ch/wl_scalar.py +++ b/examples/pyomobook/overview-ch/wl_scalar.py @@ -4,35 +4,41 @@ model = pyo.ConcreteModel() # @vars: -model.x_Harlingen_NYC = pyo.Var(bounds=(0,1)) -model.x_Harlingen_LA = pyo.Var(bounds=(0,1)) -model.x_Harlingen_Chicago = pyo.Var(bounds=(0,1)) -model.x_Harlingen_Houston = pyo.Var(bounds=(0,1)) -model.x_Memphis_NYC = pyo.Var(bounds=(0,1)) -model.x_Memphis_LA = pyo.Var(bounds=(0,1)) -#... +model.x_Harlingen_NYC = pyo.Var(bounds=(0, 1)) +model.x_Harlingen_LA = pyo.Var(bounds=(0, 1)) +model.x_Harlingen_Chicago = pyo.Var(bounds=(0, 1)) +model.x_Harlingen_Houston = pyo.Var(bounds=(0, 1)) +model.x_Memphis_NYC = pyo.Var(bounds=(0, 1)) +model.x_Memphis_LA = pyo.Var(bounds=(0, 1)) +# ... # @:vars -model.x_Memphis_Chicago = pyo.Var(bounds=(0,1)) -model.x_Memphis_Houston = pyo.Var(bounds=(0,1)) -model.x_Ashland_NYC = pyo.Var(bounds=(0,1)) -model.x_Ashland_LA = pyo.Var(bounds=(0,1)) -model.x_Ashland_Chicago = pyo.Var(bounds=(0,1)) -model.x_Ashland_Houston = pyo.Var(bounds=(0,1)) +model.x_Memphis_Chicago = pyo.Var(bounds=(0, 1)) +model.x_Memphis_Houston = pyo.Var(bounds=(0, 1)) +model.x_Ashland_NYC = pyo.Var(bounds=(0, 1)) +model.x_Ashland_LA = pyo.Var(bounds=(0, 1)) +model.x_Ashland_Chicago = pyo.Var(bounds=(0, 1)) +model.x_Ashland_Houston = pyo.Var(bounds=(0, 1)) model.y_Harlingen = pyo.Var(within=pyo.Binary) -model.y_Memphis= pyo.Var(within=pyo.Binary) -model.y_Ashland= pyo.Var(within=pyo.Binary) +model.y_Memphis = pyo.Var(within=pyo.Binary) +model.y_Ashland = pyo.Var(within=pyo.Binary) P = 2 # @cons: -model.one_warehouse_for_NYC = pyo.Constraint(expr=model.x_Harlingen_NYC + model.x_Memphis_NYC + model.x_Ashland_NYC == 1) +model.one_warehouse_for_NYC = pyo.Constraint( + expr=model.x_Harlingen_NYC + model.x_Memphis_NYC + model.x_Ashland_NYC == 1 +) -model.one_warehouse_for_LA = pyo.Constraint(expr=model.x_Harlingen_LA + model.x_Memphis_LA + model.x_Ashland_LA == 1) -#... +model.one_warehouse_for_LA = pyo.Constraint( + expr=model.x_Harlingen_LA + model.x_Memphis_LA + model.x_Ashland_LA == 1 +) +# ... # @:cons # @maxY: -model.maxY = pyo.Constraint(expr=model.y_Harlingen + model.y_Memphis + model.y_Ashland <= P) +model.maxY = pyo.Constraint( + expr=model.y_Harlingen + model.y_Memphis + model.y_Ashland <= P +) # @:maxY model.pprint() diff --git a/examples/pyomobook/performance-ch/SparseSets.py b/examples/pyomobook/performance-ch/SparseSets.py index 0586feb9b5f..90d097b53aa 100644 --- a/examples/pyomobook/performance-ch/SparseSets.py +++ b/examples/pyomobook/performance-ch/SparseSets.py @@ -6,8 +6,11 @@ model.K = pyo.Set() model.V = pyo.Set(model.K) + def kv_init(m): - return ((k,v) for k in m.K for v in m.V[k]) + return ((k, v) for k in m.K for v in m.V[k]) + + model.KV = pyo.Set(dimen=2, initialize=kv_init) model.a = pyo.Param(model.I, model.K) @@ -18,6 +21,9 @@ def kv_init(m): # include a constraint that looks like this: # x[i,k,v] <= a[i,k]*y[i], for i in I, k in K, v in V[k] -def c1Rule(m,i,k,v): - return m.x[i,k,v] <= m.a[i,k]*m.y[i] + +def c1Rule(m, i, k, v): + return m.x[i, k, v] <= m.a[i, k] * m.y[i] + + model.c1 = pyo.Constraint(model.I, model.KV, rule=c1Rule) diff --git a/examples/pyomobook/performance-ch/lin_expr.py b/examples/pyomobook/performance-ch/lin_expr.py index 728b2678a58..75f4e70ec2a 100644 --- a/examples/pyomobook/performance-ch/lin_expr.py +++ b/examples/pyomobook/performance-ch/lin_expr.py @@ -12,7 +12,7 @@ timer.tic() for i in range(N2): - e = sum(i*m.x[i] for i in range(N1)) + e = sum(i * m.x[i] for i in range(N1)) timer.toc('created expression with sum function') for i in range(N2): diff --git a/examples/pyomobook/performance-ch/persistent.py b/examples/pyomobook/performance-ch/persistent.py index 70808272866..98207909cb6 100644 --- a/examples/pyomobook/performance-ch/persistent.py +++ b/examples/pyomobook/performance-ch/persistent.py @@ -1,10 +1,11 @@ # @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) +m.c = pyo.Constraint(expr=m.y >= -2 * m.x + 5) # @:model # @creation: @@ -44,7 +45,7 @@ m = pyo.ConcreteModel() m.x = pyo.Var() m.y = pyo.Var() -m.c = pyo.Constraint(expr=m.y >= -2*m.x + 5) +m.c = pyo.Constraint(expr=m.y >= -2 * m.x + 5) opt = pyo.SolverFactory('gurobi_persistent') opt.set_instance(m) # WRONG: @@ -57,7 +58,7 @@ m = pyo.ConcreteModel() m.x = pyo.Var() m.y = pyo.Var() -m.c = pyo.Constraint(expr=m.y >= -2*m.x + 5) +m.c = pyo.Constraint(expr=m.y >= -2 * m.x + 5) opt = pyo.SolverFactory('gurobi_persistent') opt.set_instance(m) # Correct: @@ -72,7 +73,7 @@ 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) +m.c = pyo.Constraint(expr=m.y >= -2 * m.x + 5) opt = pyo.SolverFactory('gurobi_persistent') opt.set_instance(m) m.x.setlb(1.0) @@ -95,7 +96,7 @@ 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) +m.c = pyo.Constraint(expr=m.y >= -2 * m.x + 5) opt = pyo.SolverFactory('gurobi_persistent') opt.set_instance(m) results = opt.solve(save_results=False) diff --git a/examples/pyomobook/performance-ch/wl.py b/examples/pyomobook/performance-ch/wl.py index 8175661e97d..1a5fd176e90 100644 --- a/examples/pyomobook/performance-ch/wl.py +++ b/examples/pyomobook/performance-ch/wl.py @@ -1,6 +1,6 @@ # wl.py # define a script to demonstrate performance profiling and improvements # @imports: -import pyomo.environ as pyo # import pyomo environment +import pyomo.environ as pyo # import pyomo environment import cProfile import pstats import io @@ -9,6 +9,7 @@ from pyomo.core.expr.numeric_expr import LinearExpression import matplotlib.pyplot as plt import numpy as np + np.random.seed(0) # @:imports @@ -17,36 +18,41 @@ def create_warehouse_model(num_locations=50, num_customers=50): N = list(range(num_locations)) # warehouse locations M = list(range(num_customers)) # customers - d = dict() # distances from warehouse locations to customers + d = dict() # distances from warehouse locations to customers for n in N: for m in M: d[n, m] = np.random.randint(low=1, high=100) max_num_warehouses = 2 model = pyo.ConcreteModel(name="(WL)") - model.P = pyo.Param(initialize=max_num_warehouses, - mutable=True) + model.P = pyo.Param(initialize=max_num_warehouses, mutable=True) model.x = pyo.Var(N, M, bounds=(0, 1)) model.y = pyo.Var(N, bounds=(0, 1)) def obj_rule(mdl): - return sum(d[n,m]*mdl.x[n,m] for n in N for m in M) + return sum(d[n, m] * mdl.x[n, m] for n in N for m in M) + model.obj = pyo.Objective(rule=obj_rule) def demand_rule(mdl, m): - return sum(mdl.x[n,m] for n in N) == 1 + return sum(mdl.x[n, m] for n in N) == 1 + model.demand = pyo.Constraint(M, rule=demand_rule) def warehouse_active_rule(mdl, n, m): - return mdl.x[n,m] <= mdl.y[n] + return mdl.x[n, m] <= mdl.y[n] + model.warehouse_active = pyo.Constraint(N, M, rule=warehouse_active_rule) def num_warehouses_rule(mdl): return sum(mdl.y[n] for n in N) <= model.P + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) return model + + # @:model_func # @model_linear_expr: @@ -54,7 +60,7 @@ def create_warehouse_linear_expr(num_locations=50, num_customers=50): N = list(range(num_locations)) # warehouse locations M = list(range(num_customers)) # customers - d = dict() # distances from warehouse locations to customers + d = dict() # distances from warehouse locations to customers for n in N: for m in M: d[n, m] = np.random.randint(low=1, high=100) @@ -63,27 +69,35 @@ def create_warehouse_linear_expr(num_locations=50, num_customers=50): model = pyo.ConcreteModel(name="(WL)") model.P = pyo.Param(initialize=max_num_warehouses, mutable=True) - model.x = pyo.Var(N, M, bounds=(0,1)) + model.x = pyo.Var(N, M, bounds=(0, 1)) model.y = pyo.Var(N, bounds=(0, 1)) def obj_rule(mdl): - return sum(d[n,m]*mdl.x[n,m] for n in N for m in M) + return sum(d[n, m] * mdl.x[n, m] for n in N for m in M) + model.obj = pyo.Objective(rule=obj_rule) def demand_rule(mdl, m): - return sum(mdl.x[n,m] for n in N) == 1 + return sum(mdl.x[n, m] for n in N) == 1 + model.demand = pyo.Constraint(M, rule=demand_rule) def warehouse_active_rule(mdl, n, m): - expr = LinearExpression(constant=0, linear_coefs=[1, -1], linear_vars=[mdl.x[n,m], mdl.y[n]]) + expr = LinearExpression( + constant=0, linear_coefs=[1, -1], linear_vars=[mdl.x[n, m], mdl.y[n]] + ) return expr <= 0 + model.warehouse_active = pyo.Constraint(N, M, rule=warehouse_active_rule) def num_warehouses_rule(mdl): return sum(mdl.y[n] for n in N) <= model.P + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) return model + + # @:model_linear_expr # @print_c_profiler: @@ -96,6 +110,8 @@ def print_c_profiler(pr, lines_to_print=15): stats = pstats.Stats(pr, stream=s).sort_stats('tottime') stats.print_stats(lines_to_print) print(s.getvalue()) + + # @:print_c_profiler # @solve_warehouse_location: @@ -103,6 +119,8 @@ def solve_warehouse_location(m): opt = pyo.SolverFactory('gurobi') res = opt.solve(m) assert_optimal_termination(res) + + # @:solve_warehouse_location # @solve_parametric: @@ -116,6 +134,8 @@ def solve_parametric(): res = opt.solve(m) assert_optimal_termination(res) obj_values.append(res.problem.lower_bound) + + # @:solve_parametric # @parametric_persistent: @@ -132,6 +152,8 @@ def solve_parametric_persistent(): res = opt.solve(save_results=False) assert_optimal_termination(res) obj_values.append(res.problem.lower_bound) + + # @:parametric_persistent # @report_timing: @@ -178,9 +200,9 @@ def solve_parametric_persistent(): # @:time_parametric_persistent # @profile_parametric_persistent: -#pr = cProfile.Profile() -#pr.enable() -#solve_parametric_persistent() -#pr.disable() -#print_c_profiler(pr) +# pr = cProfile.Profile() +# pr.enable() +# solve_parametric_persistent() +# pr.disable() +# print_c_profiler(pr) # @:profile_parametric_persistent diff --git a/examples/pyomobook/pyomo-components-ch/con_declaration.py b/examples/pyomobook/pyomo-components-ch/con_declaration.py index cb8e768b5cd..7775c1b26a0 100644 --- a/examples/pyomobook/pyomo-components-ch/con_declaration.py +++ b/examples/pyomobook/pyomo-components-ch/con_declaration.py @@ -3,8 +3,8 @@ model = pyo.ConcreteModel() # @decl1: -model.x = pyo.Var([1,2], initialize=1.0) -model.diff = pyo.Constraint(expr=model.x[2]-model.x[1] <= 7.5) +model.x = pyo.Var([1, 2], initialize=1.0) +model.diff = pyo.Constraint(expr=model.x[2] - model.x[1] <= 7.5) # @:decl1 model.pprint() @@ -12,9 +12,13 @@ model = pyo.ConcreteModel() # @decl2: -model.x = pyo.Var([1,2], initialize=1.0) +model.x = pyo.Var([1, 2], initialize=1.0) + + def diff_rule(model): return model.x[2] - model.x[1] <= 7.5 + + model.diff = pyo.Constraint(rule=diff_rule) # @:decl2 @@ -23,15 +27,18 @@ def diff_rule(model): model = pyo.ConcreteModel() # @decl3: -N = [1,2,3] +N = [1, 2, 3] -a = {1:1, 2:3.1, 3:4.5} -b = {1:1, 2:2.9, 3:3.1} +a = {1: 1, 2: 3.1, 3: 4.5} +b = {1: 1, 2: 2.9, 3: 3.1} model.y = pyo.Var(N, within=pyo.NonNegativeReals, initialize=0.0) + def CoverConstr_rule(model, i): return a[i] * model.y[i] >= b[i] + + model.CoverConstr = pyo.Constraint(N, rule=CoverConstr_rule) # @:decl3 @@ -40,16 +47,18 @@ def CoverConstr_rule(model, i): model = pyo.ConcreteModel() # @decl6: -TimePeriods = [1,2,3,4,5] +TimePeriods = [1, 2, 3, 4, 5] LastTimePeriod = 5 model.StartTime = pyo.Var(TimePeriods, initialize=1.0) + def Pred_rule(model, t): if t == LastTimePeriod: return pyo.Constraint.Skip else: - return model.StartTime[t] <= model.StartTime[t+1] + return model.StartTime[t] <= model.StartTime[t + 1] + model.Pred = pyo.Constraint(TimePeriods, rule=Pred_rule) # @:decl6 @@ -64,17 +73,16 @@ def Pred_rule(model, t): model.c1 = pyo.Constraint(expr=model.y - model.x <= 7.5) model.c2 = pyo.Constraint(expr=-2.5 <= model.y - model.x) -model.c3 = pyo.Constraint( - expr=pyo.inequality(-3.0, model.y - model.x, 7.0)) +model.c3 = pyo.Constraint(expr=pyo.inequality(-3.0, model.y - model.x, 7.0)) -print(pyo.value(model.c1.body)) # 0.0 +print(pyo.value(model.c1.body)) # 0.0 -print(model.c1.lslack()) # inf -print(model.c1.uslack()) # 7.5 -print(model.c2.lslack()) # 2.5 -print(model.c2.uslack()) # inf -print(model.c3.lslack()) # 3.0 -print(model.c3.uslack()) # 7.0 +print(model.c1.lslack()) # inf +print(model.c1.uslack()) # 7.5 +print(model.c2.lslack()) # 2.5 +print(model.c2.uslack()) # inf +print(model.c3.lslack()) # 3.0 +print(model.c3.uslack()) # 7.0 # @:slack model.display() diff --git a/examples/pyomobook/pyomo-components-ch/examples.py b/examples/pyomobook/pyomo-components-ch/examples.py index f12b31c20e5..6ba96792e28 100644 --- a/examples/pyomobook/pyomo-components-ch/examples.py +++ b/examples/pyomobook/pyomo-components-ch/examples.py @@ -4,14 +4,18 @@ # -------------------------------------------------- # @indexed1: model = pyo.ConcreteModel() -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.B = pyo.Set(initialize=['Q', 'R']) model.x = pyo.Var() model.y = pyo.Var(model.A, model.B) model.o = pyo.Objective(expr=model.x) model.c = pyo.Constraint(expr=model.x >= 0) + + def d_rule(model, a): return a * model.x <= 0 + + model.d = pyo.Constraint(model.A, rule=d_rule) # @:indexed1 diff --git a/examples/pyomobook/pyomo-components-ch/expr_declaration.py b/examples/pyomobook/pyomo-components-ch/expr_declaration.py index cf802618218..8974a4d406a 100644 --- a/examples/pyomobook/pyomo-components-ch/expr_declaration.py +++ b/examples/pyomobook/pyomo-components-ch/expr_declaration.py @@ -13,8 +13,12 @@ # @decl2: model.x = pyo.Var() model.e1 = pyo.Expression(expr=model.x + 1) + + def e2_rule(model): return model.x + 2 + + model.e2 = pyo.Expression(rule=e2_rule) # @:decl2 @@ -24,13 +28,17 @@ def e2_rule(model): model = pyo.ConcreteModel() # @decl3: -N = [1,2,3] +N = [1, 2, 3] model.x = pyo.Var(N) + + def e_rule(model, i): if i == 1: return pyo.Expression.Skip else: - return model.x[i]**2 + return model.x[i] ** 2 + + model.e = pyo.Expression(N, rule=e_rule) # @:decl3 @@ -41,8 +49,8 @@ def e_rule(model, i): # @decl4: model.x = pyo.Var() -model.e = pyo.Expression(expr=(model.x - 1.0)**2) -model.o = pyo.Objective(expr=0.1*model.e + model.x) +model.e = pyo.Expression(expr=(model.x - 1.0) ** 2) +model.o = pyo.Objective(expr=0.1 * model.e + model.x) model.c = pyo.Constraint(expr=model.e <= 1.0) # @:decl4 @@ -50,13 +58,13 @@ def e_rule(model, i): # @decl5: model.x.set_value(2.0) -print(pyo.value(model.e)) # 1.0 -print(pyo.value(model.o)) # 2.1 +print(pyo.value(model.e)) # 1.0 +print(pyo.value(model.o)) # 2.1 print(pyo.value(model.c.body)) # 1.0 -model.e.set_value((model.x - 2.0)**2) -print(pyo.value(model.e)) # 0.0 -print(pyo.value(model.o)) # 2.0 +model.e.set_value((model.x - 2.0) ** 2) +print(pyo.value(model.e)) # 0.0 +print(pyo.value(model.o)) # 2.0 print(pyo.value(model.c.body)) # 0.0 # @:decl5 diff --git a/examples/pyomobook/pyomo-components-ch/obj_declaration.py b/examples/pyomobook/pyomo-components-ch/obj_declaration.py index 9b18fed7094..5a962adeb7c 100644 --- a/examples/pyomobook/pyomo-components-ch/obj_declaration.py +++ b/examples/pyomobook/pyomo-components-ch/obj_declaration.py @@ -13,14 +13,17 @@ print('declexprrule') # @declexprrule: -model.x = pyo.Var([1,2], initialize=1.0) +model.x = pyo.Var([1, 2], initialize=1.0) + +model.b = pyo.Objective(expr=model.x[1] + 2 * model.x[2]) -model.b = pyo.Objective(expr=model.x[1] + 2*model.x[2]) def m_rule(model): expr = model.x[1] - expr += 2*model.x[2] + expr += 2 * model.x[2] return expr + + model.c = pyo.Objective(rule=m_rule) # @:declexprrule model.display() @@ -32,8 +35,12 @@ def m_rule(model): # @declmulti: A = ['Q', 'R', 'S'] model.x = pyo.Var(A, initialize=1.0) + + def d_rule(model, i): - return model.x[i]**2 + return model.x[i] ** 2 + + model.d = pyo.Objective(A, rule=d_rule) # @:declmulti @@ -42,7 +49,9 @@ def d_rule(model, i): def e_rule(model, i): if i == 'R': return pyo.Objective.Skip - return model.x[i]**2 + return model.x[i] ** 2 + + model.e = pyo.Objective(A, rule=e_rule) # @:declskip model.display() @@ -53,10 +62,10 @@ def e_rule(model, i): print('value') # @value: A = ['Q', 'R'] -model.x = pyo.Var(A, initialize={'Q':1.5, 'R':2.5}) -model.o = pyo.Objective(expr=model.x['Q'] + 2*model.x['R']) -print(model.o.expr) # x[Q] + 2*x[R] -print(model.o.sense) # minimize +model.x = pyo.Var(A, initialize={'Q': 1.5, 'R': 2.5}) +model.o = pyo.Objective(expr=model.x['Q'] + 2 * model.x['R']) +print(model.o.expr) # x[Q] + 2*x[R] +print(model.o.sense) # minimize print(pyo.value(model.o)) # 6.5 # @:value diff --git a/examples/pyomobook/pyomo-components-ch/param_declaration.py b/examples/pyomobook/pyomo-components-ch/param_declaration.py index d854d94d23d..a9d3256abfe 100644 --- a/examples/pyomobook/pyomo-components-ch/param_declaration.py +++ b/examples/pyomobook/pyomo-components-ch/param_declaration.py @@ -7,11 +7,12 @@ # @:decl1 # @decl3: -model.A = pyo.Set(initialize=[1,2,3]) -model.B = pyo.Set(initialize=['A','B']) -model.U = pyo.Param(model.A, initialize={1:10, 2:20, 3:30}) -model.T = pyo.Param(model.A, model.B, - initialize={(1,'A'):10, (2,'B'):20, (3,'A'):30}) +model.A = pyo.Set(initialize=[1, 2, 3]) +model.B = pyo.Set(initialize=['A', 'B']) +model.U = pyo.Param(model.A, initialize={1: 10, 2: 20, 3: 30}) +model.T = pyo.Param( + model.A, model.B, initialize={(1, 'A'): 10, (2, 'B'): 20, (3, 'A'): 30} +) # @:decl3 model.pprint() diff --git a/examples/pyomobook/pyomo-components-ch/param_initialization.py b/examples/pyomobook/pyomo-components-ch/param_initialization.py index af3b6103d53..e38bd6cfbcc 100644 --- a/examples/pyomobook/pyomo-components-ch/param_initialization.py +++ b/examples/pyomobook/pyomo-components-ch/param_initialization.py @@ -1,35 +1,39 @@ import pyomo.environ as pyo model = pyo.ConcreteModel() -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) # @decl3b: def X_init(model, i, j): - return i*j + return i * j + + model.X = pyo.Param(model.A, model.A, initialize=X_init) # @:decl3b # @decl3c: def XX_init(model, i, j): - if i==1 or j==1: - return i*j - return i*j + model.XX[i-1,j-1] + if i == 1 or j == 1: + return i * j + return i * j + model.XX[i - 1, j - 1] + + model.XX = pyo.Param(model.A, model.A, initialize=XX_init) # @:decl3c # @decl4: -model.B = pyo.Set(initialize=[1,2,3]) -w={} +model.B = pyo.Set(initialize=[1, 2, 3]) +w = {} w[1] = 10 w[3] = 30 model.W = pyo.Param(model.B, initialize=w) # @:decl4 # @decl5: -u={} -u[1,1] = 10 -u[2,2] = 20 -u[3,3] = 30 +u = {} +u[1, 1] = 10 +u[2, 2] = 20 +u[3, 3] = 30 model.U = pyo.Param(model.A, model.A, initialize=u, default=0) # @:decl5 @@ -43,18 +47,18 @@ def XX_init(model, i, j): # -------------------------------------------------- # @special1: model = pyo.ConcreteModel() -model.p = pyo.Param([1,2,3], initialize={1:1.42, 3:3.14}) -model.q = pyo.Param([1,2,3], initialize={1:1.42, 3:3.14}, default=0) +model.p = pyo.Param([1, 2, 3], initialize={1: 1.42, 3: 3.14}) +model.q = pyo.Param([1, 2, 3], initialize={1: 1.42, 3: 3.14}, default=0) # Demonstrating the len() function -print(len(model.p)) # 2 -print(len(model.q)) # 3 +print(len(model.p)) # 2 +print(len(model.q)) # 3 # Demonstrating the 'in' operator (checks against component keys) -print(2 in model.p) # False -print(2 in model.q) # True +print(2 in model.p) # False +print(2 in model.q) # True # Demonstrating iteration over component keys -print([key for key in model.p]) # [1, 3] -print([key for key in model.q]) # [1, 2, 3] +print([key for key in model.p]) # [1, 3] +print([key for key in model.q]) # [1, 2, 3] # @:special1 diff --git a/examples/pyomobook/pyomo-components-ch/param_misc.py b/examples/pyomobook/pyomo-components-ch/param_misc.py index 467a1cae373..baf76cc7c03 100644 --- a/examples/pyomobook/pyomo-components-ch/param_misc.py +++ b/examples/pyomobook/pyomo-components-ch/param_misc.py @@ -2,22 +2,22 @@ # @mutable1: model = pyo.ConcreteModel() -p = {1:1, 2:4, 3:9} +p = {1: 1, 2: 4, 3: 9} -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.p = pyo.Param(model.A, initialize=p) model.x = pyo.Var(model.A, within=pyo.NonNegativeReals) -model.o = pyo.Objective(expr=sum(model.p[i]*model.x[i] for i in model.A)) +model.o = pyo.Objective(expr=sum(model.p[i] * model.x[i] for i in model.A)) # @:mutable1 model.pprint() # @mutable2: model = pyo.ConcreteModel() -p = {1:1, 2:4, 3:9} +p = {1: 1, 2: 4, 3: 9} -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.p = pyo.Param(model.A, initialize=p, mutable=True) model.x = pyo.Var(model.A, within=pyo.NonNegativeReals) @@ -27,4 +27,3 @@ model.p[3] = 3.14 # @:mutable2 model.pprint() - diff --git a/examples/pyomobook/pyomo-components-ch/param_validation.py b/examples/pyomobook/pyomo-components-ch/param_validation.py index 019d6b1d92f..e496c48918d 100644 --- a/examples/pyomobook/pyomo-components-ch/param_validation.py +++ b/examples/pyomobook/pyomo-components-ch/param_validation.py @@ -9,13 +9,19 @@ # @decl2: def Y_validate(model, value): return value in pyo.Reals + + model.Y = pyo.Param(validate=Y_validate) # @:decl2 # @decl3: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) + + def X_validate(model, value, i): return value > i + + model.X = pyo.Param(model.A, validate=X_validate) # @:decl3 diff --git a/examples/pyomobook/pyomo-components-ch/rangeset.py b/examples/pyomobook/pyomo-components-ch/rangeset.py index 237031469be..d5e1015064c 100644 --- a/examples/pyomobook/pyomo-components-ch/rangeset.py +++ b/examples/pyomobook/pyomo-components-ch/rangeset.py @@ -7,11 +7,11 @@ # @:decl1 # @decl3: -model.C = pyo.RangeSet(5,10) +model.C = pyo.RangeSet(5, 10) # @:decl3 # @decl4: -model.D = pyo.RangeSet(2.5,11,1.5) +model.D = pyo.RangeSet(2.5, 11, 1.5) # @:decl4 instance = model.create_instance() diff --git a/examples/pyomobook/pyomo-components-ch/set_declaration.py b/examples/pyomobook/pyomo-components-ch/set_declaration.py index 5555c02993b..1a507d4f588 100644 --- a/examples/pyomobook/pyomo-components-ch/set_declaration.py +++ b/examples/pyomobook/pyomo-components-ch/set_declaration.py @@ -14,7 +14,7 @@ model.A = pyo.Set() model.B = pyo.Set() model.C = pyo.Set(model.A) -model.D = pyo.Set(model.A,model.B) +model.D = pyo.Set(model.A, model.B) # @:decl2 model = pyo.AbstractModel() @@ -23,8 +23,8 @@ model = pyo.AbstractModel() # @decl6: -model.E = pyo.Set([1,2,3]) -f = set([1,2,3]) +model.E = pyo.Set([1, 2, 3]) +f = set([1, 2, 3]) model.F = pyo.Set(f) # @:decl6 @@ -36,10 +36,10 @@ # @decl3: model.A = pyo.Set() model.B = pyo.Set() -model.G = model.A | model.B # set union -model.H = model.B & model.A # set intersection -model.I = model.A - model.B # set difference -model.J = model.A ^ model.B # set exclusive-or +model.G = model.A | model.B # set union +model.H = model.B & model.A # set intersection +model.I = model.A - model.B # set difference +model.J = model.A ^ model.B # set exclusive-or # @:decl3 instance = model.create_instance('set_declaration.dat') diff --git a/examples/pyomobook/pyomo-components-ch/set_initialization.py b/examples/pyomobook/pyomo-components-ch/set_initialization.py index 6d91f25e9da..ef5fb84bf61 100644 --- a/examples/pyomobook/pyomo-components-ch/set_initialization.py +++ b/examples/pyomobook/pyomo-components-ch/set_initialization.py @@ -3,35 +3,41 @@ model = pyo.ConcreteModel() # @decl2: -model.B = pyo.Set(initialize=[2,3,4]) -model.C = pyo.Set(initialize=[(1,4),(9,16)]) +model.B = pyo.Set(initialize=[2, 3, 4]) +model.C = pyo.Set(initialize=[(1, 4), (9, 16)]) # @:decl2 # @decl6: F_init = {} -F_init[2] = [1,3,5] -F_init[3] = [2,4,6] -F_init[4] = [3,5,7] -model.F = pyo.Set([2,3,4],initialize=F_init) +F_init[2] = [1, 3, 5] +F_init[3] = [2, 4, 6] +F_init[4] = [3, 5, 7] +model.F = pyo.Set([2, 3, 4], initialize=F_init) # @:decl6 # @decl8: def J_init(model, i, j): - return range(0,i*j) -model.J = pyo.Set(model.B,model.B, initialize=J_init) + return range(0, i * j) + + +model.J = pyo.Set(model.B, model.B, initialize=J_init) # @:decl8 # @decl12: -model.P = pyo.Set(initialize=[1,2,3,5,7]) +model.P = pyo.Set(initialize=[1, 2, 3, 5, 7]) + + def filter_rule(model, x): return x not in model.P -model.Q = pyo.Set(initialize=range(1,10), filter=filter_rule) + + +model.Q = pyo.Set(initialize=range(1, 10), filter=filter_rule) # @:decl12 # @decl20: -model.R = pyo.Set([1,2,3]) +model.R = pyo.Set([1, 2, 3]) model.R[1] = [1] -model.R[2] = [1,2] +model.R[2] = [1, 2] # @:decl20 model.pprint(verbose=True) diff --git a/examples/pyomobook/pyomo-components-ch/set_misc.py b/examples/pyomobook/pyomo-components-ch/set_misc.py index 73ef80baac1..9a795b196b8 100644 --- a/examples/pyomobook/pyomo-components-ch/set_misc.py +++ b/examples/pyomobook/pyomo-components-ch/set_misc.py @@ -2,48 +2,48 @@ model = pyo.ConcreteModel() # @len: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) -print(len(model.A)) # 3 +print(len(model.A)) # 3 # @:len model = pyo.ConcreteModel() # @data: model.A = pyo.Set(initialize=[1, 2, 3]) model.B = pyo.Set(initialize=[3, 2, 1], ordered=True) -model.C = pyo.Set(model.A, initialize={1:[1], 2:[1, 2]}) +model.C = pyo.Set(model.A, initialize={1: [1], 2: [1, 2]}) -print(type(model.A.data()) is tuple) # True -print(type(model.B.data()) is tuple) # True -print(type(model.C.data()) is dict) # True -print(sorted(model.A.data())) # [1, 2, 3] +print(type(model.A.data()) is tuple) # True +print(type(model.B.data()) is tuple) # True +print(type(model.C.data()) is dict) # True +print(sorted(model.A.data())) # [1, 2, 3] for index in sorted(model.C.data().keys()): - print(sorted(model.C.data()[index])) + print(sorted(model.C.data()[index])) # [1] # [1, 2] # @:data model = pyo.ConcreteModel() # @special: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) # Test if an element is in the set -print(1 in model.A) # True +print(1 in model.A) # True # Test if sets are equal -print([1, 2] == model.A) # False +print([1, 2] == model.A) # False # Test if sets are not equal -print([1, 2] != model.A) # True +print([1, 2] != model.A) # True # Test if a set is a subset of or equal to the set -print([1, 2] <= model.A) # True +print([1, 2] <= model.A) # True # Test if a set is a subset of the set -print([1, 2] < model.A) # True +print([1, 2] < model.A) # True # Test if a set is a superset of the set -print([1, 2, 3] > model.A) # False +print([1, 2, 3] > model.A) # False # Test if a set is a superset of or equal to the set print([1, 2, 3] >= model.A) # True @@ -52,9 +52,9 @@ model = pyo.ConcreteModel() # @iter: model.A = pyo.Set(initialize=[1, 2, 3]) -model.C = pyo.Set(model.A, initialize={1:[1], 2:[1, 2]}) +model.C = pyo.Set(model.A, initialize={1: [1], 2: [1, 2]}) -print(sorted(e for e in model.A)) # [1, 2, 3] +print(sorted(e for e in model.A)) # [1, 2, 3] for index in model.C: print(sorted(e for e in model.C[index])) # [1] @@ -65,21 +65,20 @@ # @ordered: model.A = pyo.Set(initialize=[3, 2, 1], ordered=True) -print(model.A.first()) # 3 -print(model.A.last()) # 1 -print(model.A.next(2)) # 1 -print(model.A.prev(2)) # 3 -print(model.A.nextw(1)) # 3 -print(model.A.prevw(3)) # 1 +print(model.A.first()) # 3 +print(model.A.last()) # 1 +print(model.A.next(2)) # 1 +print(model.A.prev(2)) # 3 +print(model.A.nextw(1)) # 3 +print(model.A.prevw(3)) # 1 # @:ordered model = pyo.ConcreteModel() # @ordered2: model.A = pyo.Set(initialize=[3, 2, 1], ordered=True) -print(model.A.ord(3)) # 1 -print(model.A.ord(1)) # 3 -print(model.A[1]) # 3 -print(model.A[3]) # 1 +print(model.A.ord(3)) # 1 +print(model.A.ord(1)) # 3 +print(model.A[1]) # 3 +print(model.A[3]) # 1 # @:ordered2 - diff --git a/examples/pyomobook/pyomo-components-ch/set_validation.py b/examples/pyomobook/pyomo-components-ch/set_validation.py index 2e1d90b0039..79886d01d0f 100644 --- a/examples/pyomobook/pyomo-components-ch/set_validation.py +++ b/examples/pyomobook/pyomo-components-ch/set_validation.py @@ -10,6 +10,8 @@ # @decl2: def C_validate(model, value): return value in model.A + + model.C = pyo.Set(validate=C_validate) # @:decl2 diff --git a/examples/pyomobook/pyomo-components-ch/suffix_declaration.py b/examples/pyomobook/pyomo-components-ch/suffix_declaration.py index 455ab6e33c5..650669ef5a6 100644 --- a/examples/pyomobook/pyomo-components-ch/suffix_declaration.py +++ b/examples/pyomobook/pyomo-components-ch/suffix_declaration.py @@ -11,8 +11,7 @@ # @suffixdecl: # Export integer data -model.priority = pyo.Suffix(direction=pyo.Suffix.EXPORT, - datatype=pyo.Suffix.INT) +model.priority = pyo.Suffix(direction=pyo.Suffix.EXPORT, datatype=pyo.Suffix.INT) # Export and import floating point data model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT_EXPORT) @@ -25,20 +24,23 @@ model.x = pyo.Var() model.c = pyo.Constraint(expr=model.x >= 1) + def foo_rule(m): - return ((m.x, 2.0), (m.c, 3.0)) + return ((m.x, 2.0), (m.c, 3.0)) + + model.foo = pyo.Suffix(initialize=foo_rule) # @:suffixinitrule model.pprint() -del foo_rule # Needed to avoid implicit rule warning in next example +del foo_rule # Needed to avoid implicit rule warning in next example print('') print('*** suffix1 ***') # @suffix1: model = pyo.ConcreteModel() model.x = pyo.Var() -model.y = pyo.Var([1,2,3]) +model.y = pyo.Var([1, 2, 3]) model.foo = pyo.Suffix() # @:suffix1 print('suffix1a') @@ -50,7 +52,7 @@ def foo_rule(m): model.x.set_suffix_value(model.foo, 2.0) # Get the value of suffix 'foo' for model.x -print(model.x.get_suffix_value('foo')) # 2.0 +print(model.x.get_suffix_value('foo')) # 2.0 # @:suffix1a print('suffix1b') # @suffix1b: @@ -61,17 +63,17 @@ def foo_rule(m): model.y[2].set_suffix_value(model.foo, 4.0) # Get the value of suffix 'foo' for model.y -print(model.y.get_suffix_value(model.foo)) # None -print(model.y[1].get_suffix_value(model.foo)) # 3.0 -print(model.y[2].get_suffix_value(model.foo)) # 4.0 -print(model.y[3].get_suffix_value(model.foo)) # 3.0 +print(model.y.get_suffix_value(model.foo)) # None +print(model.y[1].get_suffix_value(model.foo)) # 3.0 +print(model.y[2].get_suffix_value(model.foo)) # 4.0 +print(model.y[3].get_suffix_value(model.foo)) # 3.0 # @:suffix1b # @suffix1d: model.y[3].clear_suffix_value(model.foo) -print(model.y.get_suffix_value(model.foo)) # None -print(model.y[1].get_suffix_value(model.foo)) # 3.0 -print(model.y[2].get_suffix_value(model.foo)) # 4.0 -print(model.y[3].get_suffix_value(model.foo)) # None +print(model.y.get_suffix_value(model.foo)) # None +print(model.y[1].get_suffix_value(model.foo)) # 3.0 +print(model.y[2].get_suffix_value(model.foo)) # 4.0 +print(model.y[3].get_suffix_value(model.foo)) # None # @:suffix1d diff --git a/examples/pyomobook/pyomo-components-ch/var_declaration.py b/examples/pyomobook/pyomo-components-ch/var_declaration.py index 1f48e1502a6..538cbea1842 100644 --- a/examples/pyomobook/pyomo-components-ch/var_declaration.py +++ b/examples/pyomobook/pyomo-components-ch/var_declaration.py @@ -8,17 +8,21 @@ # @:initscalarvar # for testing -print('3.14 =', pyo.value(model.x)) # 3.14 +print('3.14 =', pyo.value(model.x)) # 3.14 model = None model = pyo.ConcreteModel() # @dictruleinit: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.x = pyo.Var(model.A, initialize=3.14) -model.y = pyo.Var(model.A, initialize={1:1.5, 2:4.5, 3:5.5}) +model.y = pyo.Var(model.A, initialize={1: 1.5, 2: 4.5, 3: 5.5}) + + def z_init_rule(m, i): return float(i) + 0.5 + + model.z = pyo.Var(model.A, initialize=z_init_rule) # @:dictruleinit @@ -41,7 +45,7 @@ def z_init_rule(m, i): model = pyo.ConcreteModel() # @domaindecl: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.y = pyo.Var(within=model.A) model.r = pyo.Var(domain=pyo.Reals) model.w = pyo.Var(within=pyo.Boolean) @@ -57,9 +61,13 @@ def z_init_rule(m, i): model = pyo.ConcreteModel() # @domaindeclrule: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) + + def s_domain(model, i): - return pyo.RangeSet(i, i+1, 1) # (start, end, step) + return pyo.RangeSet(i, i + 1, 1) # (start, end, step) + + model.s = pyo.Var(model.A, domain=s_domain) # @:domaindeclrule @@ -71,13 +79,17 @@ def s_domain(model, i): model = pyo.ConcreteModel() # @declbounds: -model.A = pyo.Set(initialize=[1,2,3]) -model.a = pyo.Var(bounds=(0.0,None)) +model.A = pyo.Set(initialize=[1, 2, 3]) +model.a = pyo.Var(bounds=(0.0, None)) + +lower = {1: 2.5, 2: 4.5, 3: 6.5} +upper = {1: 3.5, 2: 4.5, 3: 7.5} + -lower = {1:2.5, 2:4.5, 3:6.5} -upper = {1:3.5, 2:4.5, 3:7.5} def f(model, i): return (lower[i], upper[i]) + + model.b = pyo.Var(model.A, bounds=f) # @:declbounds @@ -92,27 +104,31 @@ def f(model, i): model = pyo.ConcreteModel() # @declinit: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.za = pyo.Var(initialize=9.5, within=pyo.NonNegativeReals) -model.zb = pyo.Var(model.A, initialize={1:1.5, 2:4.5, 3:5.5}) +model.zb = pyo.Var(model.A, initialize={1: 1.5, 2: 4.5, 3: 5.5}) model.zc = pyo.Var(model.A, initialize=2.1) -print(pyo.value(model.za)) # 9.5 -print(pyo.value(model.zb[3])) # 5.5 -print(pyo.value(model.zc[3])) # 2.1 +print(pyo.value(model.za)) # 9.5 +print(pyo.value(model.zb[3])) # 5.5 +print(pyo.value(model.zc[3])) # 2.1 # @:declinit model = None model = pyo.ConcreteModel() # @declinitrule: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) + + def g(model, i): - return 3*i + return 3 * i + + model.m = pyo.Var(model.A, initialize=g) -print(pyo.value(model.m[1])) # 3 -print(pyo.value(model.m[3])) # 9 +print(pyo.value(model.m[1])) # 3 +print(pyo.value(model.m[3])) # 9 # @:declinitrule model = None @@ -120,16 +136,16 @@ def g(model, i): print("varattrib") # @varattribdecl: -model.A = pyo.Set(initialize=[1,2,3]) +model.A = pyo.Set(initialize=[1, 2, 3]) model.za = pyo.Var(initialize=9.5, within=pyo.NonNegativeReals) -model.zb = pyo.Var(model.A, initialize={1:1.5, 2:4.5, 3:5.5}) +model.zb = pyo.Var(model.A, initialize={1: 1.5, 2: 4.5, 3: 5.5}) model.zc = pyo.Var(model.A, initialize=2.1) # @:varattribdecl # @varattribvaluebounds: -print(pyo.value(model.zb[2])) # 4.5 -print(model.za.lb) # 0 -print(model.za.ub) # None +print(pyo.value(model.zb[2])) # 4.5 +print(model.za.lb) # 0 +print(model.za.ub) # None # @:varattribvaluebounds # @varassign: @@ -139,11 +155,9 @@ def g(model, i): # @varfixed: model.zb.fix(3.0) -print(model.zb[1].fixed) # True -print(model.zb[2].fixed) # True +print(model.zb[1].fixed) # True +print(model.zb[2].fixed) # True model.zc[2].fix(3.0) -print(model.zc[1].fixed) # False -print(model.zc[2].fixed) # True +print(model.zc[1].fixed) # False +print(model.zc[2].fixed) # True # @:varfixed - - diff --git a/examples/pyomobook/python-ch/class.py b/examples/pyomobook/python-ch/class.py index 97bb44b1464..42c404efd81 100644 --- a/examples/pyomobook/python-ch/class.py +++ b/examples/pyomobook/python-ch/class.py @@ -3,18 +3,22 @@ # @all: class IntLocker: sint = None + def __init__(self, i): self.set_value(i) + def set_value(self, i): if type(i) is not int: print("Error: %d is not integer." % i) else: self.sint = i + def pprint(self): - print("The Int Locker has "+str(self.sint)) - + print("The Int Locker has " + str(self.sint)) + + a = IntLocker(3) -a.pprint() # prints: The Int Locker has 3 +a.pprint() # prints: The Int Locker has 3 a.set_value(5) -a.pprint() # prints: The Int Locker has 5 +a.pprint() # prints: The Int Locker has 5 # @:all diff --git a/examples/pyomobook/python-ch/ctob.py b/examples/pyomobook/python-ch/ctob.py index d05f6f03cb7..e418d27f103 100644 --- a/examples/pyomobook/python-ch/ctob.py +++ b/examples/pyomobook/python-ch/ctob.py @@ -1,14 +1,18 @@ -# An example of a silly decorator to change 'c' to 'b' -# in the return value of a function. +# An example of a silly decorator to change 'c' to 'b' +# in the return value of a function. + def ctob_decorate(func): - def func_wrapper(*args, **kwargs): - retval = func(*args, **kwargs).replace('c','b') - return retval.replace('C','B') - return func_wrapper + def func_wrapper(*args, **kwargs): + retval = func(*args, **kwargs).replace('c', 'b') + return retval.replace('C', 'B') + + return func_wrapper + @ctob_decorate def Last_Words(): return "Flying Circus" + print(Last_Words()) # prints: Flying Birbus diff --git a/examples/pyomobook/python-ch/example2.py b/examples/pyomobook/python-ch/example2.py index 4c0cb94c0ad..da7d14e24ae 100644 --- a/examples/pyomobook/python-ch/example2.py +++ b/examples/pyomobook/python-ch/example2.py @@ -2,4 +2,5 @@ print("Hello World") import sys + sys.stdin.readline() diff --git a/examples/pyomobook/python-ch/functions.py b/examples/pyomobook/python-ch/functions.py index 15657a5eb78..6c9ab431f71 100644 --- a/examples/pyomobook/python-ch/functions.py +++ b/examples/pyomobook/python-ch/functions.py @@ -6,15 +6,17 @@ def Apply(f, a): for i in range(len(a)): r.append(f(a[i])) return r - + + def SqifOdd(x): # if x is odd, 2*int(x/2) is not x # due to integer divide of x/2 - if 2*int(x/2) == x: + if 2 * int(x / 2) == x: return x else: - return x*x - + return x * x + + ShortList = range(4) B = Apply(SqifOdd, ShortList) print(B) diff --git a/examples/pyomobook/python-ch/iterate.py b/examples/pyomobook/python-ch/iterate.py index b59cd2c7814..3a3422b2a09 100644 --- a/examples/pyomobook/python-ch/iterate.py +++ b/examples/pyomobook/python-ch/iterate.py @@ -1,7 +1,7 @@ # iterate.py # @all: -D = {'Mary':231} +D = {'Mary': 231} D['Bob'] = 123 D['Alice'] = 331 D['Ted'] = 987 @@ -11,8 +11,8 @@ continue if i == 'John': print("Loop ends. Cleese alert!") - break; - print(i+" "+str(D[i])) + break + print(i + " " + str(D[i])) else: print("Cleese is not in the list.") # @:all diff --git a/examples/pyomobook/scripts-ch/attributes.py b/examples/pyomobook/scripts-ch/attributes.py index b182a4c2ffd..643162082b6 100644 --- a/examples/pyomobook/scripts-ch/attributes.py +++ b/examples/pyomobook/scripts-ch/attributes.py @@ -22,7 +22,3 @@ # print the value of a particular variable print(pyo.value(model.y['Harlingen'])) - - - - diff --git a/examples/pyomobook/scripts-ch/prob_mod_ex.py b/examples/pyomobook/scripts-ch/prob_mod_ex.py index 6712fbed5b1..6d610e9b44a 100644 --- a/examples/pyomobook/scripts-ch/prob_mod_ex.py +++ b/examples/pyomobook/scripts-ch/prob_mod_ex.py @@ -1,52 +1,51 @@ import pyomo.environ as pyo model = pyo.ConcreteModel() -model.x = pyo.Var(bounds=(0,5)) -model.y = pyo.Var(bounds=(0,1)) +model.x = pyo.Var(bounds=(0, 5)) +model.y = pyo.Var(bounds=(0, 1)) model.con = pyo.Constraint(expr=model.x + model.y == 1.0) -model.obj = pyo.Objective(expr=model.y-model.x) +model.obj = pyo.Objective(expr=model.y - model.x) # solve the problem # @solver: solver = pyo.SolverFactory('glpk') # @:solver solver.solve(model) -print(pyo.value(model.x)) # 1.0 -print(pyo.value(model.y)) # 0.0 +print(pyo.value(model.x)) # 1.0 +print(pyo.value(model.y)) # 0.0 # add a constraint -model.con2 = pyo.Constraint(expr=4.0*model.x + model.y == 2.0) +model.con2 = pyo.Constraint(expr=4.0 * model.x + model.y == 2.0) solver.solve(model) -print(pyo.value(model.x)) # 0.33 -print(pyo.value(model.y)) # 0.66 +print(pyo.value(model.x)) # 0.33 +print(pyo.value(model.y)) # 0.66 # deactivate a constraint model.con.deactivate() solver.solve(model) -print(pyo.value(model.x)) # 0.5 -print(pyo.value(model.y)) # 0.0 +print(pyo.value(model.x)) # 0.5 +print(pyo.value(model.y)) # 0.0 # re-activate a constraint model.con.activate() solver.solve(model) -print(pyo.value(model.x)) # 0.33 -print(pyo.value(model.y)) # 0.66 +print(pyo.value(model.x)) # 0.33 +print(pyo.value(model.y)) # 0.66 # delete a constraint del model.con2 solver.solve(model) -print(pyo.value(model.x)) # 1.0 -print(pyo.value(model.y)) # 0.0 +print(pyo.value(model.x)) # 1.0 +print(pyo.value(model.y)) # 0.0 # fix a variable model.x.fix(0.5) solver.solve(model) -print(pyo.value(model.x)) # 0.5 -print(pyo.value(model.y)) # 0.5 +print(pyo.value(model.x)) # 0.5 +print(pyo.value(model.y)) # 0.5 # unfix a variable model.x.unfix() solver.solve(model) -print(pyo.value(model.x)) # 1.0 -print(pyo.value(model.y)) # 0.0 - +print(pyo.value(model.x)) # 1.0 +print(pyo.value(model.y)) # 0.0 diff --git a/examples/pyomobook/scripts-ch/sudoku/sudoku.py b/examples/pyomobook/scripts-ch/sudoku/sudoku.py index f2515252eb8..0ee061b9e50 100644 --- a/examples/pyomobook/scripts-ch/sudoku/sudoku.py +++ b/examples/pyomobook/scripts-ch/sudoku/sudoku.py @@ -4,17 +4,17 @@ # the list (row,col) entries subsq_to_row_col = dict() -subsq_to_row_col[1] = [(i,j) for i in range(1,4) for j in range(1,4)] -subsq_to_row_col[2] = [(i,j) for i in range(1,4) for j in range(4,7)] -subsq_to_row_col[3] = [(i,j) for i in range(1,4) for j in range(7,10)] +subsq_to_row_col[1] = [(i, j) for i in range(1, 4) for j in range(1, 4)] +subsq_to_row_col[2] = [(i, j) for i in range(1, 4) for j in range(4, 7)] +subsq_to_row_col[3] = [(i, j) for i in range(1, 4) for j in range(7, 10)] -subsq_to_row_col[4] = [(i,j) for i in range(4,7) for j in range(1,4)] -subsq_to_row_col[5] = [(i,j) for i in range(4,7) for j in range(4,7)] -subsq_to_row_col[6] = [(i,j) for i in range(4,7) for j in range(7,10)] +subsq_to_row_col[4] = [(i, j) for i in range(4, 7) for j in range(1, 4)] +subsq_to_row_col[5] = [(i, j) for i in range(4, 7) for j in range(4, 7)] +subsq_to_row_col[6] = [(i, j) for i in range(4, 7) for j in range(7, 10)] -subsq_to_row_col[7] = [(i,j) for i in range(7,10) for j in range(1,4)] -subsq_to_row_col[8] = [(i,j) for i in range(7,10) for j in range(4,7)] -subsq_to_row_col[9] = [(i,j) for i in range(7,10) for j in range(7,10)] +subsq_to_row_col[7] = [(i, j) for i in range(7, 10) for j in range(1, 4)] +subsq_to_row_col[8] = [(i, j) for i in range(7, 10) for j in range(4, 7)] +subsq_to_row_col[9] = [(i, j) for i in range(7, 10) for j in range(7, 10)] # creates the sudoku model for a 10x10 board, where the # input board is a list of fixed numbers specified in @@ -27,50 +27,55 @@ def create_sudoku_model(board): model.board = board # create sets for rows columns and squares - model.ROWS = pyo.RangeSet(1,9) - model.COLS = pyo.RangeSet(1,9) - model.SUBSQUARES = pyo.RangeSet(1,9) - model.VALUES = pyo.RangeSet(1,9) + model.ROWS = pyo.RangeSet(1, 9) + model.COLS = pyo.RangeSet(1, 9) + model.SUBSQUARES = pyo.RangeSet(1, 9) + model.VALUES = pyo.RangeSet(1, 9) # create the binary variables to define the values model.y = pyo.Var(model.ROWS, model.COLS, model.VALUES, within=pyo.Binary) # fix variables based on the current board - for (r,c,v) in board: - model.y[r,c,v].fix(1) + for (r, c, v) in board: + model.y[r, c, v].fix(1) # create the objective - this is a feasibility problem # so we just make it a constant - model.obj = pyo.Objective(expr= 1.0) + model.obj = pyo.Objective(expr=1.0) -# @row_col_cons: + # @row_col_cons: # exactly one number in each row def _RowCon(model, r, v): - return sum(model.y[r,c,v] for c in model.COLS) == 1 + return sum(model.y[r, c, v] for c in model.COLS) == 1 + model.RowCon = pyo.Constraint(model.ROWS, model.VALUES, rule=_RowCon) # exactly one number in each column def _ColCon(model, c, v): - return sum(model.y[r,c,v] for r in model.ROWS) == 1 + return sum(model.y[r, c, v] for r in model.ROWS) == 1 + model.ColCon = pyo.Constraint(model.COLS, model.VALUES, rule=_ColCon) -# @:row_col_cons + # @:row_col_cons -# @subsq_con: + # @subsq_con: # exactly one number in each subsquare def _SqCon(model, s, v): - return sum(model.y[r,c,v] for (r,c) in subsq_to_row_col[s]) == 1 + return sum(model.y[r, c, v] for (r, c) in subsq_to_row_col[s]) == 1 + model.SqCon = pyo.Constraint(model.SUBSQUARES, model.VALUES, rule=_SqCon) -# @:subsq_con + # @:subsq_con -# @num_con: + # @num_con: # exactly one number in each cell def _ValueCon(model, r, c): - return sum(model.y[r,c,v] for v in model.VALUES) == 1 + return sum(model.y[r, c, v] for v in model.VALUES) == 1 + model.ValueCon = pyo.Constraint(model.ROWS, model.COLS, rule=_ValueCon) -# @:num_con + # @:num_con return model + # use this function to add a new integer cut to the model. def add_integer_cut(model): # add the ConstraintList to store the IntegerCuts if @@ -84,18 +89,24 @@ def add_integer_cut(model): for r in model.ROWS: for c in model.COLS: for v in model.VALUES: - if not model.y[r,c,v].fixed: + if not model.y[r, c, v].fixed: # check if the binary variable is on or off # note, it may not be exactly 1 - if pyo.value(model.y[r,c,v]) >= 0.5: - cut_expr += (1.0 - model.y[r,c,v]) + if pyo.value(model.y[r, c, v]) >= 0.5: + cut_expr += 1.0 - model.y[r, c, v] else: - cut_expr += model.y[r,c,v] + cut_expr += model.y[r, c, v] model.IntegerCuts.add(cut_expr >= 1) + # prints the current solution stored in the model def print_solution(model): for r in model.ROWS: - print(' '.join(str(v) for c in model.COLS - for v in model.VALUES - if pyo.value(model.y[r,c,v]) >= 0.5)) + print( + ' '.join( + str(v) + for c in model.COLS + for v in model.VALUES + if pyo.value(model.y[r, c, v]) >= 0.5 + ) + ) diff --git a/examples/pyomobook/scripts-ch/sudoku/sudoku_run.py b/examples/pyomobook/scripts-ch/sudoku/sudoku_run.py index ce8bed4ed4e..8a961cae771 100644 --- a/examples/pyomobook/scripts-ch/sudoku/sudoku_run.py +++ b/examples/pyomobook/scripts-ch/sudoku/sudoku_run.py @@ -1,19 +1,39 @@ -from pyomo.opt import (SolverFactory, - TerminationCondition) -from sudoku import (create_sudoku_model, - print_solution, - add_integer_cut) +from pyomo.opt import SolverFactory, TerminationCondition +from sudoku import create_sudoku_model, print_solution, add_integer_cut # define the board -board = [(1,1,5),(1,2,3),(1,5,7), \ - (2,1,6),(2,4,1),(2,5,9),(2,6,5), \ - (3,2,9),(3,3,8),(3,8,6), \ - (4,1,8),(4,5,6),(4,9,3), \ - (5,1,4),(5,4,8),(5,6,3),(5,9,1), \ - (6,1,7),(6,5,2),(6,9,6), \ - (7,2,6),(7,7,2),(7,8,8), \ - (8,4,4),(8,5,1),(8,6,9),(8,9,5), \ - (9,5,8),(9,8,7),(9,9,9)] +board = [ + (1, 1, 5), + (1, 2, 3), + (1, 5, 7), + (2, 1, 6), + (2, 4, 1), + (2, 5, 9), + (2, 6, 5), + (3, 2, 9), + (3, 3, 8), + (3, 8, 6), + (4, 1, 8), + (4, 5, 6), + (4, 9, 3), + (5, 1, 4), + (5, 4, 8), + (5, 6, 3), + (5, 9, 1), + (6, 1, 7), + (6, 5, 2), + (6, 9, 6), + (7, 2, 6), + (7, 7, 2), + (7, 8, 8), + (8, 4, 4), + (8, 5, 1), + (8, 6, 9), + (8, 9, 5), + (9, 5, 8), + (9, 8, 7), + (9, 9, 9), +] model = create_sudoku_model(board) @@ -22,8 +42,7 @@ with SolverFactory("glpk") as opt: results = opt.solve(model) - if results.solver.termination_condition != \ - TerminationCondition.optimal: + if results.solver.termination_condition != TerminationCondition.optimal: print("All board solutions have been found") break diff --git a/examples/pyomobook/scripts-ch/warehouse_cuts.py b/examples/pyomobook/scripts-ch/warehouse_cuts.py index 6bd868c1224..c6516e796af 100644 --- a/examples/pyomobook/scripts-ch/warehouse_cuts.py +++ b/examples/pyomobook/scripts-ch/warehouse_cuts.py @@ -1,9 +1,11 @@ import warnings + warnings.filterwarnings("ignore") # The following import/use is needed to prevent matplotlib from using # the X-backend on *nix platforms, which would fail when run in # automated testing environments or when $DISPLAY is not set. import matplotlib + matplotlib.use('agg') # @all: import json @@ -28,7 +30,7 @@ term_cond = results.solver.termination_condition print('') print('--- Solver Status: {0} ---'.format(term_cond)) - + if pyo.check_optimal_termination(results): # look at the solution print('Optimal Obj. Value = {0}'.format(pyo.value(model.obj))) @@ -41,13 +43,13 @@ expr1 = sum(model.y[i] for i in WH_True) expr2 = sum(model.y[i] for i in WH_False) model.integer_cuts.add( - sum(model.y[i] for i in WH_True) \ - - sum(model.y[i] for i in WH_False) \ - <= len(WH_True)-1) + sum(model.y[i] for i in WH_True) - sum(model.y[i] for i in WH_False) + <= len(WH_True) - 1 + ) else: done = True -x = range(1, len(objective_values)+1) +x = range(1, len(objective_values) + 1) plt.bar(x, objective_values, align='center') plt.gca().set_xticks(x) plt.xlabel('Solution Number') diff --git a/examples/pyomobook/scripts-ch/warehouse_load_solutions.py b/examples/pyomobook/scripts-ch/warehouse_load_solutions.py index 8719112813c..790333a0e64 100644 --- a/examples/pyomobook/scripts-ch/warehouse_load_solutions.py +++ b/examples/pyomobook/scripts-ch/warehouse_load_solutions.py @@ -17,10 +17,13 @@ # @load_solutions: from pyomo.opt import SolverStatus, TerminationCondition + # Wait to load the solution into the model until # after the solver status is checked results = solver.solve(model, load_solutions=False) -if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal): +if (results.solver.status == SolverStatus.ok) and ( + results.solver.termination_condition == TerminationCondition.optimal +): # Manually load the solution into the model model.solutions.load_from(results) else: diff --git a/examples/pyomobook/scripts-ch/warehouse_model.py b/examples/pyomobook/scripts-ch/warehouse_model.py index 49c3b4ecdfc..f5983d3cd89 100644 --- a/examples/pyomobook/scripts-ch/warehouse_model.py +++ b/examples/pyomobook/scripts-ch/warehouse_model.py @@ -1,5 +1,6 @@ import pyomo.environ as pyo + def create_wl_model(data, P): # create the model model = pyo.ConcreteModel(name="(WL)") @@ -7,23 +8,29 @@ def create_wl_model(data, P): model.CUST = data['CUST'] model.dist = data['dist'] model.P = P - model.x = pyo.Var(model.WH, model.CUST, bounds=(0,1)) + model.x = pyo.Var(model.WH, model.CUST, bounds=(0, 1)) model.y = pyo.Var(model.WH, within=pyo.Binary) def obj_rule(m): - return sum(m.dist[w][c]*m.x[w,c] for w in m.WH for c in m.CUST) + return sum(m.dist[w][c] * m.x[w, c] for w in m.WH for c in m.CUST) + model.obj = pyo.Objective(rule=obj_rule) def one_per_cust_rule(m, c): - return sum(m.x[w,c] for w in m.WH) == 1 + return sum(m.x[w, c] for w in m.WH) == 1 + model.one_per_cust = pyo.Constraint(model.CUST, rule=one_per_cust_rule) def warehouse_active_rule(m, w, c): - return m.x[w,c] <= m.y[w] - model.warehouse_active = pyo.Constraint(model.WH, model.CUST, rule=warehouse_active_rule) + return m.x[w, c] <= m.y[w] + + model.warehouse_active = pyo.Constraint( + model.WH, model.CUST, rule=warehouse_active_rule + ) def num_warehouses_rule(m): return sum(m.y[w] for w in m.WH) <= m.P + model.num_warehouses = pyo.Constraint(rule=num_warehouses_rule) return model diff --git a/examples/pyomobook/scripts-ch/warehouse_print.py b/examples/pyomobook/scripts-ch/warehouse_print.py index 933824c5470..e0e2f961345 100644 --- a/examples/pyomobook/scripts-ch/warehouse_print.py +++ b/examples/pyomobook/scripts-ch/warehouse_print.py @@ -32,7 +32,7 @@ # @:printloopset # @printslicing: -for v in model.x['Ashland',:]: +for v in model.x['Ashland', :]: print('{0} = {1}'.format(v, pyo.value(v))) # @:printslicing diff --git a/examples/pyomobook/scripts-ch/warehouse_solver_options.py b/examples/pyomobook/scripts-ch/warehouse_solver_options.py index 0f60873e13d..c8eaf11a0f3 100644 --- a/examples/pyomobook/scripts-ch/warehouse_solver_options.py +++ b/examples/pyomobook/scripts-ch/warehouse_solver_options.py @@ -28,4 +28,5 @@ # @:script import os + os.remove('warehouse.log') diff --git a/examples/pyomobook/strip_examples.py b/examples/pyomobook/strip_examples.py index 7c6c95b01c3..0a65eef7c04 100644 --- a/examples/pyomobook/strip_examples.py +++ b/examples/pyomobook/strip_examples.py @@ -3,23 +3,24 @@ import os import os.path + def f(file): base, name = os.path.split(file) prefix = os.path.splitext(name)[0] if prefix.endswith('_strip'): return - with open(base+'/'+prefix+'_strip.py','w') as OUTPUT, \ - open(file,'r') as INPUT: + with open(base + '/' + prefix + '_strip.py', 'w') as OUTPUT, open( + file, 'r' + ) as INPUT: for line in INPUT: if line[0] == '#' and '@' in line: continue OUTPUT.write(line) -for file in glob.glob(os.path.abspath(os.path.dirname(__file__))+'/*/*.py'): +for file in glob.glob(os.path.abspath(os.path.dirname(__file__)) + '/*/*.py'): f(file) -for file in glob.glob(os.path.abspath(os.path.dirname(__file__))+'/*/*/*.py'): +for file in glob.glob(os.path.abspath(os.path.dirname(__file__)) + '/*/*/*.py'): f(file) - diff --git a/examples/pyomobook/test_book_examples.py b/examples/pyomobook/test_book_examples.py index 3d599ffe080..b2413929eaf 100644 --- a/examples/pyomobook/test_book_examples.py +++ b/examples/pyomobook/test_book_examples.py @@ -25,6 +25,7 @@ from pyomo.common.tee import capture_output import pyomo.environ as pyo + def gurobi_fully_licensed(): m = pyo.ConcreteModel() m.x = pyo.Var(list(range(2001)), within=pyo.NonNegativeReals) @@ -36,6 +37,7 @@ def gurobi_fully_licensed(): except: return False + parameterized, param_available = attempt_import('parameterized') if not param_available: raise unittest.SkipTest('Parameterized is not available.') @@ -44,7 +46,7 @@ def gurobi_fully_licensed(): currdir = this_file_dir() datadir = currdir -solver_dependencies = { +solver_dependencies = { # abstract_ch 'test_abstract_ch_wl_abstract_script': ['glpk'], 'test_abstract_ch_pyomo_wl_abstract': ['glpk'], @@ -63,26 +65,21 @@ def gurobi_fully_licensed(): 'test_abstract_ch_pyomo_AbstractH': ['ipopt'], 'test_abstract_ch_AbstHLinScript': ['glpk'], 'test_abstract_ch_pyomo_AbstractHLinear': ['glpk'], - # blocks_ch 'test_blocks_ch_lotsizing': ['glpk'], 'test_blocks_ch_blocks_lotsizing': ['glpk'], - # dae_ch 'test_dae_ch_run_path_constraint_tester': ['ipopt'], - # gdp_ch 'test_gdp_ch_pyomo_gdp_uc': ['glpk'], 'test_gdp_ch_pyomo_scont': ['glpk'], 'test_gdp_ch_pyomo_scont2': ['glpk'], 'test_gdp_ch_scont_script': ['glpk'], - # intro_ch' 'test_intro_ch_pyomo_concrete1_generic': ['glpk'], 'test_intro_ch_pyomo_concrete1': ['glpk'], 'test_intro_ch_pyomo_coloring_concrete': ['glpk'], 'test_intro_ch_pyomo_abstract5': ['glpk'], - # mpec_ch 'test_mpec_ch_path1': ['path'], 'test_mpec_ch_nlp_ex1b': ['ipopt'], @@ -94,7 +91,6 @@ def gurobi_fully_licensed(): 'test_mpec_ch_nlp2': ['ipopt'], 'test_mpec_ch_nlp3': ['ipopt'], 'test_mpec_ch_mip1': ['glpk'], - # nonlinear_ch 'test_rosen_rosenbrock': ['ipopt'], 'test_react_design_ReactorDesign': ['ipopt'], @@ -103,7 +99,6 @@ def gurobi_fully_licensed(): 'test_multimodal_multimodal_init2': ['ipopt'], 'test_disease_est_disease_estimation': ['ipopt'], 'test_deer_DeerProblem': ['ipopt'], - # scripts_ch 'test_sudoku_sudoku_run': ['glpk'], 'test_scripts_ch_warehouse_script': ['glpk'], @@ -111,40 +106,33 @@ def gurobi_fully_licensed(): 'test_scripts_ch_warehouse_cuts': ['glpk'], 'test_scripts_ch_prob_mod_ex': ['glpk'], 'test_scripts_ch_attributes': ['glpk'], - # optimization_ch 'test_optimization_ch_ConcHLinScript': ['glpk'], - # overview_ch 'test_overview_ch_wl_mutable_excel': ['glpk'], 'test_overview_ch_wl_excel': ['glpk'], 'test_overview_ch_wl_concrete_script': ['glpk'], 'test_overview_ch_wl_abstract_script': ['glpk'], 'test_overview_ch_pyomo_wl_abstract': ['glpk'], - # performance_ch 'test_performance_ch_wl': ['gurobi', 'gurobi_persistent', 'gurobi_license'], 'test_performance_ch_persistent': ['gurobi_persistent'], } -package_dependencies = { +package_dependencies = { # abstract_ch' 'test_abstract_ch_pyomo_solve4': ['yaml'], 'test_abstract_ch_pyomo_solve5': ['yaml'], - # gdp_ch 'test_gdp_ch_pyomo_scont': ['yaml'], 'test_gdp_ch_pyomo_scont2': ['yaml'], 'test_gdp_ch_pyomo_gdp_uc': ['sympy'], - # overview_ch' 'test_overview_ch_wl_excel': ['pandas', 'xlrd'], 'test_overview_ch_wl_mutable_excel': ['pandas', 'xlrd'], - # scripts_ch' 'test_scripts_ch_warehouse_cuts': ['matplotlib'], - # performance_ch' - 'test_performance_ch_wl': ['numpy','matplotlib'], + 'test_performance_ch_wl': ['numpy', 'matplotlib'], } @@ -155,7 +143,7 @@ def gurobi_fully_licensed(): available_solvers = check_available_solvers(*solvers_used) if gurobi_fully_licensed(): available_solvers.append('gurobi_license') -solver_available = {solver_:(solver_ in available_solvers) for solver_ in solvers_used} +solver_available = {solver_: (solver_ in available_solvers) for solver_ in solvers_used} package_available = {} package_modules = {} @@ -182,7 +170,8 @@ def check_skip(name): return "Solver%s %s %s not available" % ( 's' if len(_missing) > 1 else '', ", ".join(_missing), - 'are' if len(_missing) > 1 else 'is',) + 'are' if len(_missing) > 1 else 'is', + ) if name in package_dependencies: packages_ = package_dependencies[name] @@ -195,53 +184,63 @@ def check_skip(name): return "Package%s %s %s not available" % ( 's' if len(_missing) > 1 else '', ", ".join(_missing), - 'are' if len(_missing) > 1 else 'is',) + 'are' if len(_missing) > 1 else 'is', + ) # This is a hack, xlrd dropped support for .xlsx files in 2.0.1 which # causes problems with older versions of Pandas<=1.1.5 so skipping # tests requiring both these packages when incompatible versions are found - if 'pandas' in package_dependencies[name] and 'xlrd' in package_dependencies[name]: - if check_min_version(package_modules['xlrd'], '2.0.1') and \ - not check_min_version(package_modules['pandas'], '1.1.6'): + if ( + 'pandas' in package_dependencies[name] + and 'xlrd' in package_dependencies[name] + ): + if check_min_version( + package_modules['xlrd'], '2.0.1' + ) and not check_min_version(package_modules['pandas'], '1.1.6'): return "Incompatible versions of xlrd and pandas" return False + def filter(line): """ Ignore certain text when comparing output with baseline """ - for field in ( '[', - 'password:', - 'http:', - 'Job ', - 'Importing module', - 'Function', - 'File', - 'Matplotlib', - '-------', - '=======', - ' ^'): + for field in ( + '[', + 'password:', + 'http:', + 'Job ', + 'Importing module', + 'Function', + 'File', + 'Matplotlib', + '-------', + '=======', + ' ^', + ): if line.startswith(field): return True - for field in ( 'Total CPU', - 'Ipopt', - 'license', - 'Status: optimal', - 'Status: feasible', - 'time:', - 'Time:', - 'with format cpxlp', - 'usermodel =