Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimize with pre-defined variables

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)
like image 273
繆征達 Avatar asked Sep 30 '25 09:09

繆征達


2 Answers

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:

  • https://gekko.readthedocs.io/en/latest/examples.html
  • https://gekko.readthedocs.io/en/latest/model_methods.html
like image 61
colidyre Avatar answered Oct 01 '25 23:10

colidyre


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

like image 31
John Hedengren Avatar answered Oct 01 '25 23:10

John Hedengren



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!