问题
I am setting up a biggish energy optimization problem with pyomo. The setup took unreasonably long as mentioned in other questions, however I managed to speed up most of the problematic lines, except the energy flow constraints.
Opposed to all other constraints the flow includes a sum over all elements. So I decided to rewrite the way the flow variables are created so they include an index over all elements, hoping this would improve the situation. My code now looks like this:
def flows(model, et, t):
return pyo.quicksum(model.in_flow[:, et, t],
linear=True,
start=pyo.quicksum(model.out_flow[:, et, t],
linear=True)
) == 0
model.add_component("flows",
pyo.Constraint(model.energy_type,
model.t,
rule=flows)
)
However this still takes 65% of my model setup time.
I broke it down into a nested for loop just to see who takes the time:
for t in model.t:
for et in model.energy_type:
e = model.in_flow[:, et, t]
f = model.out_flow[:, et, t]
es = pyo.quicksum(e)
fs = pyo.quicksum(f)
This takes about the same runtime and "all" of it is spend in the last two lines. Chaining up the quicksums and setting the linear flag gives some minor improvements but nothing substantially. The shared code from PyPSA still uses the old coopr3 expression generator, so it does not work any more. I also could not figure out how it would be used.
Any suggestions of how to improve the model generation performance?
回答1:
Well, it turns out the problem was with the slices.
def flows(model, et, t):
vars = [model.in_flow[obj, et, t] for obj in model.objects_index]
vars.extend([model.out_flow[obj, et, t] for obj in model.objects_index])
return pyo.quicksum(vars) == 0
This refomulation of the constraint rule speed up my model creation by about 60%. I found two other places where I did a similar reformulation. I am now down from 120s before the optimisation, to about 7s.
来源:https://stackoverflow.com/questions/57849478/performance-of-creating-pyomo-constraints