[英]GEKKO returned non-optimal solution
我想用 GEKKO 解决以下优化问题:
Minimize x'Qx + 1e-10 * sum_{i=1}^n x_i^0.1
subject to 1' x = 1 and x >= 0
但是,以下代码返回sol = [0., 0., 0. ,0. ,1.]
sol = [0., 0., 0. ,0. ,1.]
和Objective: 1.99419
作为解决方案。 这远非最佳,我将在下面解释原因。
import numpy as np
from gekko import GEKKO
n = 5
m = GEKKO(remote=False)
m.options.SOLVER = 1
m.options.IMODE = 3
x = [m.Var(lb=0, ub=1) for _ in range(n)]
m.Equation(m.sum(x) == 1)
np.random.seed(0)
Q = np.random.uniform(-1, 1, size=(n, n))
Q = np.dot(Q.T, Q)
## Add h_i^p
c, p = 1e-10, 0.1
for i in range(n):
m.Obj(c * x[i] ** p)
for j in range(n):
m.Obj(x[i] * Q[i, j] * x[j])
m.solve(disp=True)
sol = np.array(x).flatten()
这显然是错误的,因为如果我们只使用下面的代码优化二次部分(x'Qx),并将解决方案放在初始目标上,我们会得到一个小得多的目标值( Objective: 0.02489503
)。 1e-10 * sum_{i=1}^n x_i^p
基本上被忽略了,因为它非常小。
m1 = GEKKO(remote=False)
m1.options.SOLVER = 1
m1.options.OTOL = 1e-10
x1 = [m1.Var(lb=0, ub=1) for _ in range(n)]
m1.Equation(m1.sum(x1) == 1)
m1.qobj(b=np.zeros(n), A=2 * Q, x=x1, otype='min')
m1.solve(disp=True)
sol = np.array(x1).flatten()
有没有办法解决这个问题? 谢谢!
Gekko 使用基于梯度的方法解决非线性规划优化问题:内点和活动集 SQP。 看起来目标函数有问题。 在 Numpy 中使用矩阵运算来简化目标定义。
## Create Objective
c, p = 1e-10, 0.1
obj = np.dot(np.dot(x,Q),x) + c*m.sum([xi**p for xi in x])
m.Minimize(obj)
这是使用 Gekko 解决的修改后的脚本。 如果达到默认限制250
,则增加MAX_ITER
。
import numpy as np
from gekko import GEKKO
n = 5
m = GEKKO(remote=False)
m.options.SOLVER = 3
m.options.IMODE = 3
x = m.Array(m.Var,n,value=0.1, lb=1e-6, ub=1)
m.Equation(m.sum(x) == 1)
np.random.seed(0)
Q = np.random.uniform(-1, 1, size=(n, n))
Q = np.dot(Q.T, Q)
print(Q)
## Create Objective
c, p = 1e-10, 0.1
obj = np.dot(np.dot(x,Q),x) + c*m.sum([xi**p for xi in x])
m.Minimize(obj)
# adjust solver tolerance
m.options.RTOL=1e-10
m.options.OTOL=1e-10
m.options.MAX_ITER = 1000
m.solve(disp=True)
sol = np.array(x).flatten()
print('x: ', sol)
print('obj: ', m.options.OBJFCNVAL)
这给出了一个全局最优解,因为它是二次规划 (QP) 问题(凸优化)。 对 QP 问题使用非线性规划 (SQP) 求解器可以通过 IPPT 求解器得到一个解:
x: [[0.36315827507] [0.081993130341] [1e-06] [0.086231281612] [0.46861632269]]
obj: 0.024895918696
据我所知, gekko
看起来像是为机器学习而构建的,它专注于局部优化而不是全局优化,通常大多数库都无法保证您获得最佳解决方案。
如果您真的想要最佳解决方案,那么对于这种情况,我建议您研究区间算术。 诸如mpmath 之类的软件包可以提供此功能,尽管我还没有看到优化器在我短暂的搜索中使用它。
关于区间算术如何工作的 TL;DR 是您输入一系列输入并返回一系列输出。 例如,您可以测试1
是否在x1 + x2 + x3 + x4
的可能输出范围内,并且可以查看目标函数的最小/最大潜在值。 通过这种方式,您可以逐步将区间分成两半,仅保留可能满足约束且目标函数的最大潜力至少是最大最小潜力的区间。 这允许您以更多计算为代价实现有保证的收敛到全局最优值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.