问题
Given inputs such as electricity consumption, generation from solar panel, price, (All at a given time t), we have a battery, and we want to evaluate how much it should (dis)/charge at any given time. The Problem can be formulated as follows:
Pt = price of electricity at time t
Lt = consumption of electricity at time t
Zt = charge of battery at time t (how much is in the battery)
St = Electricity generated from solar generator at time t
Qt = amount the battery (dis)/charges at time t
the function we are trying to optimise is
Ct = Pt *(Lt - St - Qt)
This aims to minimise the amount of electricity purchased
With the following constraints:
Lt - St - Qt >= 0 (our demand has to be non-negative)
Qmin <= Qt <= Qmax ( the battery can only (dis)/charge between certain values at any given time)
Zmin <= Zt <= Zmax. (the battery has to be within its capacity, i.e. you can't discharge more than the battery holders, and you can charge more than the battery can hold)
Zt+1 = Zt + Qt+1 ( this means that the battery level at the next time step is equal to the battery level at the previous time step plus the amount that was (dis)/charged from the battery)
The problem I am having how to formulate in python (Scipy) the problem, particularly updating the battery levels.
I know other library's (Pyomo, Pulp) exist, solutions in that would be welcome.
回答1:
You're in luck, I was motivated by Giorgio's answer to learn pyomo (I mostly user PULP), so used your question as a chance to make sure I understood all the interfaces. I'll post it here so I can find it again myself in the future:
import pyomo.environ as pyomo
import numpy as np
# create model
m = pyomo.ConcreteModel()
# Problem DATA
T = 24
Zmin = 0.0
Zmax = 2.0
Qmin = -1.0
Qmax = 1.0
# Generate prices, solar output and load signals
np.random.seed(42)
P = np.random.rand(T)*5.0
S = np.random.rand(T)
L = np.random.rand(T)*2.0
# Indexes
times = range(T)
times_plus_1 = range(T+1)
# Decisions variables
m.Q = pyomo.Var(times, domain=pyomo.Reals)
m.Z = pyomo.Var(times_plus_1, domain=pyomo.NonNegativeReals)
# objective
cost = sum(P[t]*(L[t] - S[t] - m.Q[t]) for t in times)
m.cost = pyomo.Objective(expr = cost, sense=pyomo.minimize)
# constraints
m.cons = pyomo.ConstraintList()
m.cons.add(m.Z[0] == 0.5*(Zmin + Zmax))
for t in times:
m.cons.add(pyomo.inequality(Qmin, m.Q[t], Qmax))
m.cons.add(pyomo.inequality(Zmin, m.Z[t], Zmax))
m.cons.add(m.Z[t+1] == m.Z[t] - m.Q[t])
m.cons.add(L[t] - S[t] - m.Q[t] >= 0)
# solve
solver = pyomo.SolverFactory('cbc')
solver.solve(m)
# display results
print("Total cost =", m.cost(), ".")
for v in m.component_objects(pyomo.Var, active=True):
print ("Variable component object",v)
print ("Type of component object: ", str(type(v))[1:-1]) # Stripping <> for nbconvert
varobject = getattr(m, str(v))
print ("Type of object accessed via getattr: ", str(type(varobject))[1:-1])
for index in varobject:
print (" ", index, varobject[index].value)
回答2:
In my experience (linear / MIP) optimization is a valid approach for this kind of applications. In my opinion (opinion, yeah), Pyomo is a great tool:
- it's written in Python
- the overall design is great
- it has most common features from other modeling languages (AMPL, GAMS...)
- it has simple interfaces for most solvers
- it's very well maintained (check the Github page)
The documentation is quite extensive and is hosted here: https://pyomo.readthedocs.io/en/latest/index.html
You can find some more material here: https://pyomo.readthedocs.io/en/latest/tutorial_examples.html
Also, this is a link to a quite extensive introduction to Pyomo, which goes down to quite advanced topics such as stochastic optimization and bi-level problems.
Finally, the only specific issue to your case is the fact that you probably want to apply losses to charging and discharging the battery. As a heads up, it's probably a good idea to define two independent variables for charging and discharging (both of them being non-negative), so that you can write the energy balance of the battery as a constraint linking the State of Energy (SOE) at time t
with the SOE at time t+1
.
Good luck!
来源:https://stackoverflow.com/questions/56968971/constrained-optimization-of-battery-scheduling-in-microgrid