I am studying how to solve one problem with pre-defined variables. For example, variable "x" must be one of the values below.
[2, 5, 6, 13] But, I don't know how to modify my codes.
The original code is as belows.
from gekko import GEKKO
m = GEKKO(remote=False)
x = m.Array(m.Var,9,lb=0,ub=7,integer=True)
def f(x):
return (481.79/(5+x[0]))+(412.04/(4+x[1]))\
+(365.54/(3+x[2]))+(375.88/(3+x[3]))\
+(379.75/(3+x[4]))+(632.92/(5+x[5]))\
+(127.89/(1+x[6]))+(835.71/(6+x[7]))\
+(200.21/(1+x[8]))
m.Minimize(f(x))
m.Equation(sum(x)==7)
m.options.SOLVER=1
m.solve()
print(x)
I modify it as follows, but error message shows " TypeError: GEKKO.Array() takes 3 positional arguments but 4 were given ".
from gekko import GEKKO
m = GEKKO(remote=False)
x = m.Array(m.Var,9,[2, 5, 6, 13])
def f(x):
return (481.79/(5+x[0]))+(412.04/(4+x[1]))\
+(365.54/(3+x[2]))+(375.88/(3+x[3]))\
+(379.75/(3+x[4]))+(632.92/(5+x[5]))\
+(127.89/(1+x[6]))+(835.71/(6+x[7]))\
+(200.21/(1+x[8]))
m.Minimize(f(x))
m.Equation(sum(x)==7)
m.options.SOLVER=1
m.solve()
print(x)
The error shows that you're using the Array(self, f, dim, **args)
with 3 positional arguments (in Python self
is counted as well in the error description, but it should not be used if you're having an instance of this class).
So by using x = m.Array(m.Var,9,[2, 5, 6, 13])
, you have following positional arguments:
self
(counted, but correctly not used)m.Var
9
[2, 5, 6, 13]
Then, Python wants to distribute arguments m.Var
, 9
and [2, 5, 6, 13]
to f
and dim
parameter, i.e. passing 3 arguments to 2 parameters. That's why you're getting this error. The **args
parameter means that you can add further keyword arguments, but not more positional ones.
Otherwise it is unclear what you mean by more or less saying: variable "x" must be one of the values [2, 5, 6, 13]? x
is an resulting array with multiple values. It cannot be mapped to single values like 2
or 5
etc.
See here for some examples how to use Arrays in Gekko:
Use the Special Ordered Set m.sos1()
type to select from a set of values.
m.sos1([2,5,6,13])
Here is a complete version:
from gekko import GEKKO
def f(x):
return (481.79/(5+x[0]))+(412.04/(4+x[1]))\
+(365.54/(3+x[2]))+(375.88/(3+x[3]))\
+(379.75/(3+x[4]))+(632.92/(5+x[5]))\
+(127.89/(1+x[6]))+(835.71/(6+x[7]))\
+(200.21/(1+x[8]))
m = GEKKO(remote=False)
x = [None]*9
for i in range(len(x)):
x[i] = m.sos1([2,5,6,13])
m.Minimize(f(x))
m.Equation(sum(x)==27)
m.solve()
print(x)
There is no feasible solution when m.Equation(sum(x)==7)
because x
has an array size of 9 with the minimum value of 2 for each. The minimum summation is therefore 18 for a feasible solution. With m.Equation(sum(x)==27)
as an example, there is a feasible solution:
Iter: 132 I: -1 Tm: 0.00 NLPi: 1 Dpth: 6 Lvs: 74 Obj: 5.71E+02 Gap: 1.02E-02
Iter: 133 I: 0 Tm: 0.00 NLPi: 7 Dpth: 6 Lvs: 73 Obj: 5.80E+02 Gap: 1.02E-02
--Integer Solution: 5.76E+02 Lowest Leaf: 5.71E+02 Gap: 8.43E-03
Iter: 134 I: 0 Tm: 0.00 NLPi: 3 Dpth: 6 Lvs: 73 Obj: 5.76E+02 Gap: 8.43E-03
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 0.384400000002643 sec
Objective : 575.642338744589
Successful solution
---------------------------------------------------
[[2.0],[2.0],[2.0],[2.0],[5.0],[2.0],[2.0],[5.0],[5.0]]
The m.sos1()
function creates a new binary variable for each option (0,1)
. For future reference, if you have a continuous integer variable such as [2,3,4,5], it is more efficient to use m.Var(lb=2,ub=5,integer=True)
instead of m.sos1([2,3,4,5])
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With