3 votes

Utilisation de Gekko pour minimiser la norme de la matrice

J'essaie d'appliquer Gekko pour minimiser la norme d'un vecteur (en fait, la différence entre deux vecteurs comme le montre le code ci-dessous). Comme vous pouvez le voir, j'aimerais aussi avoir des solutions entières et je contrains aussi quelques variables à être limitées par 0. Voici un peu de code de test :

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)

Lorsque je l'exécute, j'obtiens l'erreur suivante :

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

Est-ce que gekko peut gérer des fonctions objectives comme celle-ci ? Ma configuration est-elle incorrecte ? Tout commentaire serait très apprécié.

1voto

John Hedengren Points 1

Il n'y a aucun problème avec ce type d'objectifs. L'erreur est que le m.Obj o m.Minimize doit avoir une variable scalaire. Une boucle ou m.sum() est nécessaire pour additionner tous les termes de la fonction objectif individuelle en un seul objectif.

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

Je recommande également m.abs3() au lieu de m.abs() afin qu'il y ait des dérivées premières et secondes continues pour le solveur. Voici le script complet.

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

Solution entière

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X