'GEKKO optimizer fails to reach 2nd iteration

I just got started with GEKKO. I am trying to optimize a 3D array with 200 variables, but they only take binary values (0 or 1). This is what my code looks like (it's a bit ugly, but I'm not sure if there's a better way to define 200 variables reliably):

params = []
m = GEKKO()
m.options.SOLVER = 1
for i in range(1,201):
    exec('x'+str(i)+'=m.Var(value=1, lb=0, ub=1, integer=True)')
    exec('params.append(x'+str(i)+')')
m.Obj(solve_and_measure(*params)) # function I wish to minimize
m.solve(disp=True)

The full code can be found here.

I'm no expect in which optimization algorithm might be most suitable for my problem, but the problem I'm facing is the optimizer appears to call the function once, and never again.

This is the output - any idea why it doesn't continue to the second iteration?

--- FUNCTION CALLED ---
--- FUNCTION OUTPUT --- [dB]: 0.010252837676577073
apm 79.129.195.6_gk_model0 <br><pre> ----------------------------------------------------------------
 APMonitor, Version 1.0.1
 APMonitor Optimization Suite
 ----------------------------------------------------------------
 
 
 --------- APM Model Size ------------
 Each time step contains
   Objects      :            0
   Constants    :            0
   Variables    :          200
   Intermediates:            0
   Connections  :            0
   Equations    :            1
   Residuals    :            1
 
 Number of state variables:            200
 Number of total equations: -            0
 Number of slack variables: -            0
 ---------------------------------------
 Degrees of freedom       :            200
 
 ----------------------------------------------
 Steady State Optimization with APOPT Solver
 ----------------------------------------------
Iter:     1 I:  0 Tm:      0.00 NLPi:    1 Dpth:    0 Lvs:    0 Obj:  1.03E-02 Gap:  0.00E+00
 Successful solution
 
 ---------------------------------------------------
 Solver         :  APOPT (v1.0)
 Solution time  :   1.290000000153668E-002 sec
 Objective      :   1.025283767657707E-002
 Successful solution
 ---------------------------------------------------


Solution 1:[1]

Gekko uses gradient-based solvers that require continuously differentiable functions. The model is symbolically calculated once and compiled to create a model form for efficient large-scale optimization. This involves automatic differentiation of the model to give sparse 1st and 2nd derivatives of the objective function and constraints. You can still use Gekko if the function needs to be externally calculated. One option is to use cspline (1D) or bspline (2D) functions to create a surrogate model that meets the conditions of continuously differentiable functions.

cspline optimization

from gekko import gekko 
import numpy as np
import matplotlib.pyplot as plt

"""
minimize y
s.t.     y = f(x)

using cubic spline with random sampling of data
"""

# Function to generate data for cspline
def f(x):
    return 3*np.sin(x) - (x-3) 

# Create model
c = gekko()

# Cubic spline
x = c.Var(value=15)
y = c.Var()
x_data = np.random.rand(50)*10+10
y_data = f(x_data)
c.cspline(x,y,x_data,y_data,True)
c.Obj(y)

# Options
c.options.IMODE = 3
c.options.CSV_READ = 0
c.options.SOLVER = 3
c.solve()

# Generate continuous trend for plot
z = np.linspace(10,20,100)

# Check if solved successfully
if c.options.SOLVESTATUS == 1:
    plt.figure()
    plt.plot(z,f(z),'r-',label='original')
    plt.scatter(x_data,y_data,5,'b',label='data')
    plt.scatter(x.value,y.value,200,'k','x',label='minimum')
    plt.legend(loc='best')
else:
    print ('Failed to converge!')
    plt.figure()
    plt.plot(z,f(z),'r-',label='original')
    plt.scatter(x_data,y_data,5,'b')
    plt.legend(loc='best')
plt.show()

If it is not possible to create a surrogate model, there may be other optimization tools that can solve the problem: Restrict scipy.optimize.minimize to integer values Some are linear-only or use tools such as scipy.optimize.minimize() with heuristic strategies to find an integer soluiton.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Hedengren