Search code examples
pythongekko

Gekko returns a non-integer result for an integer variable


I am trying to solve a non-linear optimization problem using Gekko. Despite defining one of the variables as an integer, Gekko still returns a float. I tried writing a random, simpler optimization problem (shown below), and the same thing happened. Why is this and how can I get Gekko to solve for an integer value?

from gekko import Gekko

m = Gekko()

x1 = m.Var(value=2, ub=30, name="x1")
x2 = m.Var(value=1, lb=0, name="x2")
x3 = m.Var(value=4, name="x3", integer=True)

i1 = m.Intermediate(2*x1/x2)
i2 = m.Intermediate(x3**2)

m.Equation(x1 >= x2)

m.Equation(i1 >= 1)
m.Equation(i2 <= 28)

m.Maximize(x1**2 + x2**2 + x3**3)

m.solve()

print("Results:")
print(f"{x1[0]=}")
print(f"{x2[0]=}")
print(f"{x3[0]=}")

Gekko Results:

x1 = 30.0
x2 = 30.00000031
x3 = 5.2915026231

Solution

  • Change the solver to APOPT from the default IPOPT to get an integer solution.

    m.options.SOLVER=1  # 1=APOPT, 2=BPOPT, 3=IPOPT
    

    Here is more information about the solver selection and additional details in the Gekko documentation. The modified code produces an integer solution:

     ----------------------------------------------
     Steady State Optimization with APOPT Solver
     ----------------------------------------------
    Iter:     1 I:  0 Tm:      0.00 NLPi:    5 Dpth:    0 Lvs:    2 Obj: -1.95E+03 Gap:       NaN
    Iter:     2 I: -1 Tm:      0.00 NLPi:    1 Dpth:    1 Lvs:    1 Obj: -1.95E+03 Gap:       NaN
    --Integer Solution:  -1.92E+03 Lowest Leaf:  -1.92E+03 Gap:   0.00E+00
    Iter:     3 I:  0 Tm:      0.00 NLPi:    2 Dpth:    1 Lvs:    1 Obj: -1.92E+03 Gap:  0.00E+00
     Successful solution
     
     ---------------------------------------------------
     Solver         :  APOPT (v1.0)
     Solution time  :   1.590000000214786E-002 sec
     Objective      :   -1925.00000000000     
     Successful solution
     ---------------------------------------------------
     
    Results:
    x1[0]=30.0
    x2[0]=30.0
    x3[0]=5.0