4

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)
colidyre
4,87512 gold badges46 silver badges65 bronze badges
asked Jan 9, 2025 at 9:25
2
  • 1
    could you post the complete traceback? In the first code you are passing 5 parameters to m.Array(), in the second code you are passing 3 parameters, so the error about 4 parameters doesn't really seem to match any of the codes you posted. So please post the complete traceback of the error, properly formatted, so we can see what is exactly causing the error. Commented Jan 9, 2025 at 9:27
  • @Cincinnatus In the first example, 5 arguments are passed, but 2 positional. In the second example, 3 arguments are passed, all positional. The self is then counted additional in the error description as well. This is normal Python behavior. Commented Jan 9, 2025 at 9:53

2 Answers 2

1

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:

  1. self (counted, but correctly not used)
  2. m.Var
  3. 9
  4. [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:

answered Jan 9, 2025 at 9:31
Sign up to request clarification or add additional context in comments.

Comments

1

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]).

answered Jan 10, 2025 at 13:46

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.