Gekko 不遵守变量的限制

Gekko is not respecting the restrictions of the variables

Gekko 不遵守这些限制,因此无法找到与 excel 求解器相同的解决方案。

这是要解决的问题,错误最小化

from gekko import GEKKO
import numpy as np
obj = 0
obj2 = 0
m = GEKKO(remote=False)
v0 = m.Var(0.002, -0.005, 0.005)
v1 = m.Var(0.004, -0.005, 0.005)
v2 = m.Var(0.002, -0.005, 0.005)
v3 = m.Var(0.002, -0.005, 0.005)
v4 = m.Var(0.002, -0.005, 0.005)
v5 = m.Var(0.001, -0.005, 0.005)
v6 = m.Var(0.003, -0.005, 0.005)
v7 = m.Var(-0.005, -0.005, 0.005)
v8 = m.Var(-0.002, -0.005, 0.005)
v9 = m.Var(-0.001, -0.005, 0.005)
y = []
y.append(v0)
y.append(v1)
y.append(v2)
y.append(v3)
y.append(v4)
y.append(v5)
y.append(v6)
y.append(v7)
y.append(v8)
objetivos = []
obj = 0
pq = []
p = ponderaciones[:9]
p2 = ponderaciones[9:]
r = rentabilidades[:9]
r2 = rentabilidades[9:]
for j in range(len(r2) + len(r)):
    if j < (len(r)):
        obj += p[j]/(1+y[j])*r[j]
    else:
        iterator = j - len(r)
        obj += p2[iterator]*r2[iterator]
objetivos.append(obj)
pq.append(obj)
a = np.array(objetivos)
b = un_pickle
print(b[0])
z = (np.sum(b[0]- a[0]))**2
m.Minimize(z)
m.solve(disp=False)
print(y)
print('Objective = '+str(m.options.objfcnval*1000000000/5))

我试图通过这样做来限制变量,

yb = m.Array(m.Var, 0.004, lb = -0.005, ub = 0.005)

但是也没用。

最终的解法和变数是这样结束的

[[0.00039421467367], [0.00078856597697], [0.00039428301399], [0.00039428298849], [0.00039428298849], [0.00019714149424], [0.00059142448273], [-0.00096599525378], [-0.0003942834613]]
Objective = 9.2421428926

我不确定为什么这些限制不起作用。

为了重现问题,我限制了数据量,但在完整的情况下 ponderacionesrentabilidades 是具有许多 DF 的字典里面,在这种情况下,它们只是一个系列。

ponderaciones = pd.Series({'ACC': 0.07645771,
 'UAA': 0.0,
 'EOAO': 0.000712,
 'CIA': 0.0055,
 'BJA': 0.01,
 'BOEA': 0.03,
 'UA': 0.110,
 'EOA': 0.0712,
 'CI': 0.00557,
 'BJ': 0.0161,
 'BOE': 0.0355,
 'U': 0.0553,
 'E': 0.00071231,
 'C': 0.005555,
 'B': 0.0157,
 'E': 0.0335}
)

rentabilidades = pd.Series({'ACC': 0.0035323168,
 'UAA': 0.033975,
 'EOAO': -0.0016047,
 'CIA': -0.00248652,
 'BJA': -0.0075425,
 'BOEA': 0.0016429,
 'UA': 0.550,
 'EOA': 0.0512,
 'CI': 0.00157,
 'BJ': 0.0861,
 'BOE': 0.0555,
 'U': 0.0593,
 'E': 0.00231,
 'C': 0.0555,
 'B': 0.07,
 'E': 0.05
})

un_pickle = [0.00119,  0.00107,  0.0013,  0.00105,  0.00182]

该脚本给出了一个解决方案,该解决方案在所有变量的范围内 -0.005<y<0.005。未遵守边界的一个潜在原因是求解器未能找到解决方案。切换到 disp=True 显示求解器输出以确保找到成功的解决方案。

EXIT: Optimal Solution Found.

 The solution was found.

 The final value of the objective function is  0.005269679643169275
 
 ---------------------------------------------------
 Solver         :  IPOPT (v3.12)
 Solution time  :  0.011 sec
 Objective      :  0.005269679643169275
 Successful solution
 ---------------------------------------------------
[[0.00080192314638], [0.00066898310209], [0.00033248534634], [0.00031046466289], \
[0.00020163446647], [0.00025390495361], [0.004994273964], [0.0049445497412], \
[-0.00031911076974]]
Objective = 1053935.92864

要检查的另一件事是 objective 函数定义是否正确。

z = (np.sum(b[0]- a[0]))**2
m.Minimize(z)

这个语句是只有一个值的求和,求和的外面有一个正方形**2。如果是误差平方和,则一般在求和之前进行平方。在这种情况下,它不会改变问题的结果,因为 b[0]a[0] 只是一个值和表达式。

from gekko import GEKKO
import numpy as np
import pandas as pd
obj = 0
obj2 = 0

ponderaciones = pd.Series({'ACC': 0.07645771,
 'UAA': 0.0,
 'EOAO': 0.000712,
 'CIA': 0.0055,
 'BJA': 0.01,
 'BOEA': 0.03,
 'UA': 0.110,
 'EOA': 0.0712,
 'CI': 0.00557,
 'BJ': 0.0161,
 'BOE': 0.0355,
 'U': 0.0553,
 'E': 0.00071231,
 'C': 0.005555,
 'B': 0.0157,
 'E': 0.0335}
)

rentabilidades = pd.Series({'ACC': 0.0035323168,
 'UAA': 0.033975,
 'EOAO': -0.0016047,
 'CIA': -0.00248652,
 'BJA': -0.0075425,
 'BOEA': 0.0016429,
 'UA': 0.550,
 'EOA': 0.0512,
 'CI': 0.00157,
 'BJ': 0.0861,
 'BOE': 0.0555,
 'U': 0.0593,
 'E': 0.00231,
 'C': 0.0555,
 'B': 0.07,
 'E': 0.05
})

un_pickle = [0.00119,  0.00107,  0.0013,  0.00105,  0.00182]

m = GEKKO(remote=False)
v0 = m.Var(0.002, -0.005, 0.005)
v1 = m.Var(0.004, -0.005, 0.005)
v2 = m.Var(0.002, -0.005, 0.005)
v3 = m.Var(0.002, -0.005, 0.005)
v4 = m.Var(0.002, -0.005, 0.005)
v5 = m.Var(0.001, -0.005, 0.005)
v6 = m.Var(0.003, -0.005, 0.005)
v7 = m.Var(-0.005, -0.005, 0.005)
v8 = m.Var(-0.002, -0.005, 0.005)
v9 = m.Var(-0.001, -0.005, 0.005)
y = []
y.append(v0)
y.append(v1)
y.append(v2)
y.append(v3)
y.append(v4)
y.append(v5)
y.append(v6)
y.append(v7)
y.append(v8)
objetivos = []
obj = 0
pq = []
p = ponderaciones[:9]
p2 = ponderaciones[9:]
r = rentabilidades[:9]
r2 = rentabilidades[9:]
for j in range(len(r2) + len(r)):
    if j < (len(r)):
        obj += p[j]/(1+y[j])*r[j]
    else:
        iterator = j - len(r)
        obj += p2[iterator]*r2[iterator]
objetivos.append(obj)
pq.append(obj)
a = np.array(objetivos)
b = un_pickle
print(b[0])
z = (np.sum(b[0]- a[0]))**2
m.Minimize(z)
m.solve(disp=True)
print(y)
print('Objective = '+str(m.options.objfcnval*1000000000/5))