I am trying to understand how gekko and its different types of custom variables work. So I wrote a very simple optimization problem, but it won’t find the optimal solution, at least this is what i think the error message means.
The code is a simple set switch combination (braco_gas and braco_eh, both binaries) multiplied by some weights (vazao and volume, both continuos).
I want to find which combination of switches and weights yields the maximum objective value. See below the objective:
Objective = vazao_gas * braco_gas_1 + volume_gas * braco_gas_2 + vazao_eh * braco_eh_1 + volume_eh * braco_eh_2
See the code below:
from gekko import GEKKO import numpy as np m = GEKKO(remote=False) # binary variables braco_gas_1 = m.Var(integer=True, lb=0,ub=1) braco_eh_1 = m.Var(integer=True, lb=0,ub=1) braco_gas_2 = m.Var(integer=True, lb=0,ub=1) braco_eh_2 = m.Var(integer=True, lb=0,ub=1) # continuous variables vazao_gas = m.Var(value=100,lb=0,ub=150) vazao_eh = m.Var(value=100,lb=0,ub=150) #constants volume_gas = 1000 volume_eh = 2000 # I want to see each parcel of the objective tempo_b1 = m.MV(vazao_gas*braco_gas_1 + volume_gas*braco_gas_2) tempo_b1.STATUS=1 tempo_b2 = m.MV(vazao_eh*braco_eh_1 + volume_eh*braco_eh_2) tempo_b2.STATUS=1 # that is supposed to be the objective tempo_total = m.MV(tempo_b1+tempo_b2, lb=0, ub = 4000) tempo_total.STATUS=1 # Only of binary variable of each group can be true m.Equation (braco_gas_1+braco_gas_2 == 1) m.Equation (braco_eh_1+braco_eh_2 == 1) # I want to maximize the objective m.Maximize(tempo_b1+tempo_b2) m.options.SOLVER = 1 m.solve() # solve print('Braco_gas_1:'+str(braco_gas_1.value)) print('Braco_gas_2:'+str(braco_gas_2.value)) print('Braco_eh_1:'+str(braco_eh_1.value)) print('Braco_eh_2:'+str(braco_eh_2.value)) print('vazao_gas:'+str(vazao_gas.value)) print('vazao_eh:'+str(vazao_eh.value)) print('volume_gas:'+str(volume_gas)) print('volume_eh:'+str(volume_eh)) print('tempo_b1:'+str(tempo_b1.value)) print('tempo_b2:'+str(tempo_b2.value)) print('tempo_total:'+str(tempo_total.value))
Following the error message:
---------------------------------------------------------------- APMonitor, Version 1.0.0 APMonitor Optimization Suite ---------------------------------------------------------------- --------- APM Model Size ------------ Each time step contains Objects : 0 Constants : 0 Variables : 9 Intermediates: 0 Connections : 0 Equations : 3 Residuals : 3 Number of state variables: 9 Number of total equations: - 2 Number of slack variables: - 0 --------------------------------------- Degrees of freedom : 7 ---------------------------------------------- Steady State Optimization with APOPT Solver ---------------------------------------------- Iter: 1 I: 0 Tm: 0.00 NLPi: 4 Dpth: 0 Lvs: 3 Obj: -1.00E+15 Gap: NaN Iter: 2 I: -1 Tm: 0.00 NLPi: 0 Dpth: 1 Lvs: 2 Obj: -1.00E+15 Gap: NaN Iter: 3 I: -2 Tm: 0.00 NLPi: 2 Dpth: 1 Lvs: 1 Obj: -1.00E+15 Gap: NaN Iter: 4 I: -2 Tm: 0.00 NLPi: 2 Dpth: 1 Lvs: 0 Obj: -1.00E+15 Gap: NaN Warning: no more possible trial points and no integer solution Maximum iterations --------------------------------------------------- Solver : APOPT (v1.0) Solution time : 0.0208 sec Objective : -1.E+15 Unsuccessful with error code 0 --------------------------------------------------- Creating file: infeasibilities.txt Use command apm_get(server,app,'infeasibilities.txt') to retrieve file @error: Solution Not Found --------------------------------------------------------------------------- Exception Traceback (most recent call last) ~AppDataLocalTemp/ipykernel_10100/3307325789.py in <module> 32 m.options.SOLVER = 1 33 ---> 34 m.solve() # solve 35 36 print('Braco_gas_1:'+str(braco_gas_1.value)) ~Anaconda3libsite-packagesgekkogekko.py in solve(self, disp, debug, GUI, **kwargs) 2138 print("Error:", errs) 2139 if (debug >= 1) and record_error: -> 2140 raise Exception(apm_error) 2141 2142 else: #solve on APM server Exception: @error: Solution Not Found
Advertisement
Answer
The problem is currently unbounded (see Objective: -1.E+15
).
Use m.Intermediate()
instead of m.MV()
. An MV
(Manipulated Variable) is a degree of freedom that the optimizer can use to achieve an optimal objective among all of the feasible solutions. Because tempo_b1
, tempo_b2
, and tempo_total
all have equations associated with solving them, they need to either be:
- Regular variables with
m.Var()
and a correspondingm.Equation()
definition - Intermediate variables with
m.Intermediate()
to define the variable and equation with one line.
Here is the solution to the simple Mixed Integer Linear Programming (MINLP) optimization problem.
---------------------------------------------------------------- APMonitor, Version 1.0.1 APMonitor Optimization Suite ---------------------------------------------------------------- --------- APM Model Size ------------ Each time step contains Objects : 0 Constants : 0 Variables : 7 Intermediates: 2 Connections : 0 Equations : 6 Residuals : 4 Number of state variables: 7 Number of total equations: - 3 Number of slack variables: - 0 --------------------------------------- Degrees of freedom : 4 ---------------------------------------------- Steady State Optimization with APOPT Solver ---------------------------------------------- Iter: 1 I: 0 Tm: 0.00 NLPi: 4 Dpth: 0 Lvs: 0 Obj: -3.00E+03 Gap: 0.00E+00 Successful solution --------------------------------------------------- Solver : APOPT (v1.0) Solution time : 1.529999999911524E-002 sec Objective : -3000.00000000000 Successful solution ---------------------------------------------------
Braco_gas_1:[0.0] Braco_gas_2:[1.0] Braco_eh_1:[0.0] Braco_eh_2:[1.0] vazao_gas:[150.0] vazao_eh:[150.0] volume_gas:1000 volume_eh:2000 tempo_b1:[1000.0] tempo_b2:[2000.0] tempo_total:[3000.0]
The complete script:
from gekko import GEKKO import numpy as np m = GEKKO(remote=False) # binary variables braco_gas_1 = m.Var(integer=True, lb=0,ub=1) braco_eh_1 = m.Var(integer=True, lb=0,ub=1) braco_gas_2 = m.Var(integer=True, lb=0,ub=1) braco_eh_2 = m.Var(integer=True, lb=0,ub=1) # continuous variables vazao_gas = m.Var(value=100,lb=0,ub=150) vazao_eh = m.Var(value=100,lb=0,ub=150) #constants volume_gas = 1000 volume_eh = 2000 # I want to see each parcel of the objective tempo_b1 = m.Intermediate(vazao_gas*braco_gas_1 + volume_gas*braco_gas_2) tempo_b2 = m.Intermediate(vazao_eh*braco_eh_1 + volume_eh*braco_eh_2) # that is supposed to be the objective tempo_total = m.Var(lb=0, ub = 4000) m.Equation(tempo_total==tempo_b1+tempo_b2) # Only of binary variable of each group can be true m.Equation (braco_gas_1+braco_gas_2 == 1) m.Equation (braco_eh_1+braco_eh_2 == 1) # I want to maximize the objective m.Maximize(tempo_b1+tempo_b2) m.options.SOLVER = 1 m.solve() # solve print('Braco_gas_1:'+str(braco_gas_1.value)) print('Braco_gas_2:'+str(braco_gas_2.value)) print('Braco_eh_1:'+str(braco_eh_1.value)) print('Braco_eh_2:'+str(braco_eh_2.value)) print('vazao_gas:'+str(vazao_gas.value)) print('vazao_eh:'+str(vazao_eh.value)) print('volume_gas:'+str(volume_gas)) print('volume_eh:'+str(volume_eh)) print('tempo_b1:'+str(tempo_b1.value)) print('tempo_b2:'+str(tempo_b2.value)) print('tempo_total:'+str(tempo_total.value))
Additional tutorials are available in the documentation or in the 18 example problems (with videos).