I am new to Pyomo so this may be a silly question to ask. I am trying to build a 4-zone UC/ED model with many generators in each zone. So I set the model up in the following way:
model.Zone1Generators = Set()
model.Zone2Generators = Set()
model.Zone3Generators = Set()
model.Zone4Generators = Set()
model.Generators = model.Zone1Generators | model.Zone2Generators | model.Zone3Generators | model.Zone4Generators
When I run the model, I got the following error message:
ERROR: Rule failed when generating expression for constraint Local1:
RuntimeError: Cannot iterate over abstract Set 'Zone1Generators' before it has been constructed (initialized).
The related constraint is posted below:
def WECC1(i):
if i > 0:
seg1 = sum(model.mwh_1[j,i] for j in model.Zone1Generators)
seg2 = sum(model.mwh_2[j,i] for j in model.Zone1Generators)
seg3 = sum(model.mwh_3[j,i] for j in model.Zone1Generators)
renew = model.hydro[model.zones[0],i] + model.solar[model.zones[0],i]\
+ model.wind[model.zones[0],i] + model.pumpstorage[model.zones[0],i]
return seg1 + seg2 + seg3 + renew >= 0.25*model.HorizonDemand[model.zones[0],i]
else:
return Constraint.Skip
model.Local1= Constraint(rule=WECC1)
I think it may be caused by the fact that I didn’t pass all the model information. So I changed the constraint from def WECC1(i) to WECC1(model,i). This gives me a new error message:
ERROR: Unexpected exception while running model:
WECC1() takes exactly 2 arguments (1 given)
Any help would be very appreciated.
You need to provide the indexing set to the constraint in order to declare an indexed constraint
model.Local1 = Constraint(model.Generators, rule=WECC1)
Related
I keep getting this error - "TypeError: 'MonomialTermExpression' object is not iterable" - from the constraint component below of my AbstractModel Construction. However, I do not seem to understand this error and how to fix it. I shall be glad if anyone on this platform could point me in the right direction.
Thank you.
model.Q = pyo.Var(initialize=0.000001, within=pyo.PercentFraction, name='Variable for MinMax MOMP')
def wt_rule1(model,i,j):
for (i,j), val in model.w.extract_values().items():
return (val*(sum(model.d[i,j]*model.x[i,j])-291)/291.0) <= model.Q
model.distConst = pyo.Constraint(model.A,rule=wt_rule1)
After playing around with this many times, I have realized that re-constructing the constraint object as follows worked:
def wt_rule1(model,i,j):
for (i,j), val in model.w.extract_values().items():
return (val*(sum(model.d[i,j]*model.x[i,j] for i in model.I for j in model.J)-291)/291) <= model.Q
model.distConst = pyo.Constraint(model.A, rule=wt_rule1)
I am trying to save a model but am unable to because of a TypeError I am being given.
I have looked at other answers with similar errors but they are different problems.
now = dateTime.now()
miliTime = int(str(now.hour) + str(now.minute)
timeConvert = miliTime - 1200
timeString = str(timeConvert)
standard_t = timeString[:1] + ":" + timeString[1:]
standardTime = standard_t + " " + p
time_1 = standard_time
time_2 = standard_time
user = StaffMember.objects.get(id = request.session['client']['id'])
userPunchCard = PunchCard.objects.get(employee = StaffMember.objects.get(name = user.name))
punch = []
try:
if len(userPunchCard.time.punch) < 2:
punch.append(time_2)
userPunchCard.time = punch
userPunchCard.save()
except:
punch.append(time_1)
userPunchCard.time = punch
userPunchCard.save()
The main issue is trying to save the array. The try and except is to check for a punch if present.
Here's the full error message
TypeError: int() argument must be string, a bytes-like object or a number, not a 'list'.
Turns out, my model for time was only accepting an int object and the whole time I was forcing a string into it. I had to change the integerField to a CharField in my models file for time.
I am trying to save the solutions of this optimization problem but they are Nonetype. Therefore I want to convert them to float but I get this error:
float() argument must be a string or a number, not 'NoneType'
It is rare due to in the printed solution from results.write() x1 is 6.57142857142857.
from coopr . pyomo import *
from pyomo.opt import SolverFactory
def create_model(N=[], M=[], c={}, a={}, b={}):
model = ConcreteModel()
model.x = Var(N, within=NonNegativeReals)
model.obj = Objective(expr=sum(c[i]*model.x[i] for i in N))
def con_rule(model, m):
return sum(a[i,m]*model.x[i] for i in N) >= b[m]
model.con = Constraint(M, rule=con_rule)
return model
model = create_model(N = [1,2], M = [1,2], c = {1:1, 2:2},
a = {(1,1):5, (2,1):4, (1,2):7, (2,2):3},
b = {1:11, 2:46})
#model.pprint()
instance = model.create()
#instance.pprint()
opt = SolverFactory("glpk")
results = opt.solve(instance, load_solutions=False)
results.write()
x_1=float( model.x[1].value)
#x_2=float( model.x[2].value or 0)
First, model.create() is deprecated on the most recent version of Pyomo. I believe it is now renamed to model.create_instance.
Second, you are solving the instance object returned from model.create(), which is a different object from model. Therefore, you should be accessing the .value attribute of variables on the instance object and not the model object.
Third, you are starting from a ConcreteModel, which means there is no need to call model.create() (or model.create_instance()). This is simply creating an unnecessary copy of what is already a "concrete instance". I.e., you could send the model object to the solver and the code accessing .value would work as is.
The create_instance method is only necessary when you start from an AbstractModel, where you then typically pass the name of some .dat file to it.
I am just starting with Pyomo and I have a big problem.
I want to run an Abstract Model without using the terminal. I can do it with a concrete model but I have serious problems to do it in with the abstract one.
I just want to use F5 and run the code.
This ismy program:
import pyomo
from pyomo.environ import *
#
# Model
#
model = AbstractModel()
#Set: Indices
model.Unit = Set()
model.Block = Set()
model.DemBlock = Set()
#Parameters
model.EnergyBid = Param(model.Unit, model.Block)
model.PriceBid = Param(model.Unit, model.Block)
model.EnergyDem = Param(model.DemBlock)
model.PriceDem = Param(model.DemBlock)
model.Pmin = Param(model.Unit)
model.Pmax = Param(model.Unit)
#Variables definition
model.PD = Var(model.DemBlock, within=NonNegativeReals)
model.PG = Var(model.Unit,model.Block, within=NonNegativeReals)
#Binary variable
model.U = Var(model.Unit, within = Binary)
#Objective
def SocialWellfare(model):
SocialWellfare = sum([model.PriceDem[i]*model.PD[i] for i in model.DemBlock]) - sum([model.PriceBid[j,k]*model.PG[j,k] for j in model.Unit for k in model.Block ])
return SocialWellfare
model.SocialWellfare = Objective(rule=SocialWellfare, sense=maximize)
#Constraints
#Max and min Power generated
def PDmax_constraint(model,p):
return ((model.PD[p] - model.EnergyDem[p])) <= 0
model.PDmax = Constraint(model.DemBlock, rule=PDmax_constraint)
def PGmax_constraint(model,n,m):
return ((model.PG[n,m] - model.EnergyBid[n,m])) <= 0
model.PGmax = Constraint(model.Unit, model.Block,rule = PGmax_constraint)
def Power_constraintDW(model,i):
return ((sum(model.PG[i,k] for k in model.Block))-(model.Pmin[i] * model.U[i]) ) >= 0
model.LimDemandDw = Constraint(model.Unit, rule=Power_constraintDW)
def Power_constraintUP(model,i):
return ((sum(model.PG[i,k] for k in model.Block) - (model.Pmax[i])*model.U[i])) <= 0
model.LimDemandaUp = Constraint(model.Unit, rule=Power_constraintUP)
def PowerBalance_constraint(model):
return (sum(model.PD[i] for i in model.DemBlock) - sum(model.PG[j,k] for j in model.Unit for k in model.Block)) == 0
model.PowBalance = Constraint(rule = PowerBalance_constraint)
model.pprint()
instance = model.create('datos_transporte.dat')
## Create the ipopt solver plugin using the ASL interface
solver = 'ipopt'
solver_io = 'nl'
opt = SolverFactory(solver,solver_io=solver_io)
results = opt.solve(instance)
results.write()
Any help with the last part??
Thanks anyway,
I think your example is actually working. Starting in Pyomo 4.1, the solution returned from the solver is stored directly into the instance that was solved, and is not returned in the solver results object. This change was made because generating the representation of the solution in the results object was rather expensive and was not easily parsed by people. Working with the model instance directly is more natural.
It is unfortunate that the results object reports the number of solutions: 0, although this is technically correct: the results object holds no solutions ... but the Solver section should indicate that a solution was returned and stored into the model instance.
If you want to see the result returned by the solver, you can print out the current status of the model using:
instance.display()
after the call to solve(). That will report the current Var values that were returned from the solver. You will want to pay attention to the stale column:
False indicates the value is not "stale" ... that is, it was either set by the user (before the call to solve()), or it was returned from the solver (after the call to solve()).
True indicates the solver did not return a value for that variable. This is usually because the variable was not referenced by the objective or any enabled constraints, so Pyomo never sent the variable to the solver.
[Note: display() serves a slightly different role than pprint(): pprint() outputs the model structure, whereas display() outputs the model state. So, for example, where pprint() will output the constraint expressions, display() will output the numerical value of the expression (using the current variable/param values).]
Edited to expand the discussion of display() & pprint()
How can I handle this error, its driving me crazy:
unsupported operand type(s) for +: 'NoneType' and 'NoneType'
Also
unsupported operand type(s) for +: 'Float' and 'NoneType'
I get what its telling me (I think) so this is the code I wrote to try and battle it
View:
session = request.session._session_key
ind = signedup.objects.filter(sessionid = session)
team = team_signup.objects.filter(sessionid = session)
combine = list(chain(ind, team))
check = signedup.objects.filter(sessionid = session).count() + team_signup.objects.filter(sessionid = session).count()
ind = signedup.objects.filter(sessionid = session).aggregate(Sum ('price'))['price__sum']
team = team_signup.objects.filter(sessionid = session).aggregate(Sum ('price'))['price__sum']
if check == 0:
carttotal = 0.00
elif ind == None:
ind = 0.00
elif team == None:
team = 0.00
carttotal = ind + team
return render_to_response("cart.html",locals(),context_instance = RequestContext(request))
I figured what I was doing was setting their values to 0 before adding it up if it happened to be come up with none as a value. Is there another way to handle this so that when one of them does come up none, it gets set to zero so it can be added. Also when BOTH come up to none they can be set to 0 so that they can be added.
Part of the problem is probably the if/elif logic. Remember that elif will only run if the first if statement registers as false. So, imagine this scenario:
check = 0
ind = None
team = None
In that scenario, the first that that happens is that carttotal gets set equal to 0. Then, since the first if was true (check was 0), the remaining elifs don't run, and ind + team try get added even though they haven't been changed from None.
There are more elegant ways to do this, but if you just change the elifs to ifs, it should work fine. There's some redundancy there, though, and shorten the logic to by a few lines by using a tertiary operator
ind_query = signedup.objects.filter(sessionid = session)
ind = ind_query.aggregate(Sum ('price'))['price__sum'] if ind_query else 0
team_query = team_signup.objects.filter(sessionid = session)
team = team_query.aggregate(Sum ('price'))['price__sum'] if team_query else 0
carttotal = ind + team