3

I am new to the Gekko library in Python and wonder if I can model below LP formulation in Gekko.

LP Formulation

The LP formulation means that I want to find the optimal electric appliance schedule shift so that the total electricity cost is minimized. However, the total amount of power consumption (f_app*P_app) per day has to be consistent, as the constraint shows.

My code is shown below but, I received the following error "x must be a python list of GEKKO parameters, variables, or expressions" that I don't know how to solve.

Code:

import numpy as np
from gekko import GEKKO

m = GEKKO()
m.time = np.linspace(1, 24, 24)

TOU_list = [0.074646,0.074646,0.074646,0.074646,0.074646,0.074646,\
            0.074646,0.099206,0.099206,0.099206,0.099206,\
            0.169230,0.169230,0.169230,0.169230,0.169230,0.099206,\
            0.099206,0.099206,0.099206,0.074646,0.074646,\
            0.074646,0.074646] # Electricity Cost
        
TOU = m.Param(value= TOU_list)
P_app = 10.5 # Appliance power (kW)
f_app = m.MV(lb=0.0, ub=1.0, integer=False) # electric appliance schedule (0-1)

m.Equation(m.sum(f_app) == 15) # Summation of the appliance schedule for 24 hour time horizon         

m.Minimize(TOU*f_app*P_app)

m.options.IMODE = 6
m.options.SOLVER = 3
m.solve(disp=True, GUI=False)
John Hedengren
  • 12,068
  • 1
  • 21
  • 25
chloe ahn
  • 31
  • 1

1 Answers1

2

The m.sum() is a summation of values at that particular time point. Try m.integral() instead to generated a summation over the time horizon. Use m.fix_final(c,15) to fix the final value of the integral at 15. Use m.options.SOLVER=1 with integer=True or the appliance can turn on to a fractional value.

Electricity Usage

import numpy as np
from gekko import GEKKO

m = GEKKO()
m.time = np.linspace(0, 24, 25)

# Electricity Cost
TOU_list = [0.074646,0.074646,0.074646,0.074646,0.074646,0.074646,\
            0.074646,0.074646,0.099206,0.099206,0.099206,0.099206,\
            0.169230,0.169230,0.169230,0.169230,0.169230,0.099206,\
            0.099206,0.099206,0.099206,0.074646,0.074646,\
            0.074646,0.074646] 
        
TOU = m.Param(value= TOU_list)
P_app = 10.5 # Appliance power (kW)
# electric appliance schedule (0-1)
f_app = m.MV(value=0,lb=0.0, ub=1.0, integer=True)
f_app.STATUS = 1

# Summation of the appliance schedule for 24 hour time horizon
c = m.integral(f_app)
m.fix_final(c,15)

m.Minimize(TOU*f_app*P_app)

m.options.IMODE = 6
m.options.SOLVER = 1
m.solve(disp=True, GUI=False)

import matplotlib.pyplot as plt
plt.plot(m.time,f_app.value,label='On / Off')
plt.plot(m.time,TOU_list,label='Electricity Cost')
plt.legend()
plt.show()

I added an additional time point at the beginning because it is 24 hours with 25 time points total. If there is 1 hour then there needs to be two time points for the optimization problem to define the start and the end. For 24 hours, there needs to be 25 points.

You can avoid some of the complications with a dynamic control mode by programming 24 time periods with an m.Array(). This way you can use the m.sum() because f_app is an array of 24 values.

Solution - discrete

import numpy as np
from gekko import GEKKO

m = GEKKO()

# Electricity Cost
TOU_list = [0.074646,0.074646,0.074646,0.074646,0.074646,0.074646,\
            0.074646,0.099206,0.099206,0.099206,0.099206,\
            0.169230,0.169230,0.169230,0.169230,0.169230,0.099206,\
            0.099206,0.099206,0.099206,0.074646,0.074646,\
            0.074646,0.074646] 
n = len(TOU_list)
        
P_app = 10.5 # Appliance power (kW)
# electric appliance schedule (0-1)
f_app = m.Array(m.Var,n,value=0,lb=0.0, ub=1.0, integer=True)

# Summation of the appliance schedule for 24 hour time horizon
m.Equation(m.sum(f_app)==15)

for i in range(n):
    m.Minimize(TOU_list[i]*f_app[i]*P_app)

m.options.IMODE = 3
m.options.SOLVER = 1
m.solve(disp=True)

f = []
t = []
for i in range(n):
    t.append(i+1)
    f.append(f_app[i].value[0])

import matplotlib.pyplot as plt
plt.bar(x=t,height=f,label='On / Off')
plt.bar(x=t,height=TOU_list,label='Electricity Cost')
plt.legend()
plt.show()

Because the problem doesn't have differential equations, I recommend the second approach.

John Hedengren
  • 12,068
  • 1
  • 21
  • 25