簡體   English   中英

如何解決@error:GEKKO 中的方程定義

[英]How to solve @error: Equation Definition in 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)

Output:

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)之前:

在此處輸入圖像描述

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

在此處輸入圖像描述

如果您嘗試比較它們,您會發現x已更改。 這意味着已經找到了最優解! 我認為優化是由算法完成的。
但它仍然向我展示了我在 Output 部分中提到的錯誤。
我應該如何解決這個問題?

該問題可以通過更改目標 function 來解決:

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

m.Maximize()m.Minimize()定義的目標 function 必須是標量(單個)值。 附加的 np.dot() function 是使ww * Log_Caculator(np.dot(xT, 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,Log_Caculator(np.dot(x.T, 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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM