In this optimization problem (a single variable simplified version of mine) I have one variable and I am trying to maximize the objective. The answer should be x = 4 with an objfcnval equal to 2 since as x increases these will be the calculations 0 - 0 = 0, 1 - 2 = -1, 2 - 2 = 0, 3 - 2 = 1, 4 - 2 = 2 , 5 - 4 = 1.
Here is the code:
def my_ceiling(elem1, elem2):
if (elem1 // elem2) == (elem1 / elem2):
return elem1 / elem2
else:
return (elem1 // elem2) + 1
m = gekko.GEKKO(remote=False)
m.options.SOLVER = 1
x = m.Var(value=0, lb=0, ub=5, integer=True)
m.Obj((-1) * (x - 2 * my_ceiling(x, 4)))
m.solve(disp=False)
print('Objective: ' + str((-1) * m.options.objfcnval))
if (elem1 // elem2) == (elem1 / elem2):
TypeError: unsupported operand type(s) for //: 'GKVariable' and 'int'
The problem is that apparently this kind of operation is not supported. How would I go about using Gekko for problems like these?
Taking inspiration from another discussion , one way to implement the floor function is to create a new integer variable y
that is bounded by x/4 > y >= x/4 + 1e-8
.
import gekko
m = gekko.GEKKO(remote=False)
m.options.SOLVER = 1
x = m.Var(value=0, lb=0,ub=5,integer=True)
y = m.Var(lb=0,ub=5,integer=True)
m.Equations([y<x/4,y>=x/4+1e-8])
m.Maximize((x - 2*y))
m.solve(disp=False)
print(x.value[0],y.value[0])
print('Objective: ' + str((-1)*m.options.objfcnval))
This produces a solution for x
, y
, and the objective function:
4.0 1.0
Objective: 2.0
This strategy also works if x
is not an integer variable but Gekko gives a slightly different answer:
3.99999996 1.0
Objective: 1.99999996
If there is a reliable method, perhaps we should add a floor
or ceil
function in gekko that is similar to some of the other functions in the model building documentation . Could you keep us updated on your testing and what approach works best?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.