Search code examples
pythonnonlinear-optimizationgekko

Gekko optimisation error with a nonlinear function and 2 inputs


I want to maximise a concave function with two inputs

max 2 * x1 ** .8 + 1.4 * x2 ** .9

st x1 + x2 == C

using Gekko, but I get a error code -2.

 
from gekko import GEKKO

m = GEKKO()

C = m.Param(value=10)

x1, x2 = [m.Var(lb=0, ub=10) for i in range(2)]

x1.value = 5
x2.value = 5

m.Equation(x1 + x2 == C)

m.Obj(2 * x1 ** .8 + 1.4 * x2 ** .9)

m.options.IMODE = 3

m.solve()

print(x1.value)
print(x2.value)

Solution

  • There is a successful solution by switching to the APOPT solver m.options.SOLVER = 1. In this case the default solver, IPOPT, fails to find a solution but APOPT succeeds.

    from gekko import GEKKO
    m = GEKKO()
    x1, x2 = m.Array(m.Var,2,value=5,lb=0,ub=10)
    m.Equation(x1+x2 == 10)
    m.Minimize(2 * x1 ** .8 + 1.4 * x2 ** .9)
    
    m.options.IMODE = 3
    m.options.SOLVER = 1
    m.solve()
    
    print(x1.value)
    print(x2.value)
    

    contour plot

    A contour plot with the solution shows that it did reach the optimal value along the black line (x1+x2=10 constraint).

    # Generate a contour plot
    import numpy as np
    import matplotlib.pyplot as plt
    
    # Design variables at mesh points
    xg = np.arange(0.0, 10.0, 0.1)
    yg = np.arange(0.0, 10.0, 0.1)
    x1g,x2g = np.meshgrid(xg, yg)
    
    # Equation / Constraint
    eq1 = x1g+x2g
    
    # Objective
    obj = 2*x1g**0.8 + 1.4*x2g**0.9
    
    # Create a contour plot
    plt.figure()
    # Objective
    CS = plt.contour(x1g,x2g,obj)
    plt.clabel(CS, inline=1, fontsize=10)
    # Equation
    CS = plt.contour(x1g,x2g,eq1,[10.0],colors='k',linewidths=[4.0])
    plt.clabel(CS, inline=1, fontsize=10)
    # Plot optimal point
    plt.plot(x1.value[0],x2.value[0],'o',color='orange',markersize=10)
    plt.xlabel('x1'); plt.ylabel('x2')
    plt.savefig('contour.png')
    plt.show()
    

    The orange dot is the optimal solution at x1=0 and x2=10.

    Edit: Maximize instead of Minimize

    The problem statement is Maximize instead of Minimize. Thanks for the correction.

    Maximize Objective

    from gekko import GEKKO
    m = GEKKO()
    x1, x2 = m.Array(m.Var,2,value=5,lb=0,ub=10)
    m.Equation(x1+x2 == 10)
    m.Maximize(2 * x1 ** .8 + 1.4 * x2 ** .9)
    
    m.options.IMODE = 3
    m.options.SOLVER = 1
    m.solve()
    
    print(x1.value)
    print(x2.value)
    
    # Generate a contour plot
    import numpy as np
    import matplotlib.pyplot as plt
    
    # Design variables at mesh points
    xg = np.arange(0.0, 10.0, 0.1)
    yg = np.arange(0.0, 10.0, 0.1)
    x1g,x2g = np.meshgrid(xg, yg)
    
    # Equation / Constraint
    eq1 = x1g+x2g
    
    # Objective
    obj = 2*x1g**0.8 + 1.4*x2g**0.9
    
    # Create a contour plot
    plt.figure()
    # Objective
    CS = plt.contour(x1g,x2g,obj)
    plt.clabel(CS, inline=1, fontsize=10)
    # Equation
    CS = plt.contour(x1g,x2g,eq1,[10.0],colors='k',linewidths=[4.0])
    plt.clabel(CS, inline=1, fontsize=10)
    # Plot optimal point
    plt.plot(x1.value[0],x2.value[0],'o',color='orange',markersize=10)
    plt.xlabel('x1'); plt.ylabel('x2')
    plt.savefig('contour.png')
    plt.show()