Abdirizak
Abdirizak

Reputation: 87

how can I use gekko optimizer without a known objective function(let say some random function) and with known variables and constraints?

I a trying to minimize and maximize a random 'test function' using gekko which is connected to A. A consists of 4 parameters between the range (0-100) and sum of A < 100.However I keep getting weird results,because the minimum of the test function is supposed to be 2500 and the max 10000. My code is below.Can anyone tell me where the problem is? Thanks in advance


    import numpy as np
    from gekko import GEKKO 


    def test_function(x):
        return np.dot(x, x)


    A = m.Array(m.Var, (4))
    # initial guess
    ig = [1, 5, 5, 1]
    # lower bounds
    i = 0
    for Ai in A:
        Ai.value = ig[i]
        Ai.lower = 0
        Ai.upper = 100
        i += 1
    m.Equation(np.sum(A) < 100)
    m.Obj(test_function(A))
    m.solve()
    print(test_function(A))
    print (A)

results

Solver         :  IPOPT (v3.12)
 Solution time  :   1.379999999971915E-002 sec
 Objective      :   4.141037033873033E-007
 Successful solution
 ---------------------------------------------------

(((((v1)*(v1))+((v2)*(v2)))+((v3)*(v3)))+((v4)*(v4)))
[[0.00042734466188] [0.00015629584657] [0.00015629584657]
 [0.00042734466188]]

Process finished with exit code 0

Upvotes: 4

Views: 259

Answers (2)

John Hedengren
John Hedengren

Reputation: 14346

I modified the problem to match your statement. There is also a list comprehension that simplifies the process of defining new variables with upper and lower bounds. The following script shows two ways of accessing test_function(x) with (1) Gekko variables that are symbolic expressions or (2) with numeric values to evaluate that constraint and objective function.

import numpy as np
from gekko import GEKKO 
m = GEKKO(remote=False)
def test_function(x):
    return np.dot(x, x)
ig = [1, 5, 5, 1] # initial guess
A = np.array([m.Var(value=ig[i],lb=0,ub=10000,name='a'+str(i)) \
              for i in range(4)])
m.Equation(test_function(A)>2500)
m.Equation(test_function(A)<10000)
m.Minimize(test_function(A))
m.solve()
# extract values to get a numerical solution of test_function
A_sol = [A[i].value[0] for i in range(4)]
print(test_function(A_sol))
# get the objective function value from the solver
print(m.options.OBJFCNVAL)
# print variables
print (A)

The results of the script are shown below. If you use print(test_function(A_sol)), it prints the symbolic expression that Gekko uses to find the solution. In your case, you may be interested in the numeric solution, not the symbolic form.

# results
2499.999999993099
2500.0
[[14.90599615] [32.059495922] [32.059495922] [14.90599615]]

Both m.options.OBJFCNVAL and evaluating the expression give the same result but are slightly different because of machine precision.

Upvotes: 1

Andrew T
Andrew T

Reputation: 582

The way that you have your lower bounds and objective function defined, gekko is choosing decimal that is just barely above 0. A decimal just barely above zero satisfies all of the bounds that you have given it and it is why the objective is so low. Also if you make the objective function negative it will maximize it to 5000. I'm not sure where you got the min and max that you are expecting.

Upvotes: 2

Related Questions