这两个问题对于Gekko来说都应该是可行的,但最初的问题似乎更容易解决.以下是针对原始问题的一些建议:
- 使用
m.Maximize()
作为目标
- 使用
sum()
表示目标函数的内部求和,使用m.sum()
表示外部求和.当求和将创建超过15,000个字符的表达式时,我切换到m.sum()
.使用sum()
会创建一个很长的表达式,而使用m.sum()
会将求和分解为多个片段,但编译时间会更长.
- 使用
m.min3()
表示min(dt,xs)项,或使用slack variables s
表示x[i]+s[i]=D[i].DT(大小为30)似乎是一个上限,但它的维度与Xs(大小为slack variables)不同. slack 变量比使用二进制变量效率高得多.
D = np.array(100)
x = m.Array(m.Var,100,lb=0,ub=2000000)
改进后的问题有6000个二元变量和100个连续变量.这些变量有2^6000个可能的组合,因此可能需要一段时间才能解决,即使使用APOPT的有效分支定界法也是如此.以下是针对修改后的问题的一些建议:
- 尽可能使用矩阵乘法.下面是一个使用Gekko进行矩阵运算的示例.
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=False)
ni = 3; nj = 2; nk = 4
# solve AX=B
A = m.Array(m.Var,(ni,nj),lb=0)
X = m.Array(m.Var,(nj,nk),lb=0)
AX = np.dot(A,X)
B = m.Array(m.Var,(ni,nk),lb=0)
# equality constraints
m.Equations([AX[i,j]==B[i,j] for i in range(ni) \
for j in range(nk)])
m.Equation(5==m.sum([m.sum([A[i][j] for i in range(ni)]) \
for j in range(nj)]))
m.Equation(2==m.sum([m.sum([X[i][j] for i in range(nj)]) \
for j in range(nk)]))
# objective function
m.Minimize(m.sum([m.sum([B[i][j] for i in range(ni)]) \
for j in range(nk)]))
m.solve()
print(A)
print(X)
print(B)