Reputation: 21
Thanks for the great package! It's been quite nice and handy.
recently, I'm trying to solve a MILP problem, with the two state variavles are integers within lower and upper boundaries, and the objective function is a independent function that returns a real number.
The idea looks pretty simple, but my Gekko only calculate the initial one step, and then stop the optimization process. Please advise me aobut the correct way to implement this problem in Gekko. Thanks a lot!
My code is shown below:
# Initialize gekko
m = GEKKO()
# APOPT is an MINLP solver
m.options.SOLVER=1
# Solver settings (copied from an example)
m.solver_options = \['minlp_maximum_iterations 500', \
\# minlp iterations with integer solution
'minlp_max_iter_with_int_sol 10', \
\# treat minlp as nlp
'minlp_as_nlp 0', \
\# nlp sub-problem max iterations
'nlp_maximum_iterations 50', \
\# 1 = depth first, 2 = breadth first
'minlp_branch_method 1', \
\# maximum deviation from whole number
'minlp_integer_tol 0.05', \
\# covergence tolerance
'minlp_gap_tol 0.01'\]
# Two state variables
m.x1 = m.Var(value=20, lb=1, ub=90, integer=True)
m.x2 = m.Var(value=60, lb=2, ub=91, integer=True)
# Objective function with a independent function that returns a real number
m.Obj(K_func(data, m.x1, m.x2))
# Solve the Gekko optimization
m.solve(disp=True) # Solve
Upvotes: 2
Views: 129
Reputation: 14376
Here is an example of how to include an external K_func
objective function with Gekko:
from gekko import GEKKO
import numpy as np
m = GEKKO()
# sample data
data = np.random.rand(10)*20
# example function
def K_func(data,x1,x2):
obj = sum([(x1-d)**2 + (x2-d-3)**2 for d in data])
return obj
# APOPT is an MINLP solver
m.options.SOLVER=1
# Solver settings (copied from an example)
m.solver_options = ['minlp_maximum_iterations 500', \
'minlp_max_iter_with_int_sol 10', \
'minlp_as_nlp 0', \
'nlp_maximum_iterations 50', \
'minlp_branch_method 1', \
'minlp_integer_tol 0.05', \
'minlp_gap_tol 0.01']
# Two state variables
m.x1 = m.Var(value=20, lb=1, ub=90, integer=True)
m.x2 = m.Var(value=60, lb=2, ub=91, integer=True)
# Objective function with a independent function that returns a real number
m.Obj(K_func(data, m.x1, m.x2))
# Solve the Gekko optimization
m.solve(disp=True) # Solve
print(f'x1: {m.x1.value[0]}')
print(f'x2: {m.x2.value[0]}')
The result changes with different random numbers, but here is one output:
----------------------------------------------
Steady State Optimization with APOPT Solver
----------------------------------------------
Iter: 1 I: 0 Tm: 0.00 NLPi: 4 Dpth: 0 Lvs: 3 Obj: 5.14E+02 Gap: NaN
--Integer Solution: 5.14E+02 Lowest Leaf: 5.14E+02 Gap: 5.42E-04
Iter: 2 I: 0 Tm: 0.00 NLPi: 1 Dpth: 1 Lvs: 3 Obj: 5.14E+02 Gap: 5.42E-04
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 3.770000001532026E-002 sec
Objective : 513.977527789434
Successful solution
---------------------------------------------------
x1: 6.0
x2: 9.0
Any external function needs to be defined in terms of Gekko variables, otherwise it is a black-box function and a different strategy needs to be used, such as creating a surrogate model of the function with a 1D cspline, 2D bspline, or higher dimensional ML model. Here are related questions for black-box models:
Upvotes: 0