Reputation: 87
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
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
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