如何解决@error:GEKKO 中的方程定义

问题描述

我想用python解决一个优化问题。
这是代码假设:

W = [0.010858969983152403,0.15750120163876366,0.14594534721059332,0.08588827233293823,0.14391967610026943,0.17068447485608854,0.17510026127394213,0.11010179660425223]

C = np.array([[0.99365367,0.97892888,1.01870907,1.00434405,0.99742434,0.98994678,1.00610998,1.0014477 ],[0.99065144,1.00254236,0.97842508,0.93742212,0.99908661,0.99232329,0.99406251,0.99902616],[0.99355243,0.9896095,1.00603939,1.01114646,1.00859356,1.00421901,0.9994433,0.96580307],[0.99310202,1.00188421,1.01455517,0.99027971,0.99445973,0.99638549,0.98567891,1.00278336],[0.98696926,0.99425696,1.01039431,1.0066784,0.99775556,0.99873331,0.99854812,1.00948166]])

现在由 GEKKO 优化:

import numpy as np
from gekko import GEKKO

nd = 5
qw = GEKKO()
x = qw.Array(qw.Var,nd,value=1/nd,lb=0,ub=1) # x.shape --> (5,)

qw.Equation(sum(x) == 1)

ww = np.array(W) # ww.shape --> (8,)

def Log_Caculator(Array):
    '''
    final goal of This function is to Calculate Logarithm of every element of the 'Array'
    and return the new Array
    '''
    for j in range(len(Array)):
        Array[j] = qw.log10(Array[j])
    
    return Array

qw.Maximize(ww * Log_Caculator(np.dot(x.T,C)))
qw.solve(disp=True)
for i,xi in enumerate(x):
    print(i+1,xi.value)

输出

Exception:  @error: Equation DeFinition
 Equation without an equality (=) or inequality (>,<)
 ((0.15750120163876366)*(log10(((((((v1)*(0.97892888))+((v2)*(1.00254236)))+((v3
 )*(0.9896095)))+((v4)*(1.00188421)))+((v5)*(0.99425696))))))
 STOPPING...

通过 Visual Studio Code 的调试功能,我得到了这些:
在执行 qw.solve(disp=True) 之前:

enter image description here

执行qw.solve(disp=True)后:

enter image description here

如果您尝试比较它们,您会发现 x 发生了变化!这意味着已找到最佳解决方案!我认为优化是由算法完成的。
但它仍然显示了我在输出部分提到的错误
我应该如何解决这个问题?

解决方法

这个问题可以通过改变目标函数来解决:

qw.Maximize(np.dot(ww,Log_Caculator(np.dot(x.T,C))))

m.Maximize()m.Minimize() 定义的目标函数必须是标量(单个)值。附加的 np.dot() 函数是使 ww * Log_Caculator(np.dot(x.T,C)) 成为标量的一种方法。

这是完整的脚本:

import numpy as np
from gekko import GEKKO

W = [0.010858969983152403,0.15750120163876366,0.14594534721059332,\
     0.08588827233293823,0.14391967610026943,0.17068447485608854,\
     0.17510026127394213,0.11010179660425223]
ww = np.array(W)

C = np.array([[0.99365367,0.97892888,1.01870907,1.00434405,\
               0.99742434,0.98994678,1.00610998,1.0014477 ],[0.99065144,1.00254236,0.97842508,0.93742212,\
               0.99908661,0.99232329,0.99406251,0.99902616],[0.99355243,0.9896095,1.00603939,1.01114646,\
               1.00859356,1.00421901,0.9994433,0.96580307],[0.99310202,1.00188421,1.01455517,0.99027971,\
               0.99445973,0.99638549,0.98567891,1.00278336],[0.98696926,0.99425696,1.01039431,1.0066784,\
               0.99775556,0.99873331,0.99854812,1.00948166]])

nd = 5
qw = GEKKO()
x = qw.Array(qw.Var,nd,value=1/nd,lb=0,ub=1)
qw.Equation(sum(x) == 1)

def Log_Caculator(Array):
    for j in range(len(Array)):
        Array[j] = qw.log10(Array[j])    
    return Array

qw.Maximize(np.dot(ww,C))))
qw.solve(disp=True)
for i,xi in enumerate(x):
    print(i+1,xi.value)

解决办法如下:

EXIT: Optimal Solution Found.
 
 The solution was found.
 
 The final value of the objective function is  -5.540853005129416E-004
 
 ---------------------------------------------------
 Solver         :  IPOPT (v3.12)
 Solution time  :   9.600000004866160E-003 sec
 Objective      :  -5.540853005129416E-004
 Successful solution
 ---------------------------------------------------
 
1 [3.7304341888e-05]
2 [4.8543858174e-06]
3 [3.9756289011e-05]
4 [2.5331754827e-05]
5 [0.99989275323]