Pyomo Error: TypeError: 'MonomialTermExpression' object is not iterable - pyomo

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)

Related

Django - aggregation zero

I've got the following in my views.py :
called = CashFlow.objects.filter(item__slug=itemslug).filter(type='cashin').aggregate(sum=Sum('amount'))['sum']
distributed = CashFlow.objects.filter(item__slug=itemslug).filter(type='cashout').aggregate(sum=Sum('amount'))['sum']
try:
result = round(-distributed/called * 100,2)
except ZeroDivisionError :
result = 0
Everything works fine as long as one of the queries return something. but, let's say there haven't been any cashouts so far -> the result should be zero. However, I receive the following Typerror : "bad operand type for unary -: 'NoneType'"
How can I solve this?
many thanks in advance
Add this before your try/except:
if distributed is None:
distributed = 0
Or add or 0 after the CashFlow query:
distributed = (CashFlow.objects
.filter(item__slug=itemslug)
.filter(type='cashout')
.aggregate(sum=Sum('amount'))['sum']) or 0
Do the same with called.
Add TypeError to your exceptions in except
try:
result = round(-distributed/called * 100,2)
except (ZeroDivisionError, TypeError) as e :
result = 0

Why cannot I convert from 'Nonetype' to float?

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.

Pyomo cannot iterate over abstract Set and constraint index error

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)

Convert a concrete model in an abstract one

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()

get or create - unsupported operand type(s) for +=: 'builtin_function_or_method'

models:
class TestVersion(models.Model):
test = models.ForeignKey(Test)
count = models.IntegerField(default=0)
views:
test = Test.objects.get(id=id)
result = TestVersion.objects.get_or_create(test=test)
result.count += 1
result.save()
I have this error:
unsupported operand type(s) for +=: 'builtin_function_or_method' and
'int'
on line: result.count += 1
How to fix it?
try this: result, created = TestVersion.objects.get_or_create(test=test)
get_or_create returns a tuple of (object, created), where object is the retrieved or created object and created is a boolean specifying whether a new object was created.
Look here for a reference: https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create