CVXOPT солнечный + аккумулятор с ценой зарядки / разрядки оптимизация glpk - PullRequest
0 голосов
/ 06 марта 2020

У меня есть следующий df. батарея может заряжаться только от солнечной батареи и предпочитает брать урезанную / свободную солнечную батарею, поскольку это устанавливает новый предел того, сколько может покинуть систему. У меня было непростое время, чтобы разделить модель на energy_in и energy_out батареи с помощью cvxopt. Любая помощь очень ценится. enter image description here

'''
 GLPK OPTIMIZER BELOW:
'''
df = df[~pd.isnull(df['timestamp'])]
max_dispatch = 110
rte = 0.88 #round trip efficiency (RTE) of the system from PV to Battery to Grid
df['pv'] = pd.to_numeric(df['pv'], errors='coerce').fillna(0.0)
df['pv'] = df['pv']
df['pv_minus_curtail'] = df['pv'] - (df['pv_clip']) # we've addded pv_clip to pv above
df['poi_curtail_limit'] = np.where(df['pv_clip']>0, df['pv_minus_curtail'], max_dispatch )
df['price'] = df['price']
df['is_curtail'] = np.where(df['pv_clip'] > 0, 1, 0)

df['battery_level'] = 0.0
battery_capacity = cp.Parameter(nonneg=True)
battery_capacity.value = 220 / rte
discharge_max = cp.Parameter(nonneg=True)
# for australia data that is in 30min intervals = max for every 30min, so the actual MW is discharge_max*2
discharge_max.value = 55 / rte 
charge_max = cp.Parameter(nonneg=True)
charge_max.value = 55
x_in = cp.Variable(len(df.index))
x_out = cp.Variable(len(df.index))

price = df['price'].values
pv = df['pv'].values
batt_level = cp.cumsum((x_in) + (x_out))

curtail_limit = df['poi_curtail_limit'].values
pv_net_curtail = df['pv_minus_curtail'].values
pv_clip = df['pv_clip'].values
is_curtail = df['is_curtail'].values


constraints = [
    batt_level >= 0.0, # can't have negative battery 
    batt_level <= battery_capacity, # can't go above battery
    x_out >= -1*discharge_max, #don't discharge faster than it can handle it
    x_in <= charge_max, #no charging faster than allowed
    x_in <= pv, # constrained by PV generation
    x_out <= 0,
    x_in >= 0,

]
rev = cp.sum( cp.minimum (pv - x_in - (x_out * rte), curtail_limit) * price)
prob = cp.Problem(cp.Maximize(rev), constraints) # Maximize revenue, conditional on constraints

start_time = time()

prob.solve(solver='GLPK_MI', verbose=True)

df.loc[:,'mw_in'] = x_in.value
df.loc[:,'mw_out'] = x_out.value

df.loc[:,'battery_level'] = np.cumsum(df['mw_in'] + (df['mw_out']))
#df['rev']
# Put things back in data frame for inpsection
#df.loc[:,'charge'] = np.where(np.abs(df['charge']) > 0.001, df['charge']*scale, 0.0)
df.loc[:,'mw_poi'] = df['pv'] - df['mw_in'] - (df['mw_out'] * rte)

df.loc[:,'rev'] = (df['mw_poi']) * df['price']

mw_in и mw_out не могут происходить одновременно. Как я могу добавить это ограничение в? Извините, я не знаю, как добавить сюда саму df. Спасибо !!

1 Ответ

0 голосов
/ 06 марта 2020

Условие x=0 or y=0 иногда называют ограничением комплементарности . Его также можно записать как x*y=0. CVXOPT и GLPK не поддерживают такие ограничения напрямую. Однако мы можем реализовать это ограничение, используя двоичные переменные.

 x ≤ U1 δ
 y ≤ U2 (1-δ)
 x ∈ [0,U1]
 y ∈ [0,U2]
 δ ∈ {0,1}

Здесь U1 (U2) - верхняя граница для x (y). Если у вас нет хороших границ U1, U2, некоторые решатели MIP поддерживают так называемые переменные SOS1 (Специальный упорядоченный набор типа 1), которые могут помочь.

...