这是一个潜在的解决方案。
import numpy as np
from gekko import GEKKO
m = GEKKO(remote=False)
x = np.array([1,2,5,3,2.7,5.1,2.5]); n = len(x)
a = m.Array(m.Var,3,lb=-100,ub=100)
w = np.array([m.Intermediate(m.exp(a[0]+a[1]*x[i]\
+a[2]*x[i]**2))
for i in range(n)])
B = 3.1
E = 0.08
Ec = m.Intermediate(m.sum(w*x)/n-B)
m.Equation(m.abs3(Ec)<E)
m.Equation(m.sum(w)==n)
m.Minimize(m.sum(w**2))
m.solve()
这可以使用 APPT 求解器在一次迭代中求解。它将采用新的数据、目标和公差值提供不同的解决方案。
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 0.023999999999999997 sec
Objective : 6.999999999999998
Successful solution
---------------------------------------------------
这是显示解决方案的代码:
print('-'*10)
for i in range(3):
print(f'a{i}={a[i].value[0]:.3g}')
print('-'*10)
for i in range(n):
print(f'w{i}={w[i].value[0]:.3g}')
print('-'*10)
print(f'Ec={Ec.value[0]} E={E}')
print('-'*10)
结果表明满足所有约束条件。
----------
a0=-7.38e-09
a1=4.91e-09
a2=-6.73e-10
----------
w0=1
w1=1
w2=1
w3=1
w4=1
w5=1
w6=1
----------
Ec=-0.057142856157 E=0.08
----------
如果存在不可行的解决方案,则最小化 E 而不是设置硬限制。
# E = 0.08
E = m.Var(lb=0,ub=10)
m.Minimize(1e-4*E)
您还可以尝试使用方程两边的平方(以删除绝对值)。
m.Equation(Ec<E**2)
这避免了需要 APOPT 求解器的二进制变量。通过对方程两边进行平方,您可以切换到 IPOPT 求解器:m.options.SOLVER=3
或者只使用 Gekko 中的默认选项。