Ограниченная оптимизация планирования батареи в микросети - PullRequest
0 голосов
/ 10 июля 2019

Учитывая данные, такие как потребление электроэнергии, выработка от солнечной панели, цена, (все в данный момент времени t), у нас есть батарея, и мы хотим оценить, сколько она должна (разряжать) / заряжать в любой момент времени.Проблема может быть сформулирована следующим образом:

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

функция, которую мы пытаемся оптимизировать, является Ct = Pt *(Lt - St - Qt)

. Это направлено на минимизацию количества покупаемой электроэнергии

При следующих ограничениях:

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)

У меня возникла проблема, как сформулировать в Python (Scipy) проблема, особенно обновление уровня заряда батареи.

Я знаю, что существуют другие библиотеки (Pyomo, Pulp), решения в которых будут приветствоваться.

Ответы [ 2 ]

1 голос
/ 14 июля 2019

Вам повезло, я был мотивирован ответом Джорджио на изучение pyomo (я в основном пользователь PULP), поэтому использовал ваш вопрос как шанс убедиться, что я понял все интерфейсы. Я опубликую это здесь, чтобы я мог найти это снова сам в будущем:

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)
1 голос
/ 12 июля 2019

По моему опыту (линейная / MIP) оптимизация является правильным подходом для такого рода приложений. На мой взгляд (мнение, да), Pyomo - отличный инструмент:

  • написано на Python
  • отличный дизайн
  • имеет наиболее распространенные функции из других языков моделирования (AMPL, GAMS ...)
  • имеет простые интерфейсы для большинства решателей
  • это очень хорошо поддерживается (проверьте страницу Github)

Документация довольно обширна и размещена здесь: https://pyomo.readthedocs.io/en/latest/index.html

Вы можете найти еще несколько материалов здесь: https://pyomo.readthedocs.io/en/latest/tutorial_examples.html

Кроме того, this является ссылкой на довольно обширное введение в Pyomo, которое сводится к довольно сложным темам, таким как стохастическая оптимизация и двухуровневые проблемы.

Наконец, единственная конкретная проблема для вашего случая - это тот факт, что вы, вероятно, хотите понести убытки при зарядке и разрядке батареи. В качестве справки, вероятно, хорошей идеей будет определить две независимые переменные для зарядки и разрядки (обе они неотрицательные), чтобы вы могли записать энергетический баланс батареи как ограничение, связывающее состояние энергии (SOE) ) во время t с SOE во время t+1.

Удачи!

...