简体   繁体   中英

Using Gekko to minimize norm of matrix

I'm trying to apply Gekko to minimize the norm of a vector (well actually the difference between two vectors as shown in the code below). As you can see, I'd also like integer solutions and I'm also constraining a couple of the variables to be bounded above by 0. Here's some test code:

from gekko import GEKKO

M = np.array([[1, 4, 5], 
    [-5, 8, 9]])

b = np.array([1,2])

m = GEKKO(remote=False)

# create variables
x = m.Array(m.Var, M.shape[1], integer = True)
for i in range(M.shape[1]-M.shape[0]):
  x[i].lower = 0
#   #x[i].upper cannot exceed total Q



m.Obj(m.abs(np.subtract(np.matmul(M,x), b)))
m.solve(disp=False)

When I run, I get the following error:

Exception: @error: Equation Definition
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<command-2749153836142718> in <module>
     17 
     18 m.Obj(m.abs(np.subtract(np.matmul(M,x), b)))
---> 19 m.solve(disp=False)

/local_disk0/.ephemeral_nfs/envs/pythonEnv-303e2ce6-8c7a-44c3-93be-cebc25e4537a/lib/python3.7/site-packages/gekko/gekko.py in solve(self, disp, debug, GUI, **kwargs)
   2128                 print("Error:", errs)
   2129             if (debug >= 1) and record_error:
-> 2130                 raise Exception(apm_error)
   2131 
   2132         else: #solve on APM server

Exception: @error: Equation Definition
 Equation without an equality (=) or inequality (>,<)
 (((((-5)*(int_v1))+((8)*(int_v2)))+((9)*(int_v3)))-2)])
 STOPPING...

Can gekko handle objective functions like this? Is my set up messed up? Any feedback would be much appreciated.

There are no problem with these types of objectives. The error is that the m.Obj or m.Minimize function needs to have a scalar variable. A loop or m.sum() is needed to add all of the individual objective function terms into one objective.

obj = np.matmul(M,x)-b
for i in range(nr):
    m.Minimize(m.abs3(obj[i]))

I also recommend m.abs3() instead of m.abs() so that there are continuous first and second derivatives for the solver. Here is the full script.

from gekko import GEKKO
import numpy as np

M = np.array([[1, 4, 5], 
    [-5, 8, 9]])
b = np.array([1,2])

nr = np.size(M,0)  # rows
nc = np.size(M,1)  # columns

# create variables
m = GEKKO(remote=False)
x = m.Array(m.Var, nc, integer = True)
for i in range(nc-nr):
  x[i].lower = 0

obj = M@x-b
for i in range(nr):
    m.Minimize(m.abs3(obj[i]))
m.solve(disp=False)

print('Objective: ' + str(m.options.OBJFCNVAL))
for i in range(nc):
    print('x['+str(i)+'] = '+str(x[i].value[0]))

Integer Solution

Objective: 1.0
x[0] = 2.0
x[1] = 16.0

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM