GEKKO 中具有恒定输入范围和迭代初始值的非线性方程

问题描述 投票:0回答:1

我正在尝试使用边界和初始值求解 GEKKO 中的非线性方程。以下示例说明了我试图解决更大的非线性方程组的两个主要问题。

from gekko import GEKKO
import numpy as np

m = GEKKO()

a = m.Const(value=1)
b = m.Const(value=1)
x = m.Var(value=3,lb=0)
y = m.Var(value=3,lb=0)

m.Equation(10**-x + y == a)
m.Equation(x - 10**y == b)

m.solve(disp=False)

print(x.value,y.value)

这给出了一个解决方案:

[10.999999998] [0.99999999999]

问题 1 - 我想使用 a 常量的输入范围来求解 x,y,并且也不关心舍入误差。例如,我可以加入

np.linspace
吗?

a = np.linspace(1,10,10)

问题2 - 到a=4时,

value=3
的初始值就不起作用了。为了解决这个问题,我想使用 x,y 解作为下一次迭代的初始值。例如,对于 a=1,解决方案是
[10.999999998] [0.99999999999]
,我希望将其作为下一次迭代的初始值 a=2:

x = m.Var(value=10.999999998,lb=0)
y = m.Var(value=0.99999999999,lb=0)

依此类推,直到达到a=10

initialization iteration gekko nonlinear-equation
1个回答
0
投票

m.Param()
用于
a
,以便可以在每个循环中调整
a.value
。还可以调整
x.value
y.value
来给出初步猜测。 Gekko 自动将先前的解决方案存储为新的初始猜测,因此无需重新初始化
x
y

from gekko import GEKKO
import numpy as np

m = GEKKO()

av = np.linspace(1,10,10)
xv = 3; yv = 3

a = m.Param()
b = m.Const(value=1)
x = m.Var(value=xv,lb=0)
y = m.Var(value=yv,lb=0)

m.Equation(10**-x + y == a)
m.Equation(x - 10**y == b)

for ai in av:
    a.value = ai
    x.value = xv
    y.value = yv

    m.solve(disp=False)

    # print solution
    xv = np.round(x.value[0],2)
    yv = np.round(y.value[0],2)
    print(f'a: {np.round(ai,2)} x: {xv} y: {yv}')

这给出了解决方案:

a: 1.0 x: 11.0 y: 1.0
a: 2.0 x: 101.0 y: 2.0
a: 3.0 x: 1001.0 y: 3.0
a: 4.0 x: 10001.0 y: 4.0
a: 5.0 x: 100001.0 y: 5.0
a: 6.0 x: 1000001.0 y: 6.0
a: 7.0 x: 10000001.0 y: 7.0
a: 8.0 x: 100000001.0 y: 8.0
a: 9.0 x: 1000000001.0 y: 9.0
a: 10.0 x: 10000000001.0 y: 10.0

解决此问题的另一种方法是使用

IMODE=2
一次性解决
a
中的所有排列。对于这个问题,需要使用
IMODE=3
进行初始化。这可能会快得多,因此可以解决一个更大的优化问题,而不是解决一系列优化问题。

from gekko import GEKKO
import numpy as np

m = GEKKO()

a = m.Param(value=1)
b = m.Const(value=1)
x = m.Var(value=3,lb=0)
y = m.Var(value=3,lb=0)

m.Equation(10**-x + y == a)
m.Equation(x - 10**y == b)

m.options.IMODE=3
m.solve(disp=False)

m.options.IMODE=2
a.value=np.linspace(1,10,10)
m.solve(disp=False)

for i,ai in enumerate(a.value):
    xv = np.round(x.value[i],2)
    yv = np.round(y.value[i],2)
    print(f'a: {np.round(ai,2)} x: {xv} y: {yv}')

结果是一样的:

a: 1.0 x: 11.0 y: 1.0
a: 2.0 x: 101.0 y: 2.0
a: 3.0 x: 1001.0 y: 3.0
a: 4.0 x: 10001.0 y: 4.0
a: 5.0 x: 100001.0 y: 5.0
a: 6.0 x: 1000001.0 y: 6.0
a: 7.0 x: 10000001.0 y: 7.0
a: 8.0 x: 100000001.0 y: 8.0
a: 9.0 x: 1000000001.0 y: 9.0
a: 10.0 x: 10000000001.0 y: 10.0
© www.soinside.com 2019 - 2024. All rights reserved.