Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing variables in gekko using the array model function

Defining an array of Gekko variables does not allow any arguments to initialize the variables. For example, I am unable to make an array of integer variables using the m.Array function.

I can make an array of variables using this syntax: m.Array(m.Var, (42, 42)). However, I don't know how to make this array an array of integer variables because the m.Var passed in to the m.Array function does not take any arguments.

  • I have a single variable as an integer variable: my_var_is_an_integer_var = m.Var(0, lb=0, ub=1, integer=True)

  • I have an array of variables that are not integer variables: my_array_vars_are_not_integer_vars = m.Array(m.Var, (42, 42))

  • I want an array of integer variables: my_array_vars_are_integer_vars = m.Array(m.Var(0, lb=0, ub=1, integer=True), (42,42)) (Throws error)

HOW DO I INITIALIZE THE VARIABLES IN THE ARRAY TO BE INTEGER VARIABLES???

Error when trying to initialize array as integer variables:

Traceback (most recent call last):
  File "integer_array.py", line 7, in <module>
    my_array_vars_are_not_integer_vars = m.Array(m.Var(0, lb=0, ub=1, 
integer=True), (42,42))
  File "C:\Users\wills\Anaconda3\lib\site-packages\gekko\gekko.py", line 
 1831, in Array
    i[...] = f(**args)
TypeError: 'GKVariable' object is not callable
like image 666
liamW Avatar asked Nov 23 '25 08:11

liamW


1 Answers

If you need to pass additional arguments when creating a variable array, you can use one of the following options. Option 1 creates a Numpy array while Options 2 and 3 create a Python list.

Option 1 (Preferred) Create a numpy array with the m.Array function with additional argument integer=True:

y = m.Array(m.Var,(42,42),lb=0,ub=1,integer=True)

Option 2 Create a 2D list of variables with a list comprehension:

y = [[m.Var(lb=0,ub=1,integer=True) for i in range(42)] for j in range(42)]

Option 3 Alternatively, you can create an empty list (y) and append binary values to that list.

y = [[None]*42]*42
for i in range(42):
    for j in range(42):
        y[i][j] = m.Var(lb=0,ub=1,integer=True)

The UPPER and LOWER bounds can be changed after the variable creation but the integer option is only available at initialization. Don't forget to switch to the APOPT MINLP solver for integer variable solutions with m.options.SOLVER = 1. Below is a complete example that uses all three options but with a 3x4 array for x, y, and z.

from gekko import GEKKO
import numpy as np

m = GEKKO()

# option 1
x = m.Array(m.Var,(3,4),lb=0,ub=1,integer=True)

# option 2
y = [[m.Var(lb=0,ub=1,integer=True) for i in range(4)] for j in range(3)]

# option 3
z = [[None]*4]*3
for i in range(3):
    for j in range(4):
        z[i][j] = m.Var(lb=0,ub=1,integer=True)

# switch to APOPT
m.options.SOLVER = 1

# define objective function
m.Minimize(m.sum(m.sum(x)))
m.Minimize(m.sum(m.sum(np.array(y))))
m.Minimize(m.sum(m.sum(np.array(z))))

# define equation
m.Equation(x[1,2]==0)
m.Equation(m.sum(x[:,0])==2)
m.Equation(m.sum(x[:,1])==3)
m.Equation(m.sum(x[2,:])==1)

m.solve(disp=True)
print(x)

The objective is to minimize sum of all the elements in x, y, and z but there are certain constraints on an element, row, and columns of x. The solution is:

[[[1.0] [1.0] [0.0] [0.0]]
 [[1.0] [1.0] [0.0] [0.0]]
 [[0.0] [1.0] [0.0] [0.0]]]
like image 167
John Hedengren Avatar answered Nov 25 '25 22:11

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!