简体   繁体   中英

GEKKO if3 variable giving unexpected results in optimisation

I've been trying to learn how to use Gekko and am currently trying to model optimal battery charge/discharge based in input/output prices (taking inspiration from here and here .

Below is my following code.

from gekko import Gekko
import numpy as np
m = Gekko()

electricity_price_in = np.random.uniform(low=0.1, high=1, size=50)
electrictiy_price_out = np.random.uniform(low=0.3, high=3, size=50)


E_battery = m.Var(lb=0, ub=366.2, value=0) #energy in battery at time t, battery size 366 MWh
Pc = m.Var(lb=0, ub=50) #charge power, 50 MW max
Pd = m.Var(lb=0, ub=36.6)  #discharge power, max 36 MW
E_price_in = m.Param(electricity_price_in)
E_price_out = m.Param(electrictiy_price_out)
m.time = np.linspace(0,49, 50)

Revenue =  m.Intermediate(Pd*E_price_out)
Cost = m.Intermediate(Pc*E_price_in)

m.Equation(E_battery.dt() == Pc-Pd)
m.Equation(E_battery >= 0)

m.Maximize(Revenue - Cost)
m.options.IMODE = 6
m.solve()

This appears to work ok. However, I get very different results if I include the following code:

isCharging = m.if3(-Pc,1,0)
isDischarging = m.if3(-Pd,1,0)

What I believe I am doing is creating two variables. As they are not constraint equations and are not included in the objective function, I would have expected the inclusion of this to make no changes to my results, however my code gives very different results (all variables turn into a list of zeroes).

Why would adding these two variables change my results?

The m.if3() function changes the default solver from IPOPT to APOPT so that it can solve the Mixed Integer Optimization problem. APOPT solver found a different (worse) local solution so you were seeing a difference.

Also, the random number generator needs a seed value to give the same results each time such as np.random.seed(1) . The additional variables and equations associated with the m.if3() function can also require more iterations. Try using a warm-start for APOPT that is initialized with the IPOPT solution.

This script gives the same answer whether the m.if3() statements are present or not.

from gekko import Gekko
import numpy as np
m = Gekko()

np.random.seed(1)
electricity_price_in = np.random.uniform(low=0.1, high=1, size=50)
electrictiy_price_out = np.random.uniform(low=0.3, high=3, size=50)

E_battery = m.Var(lb=0, ub=366.2, value=0) #energy in battery at time t, battery size 366 MWh
Pc = m.Var(lb=0, ub=50) #charge power, 50 MW max
Pd = m.Var(lb=0, ub=36.6)  #discharge power, max 36 MW
E_price_in = m.Param(electricity_price_in)
E_price_out = m.Param(electrictiy_price_out)
m.time = np.linspace(0,49, 50)

Revenue =  m.Intermediate(Pd*E_price_out)
Cost = m.Intermediate(Pc*E_price_in)

m.Equation(E_battery.dt() == Pc-Pd)
m.Equation(E_battery >= 0)

m.Maximize(Revenue - Cost)

isCharging = m.if3(-Pc,1,0)
isDischarging = m.if3(-Pd,1,0)

m.options.IMODE = 6

m.options.SOLVER = 3
m.solve(disp=False)
print('Objective (IPOPT)', m.options.objfcnval)

m.options.TIME_SHIFT = 0
m.options.SOLVER = 1
m.solve()
print('Objective (APOPT)', m.options.objfcnval)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM