英文:
GEKKO (Python) giving incorrect solution
问题
-
为什么
results.json
文件与提示中显示的内容不匹配?这个问题可能是由于GEKKO求解器的设置或代码中的某些问题导致的。要解决这个问题,你可以检查以下几个方面:
-
检查GEKKO模型的设置,包括求解器、参数和约束条件是否正确设置。确保模型的目标函数和约束条件与你的预期一致。
-
检查代码中的随机数生成部分,确保随机数生成的方式和范围是正确的。
np.random.randint
和np.random.random
的使用应该是符合你的需求的。 -
检查结果文件
results.json
是否包含了正确的输出数据。如果结果文件不正确,可能是代码中输出结果的部分存在问题。
-
-
为什么我得到了错误的解决方案?
得到错误的解决方案可能是由于以下原因之一引起的:
-
模型的约束条件可能不正确或不完整,导致求解器找到了一个满足约束条件的局部最优解,但这个解并不是全局最优解。你应该仔细检查模型的约束条件,确保它们涵盖了问题的所有限制。
-
求解器选择和参数设置可能会影响结果。你可以尝试不同的求解器、不同的求解器选项或参数来寻找更好的解决方案。
-
模型的目标函数可能不正确。确保你的目标函数正确地描述了问题的优化目标。
-
代码中的数据生成部分可能存在问题,导致输入数据不符合预期。
-
要解决这个问题,你可以逐步调试代码,检查模型设置、约束条件和目标函数是否正确,以及检查输入数据是否合理。还可以尝试不同的求解器和参数设置来查找更好的解决方案。
英文:
Consider the following GEKKO code:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt
# Build model
#initialize GEKKO model
m = GEKKO()
m.options.solver = 1
# Seed
np.random.seed(0)
max_r = 5
min_r = 2
b = 2
b_r = {}
for i in range(b):
b_r[i] = np.random.randint(low=min_r,high=max_r)
u = 2
br = np.random.random((b,u))
lv = m.Array(m.Var,(b, u),lb=0,ub=1, integer=True)
av = {}
for i in range(b):
av[i] = m.Array(m.Var,(b_r[i], u),lb=0,ub=1, integer=True)
## Constraints
for i in range(u):
lv_sum = m.Const(value=0, name='Link Sum ' + str(i))
for j in range(b):
lv_sum += lv[j][i]
m.Equation(lv_sum <= 1)
for i in range(b):
for j in range(b_r[i]):
av_sum = m.Const(value=0, name='Alloc Sum ' + str((i,j)))
for k in range(u):
av_sum += av[i][j][k]
m.Equation(av_sum <= 1)
# Objective function
obj_u = m.Const(value=0, name='Final Objective')
for i in range(u):
obj_b = m.Const(value=0, name='Objective '+str(i))
for j in range(b):
for k in range(b_r[j]):
obj_b += lv[j][i]*av[j][k][i]*br[j][i]
obj_u += m.log(1+obj_b)
# Maximize/Minimize objective
m.Maximize(obj_u)
#Set global options
m.options.IMODE = 3 #steady state optimization
# m.options.IMODE = 6 #Dynamic optimization
print(m.path)
#Solve simulation
m.solve()
<!-- end snippet -->
Quite obviously the solution to this piece of code will always be non-negative as we are maximizing log(1+x)
where 0 <= x
. Yet somehow GEKKO gives the following output:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
/tmp/tmpw15jz3zhgk_model0
apm 203.192.204.172_gk_model0 <br><pre> ----------------------------------------------------------------
APMonitor, Version 1.0.1
APMonitor Optimization Suite
----------------------------------------------------------------
Warning: there is insufficient data in CSV file 203.192.204.172_gk_model0.csv
--------- APM Model Size ------------
Each time step contains
Objects : 0
Constants : 10
Variables : 21
Intermediates: 0
Connections : 0
Equations : 8
Residuals : 8
Number of state variables: 21
Number of total equations: - 7
Number of slack variables: - 7
---------------------------------------
Degrees of freedom : 7
----------------------------------------------
Steady State Optimization with APOPT Solver
----------------------------------------------
Iter: 1 I: 0 Tm: 0.00 NLPi: 7 Dpth: 0 Lvs: 0 Obj: -2.26E+00 Gap: 0.00E+00
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 1.460000000952277E-002 sec
Objective : -2.26374259105544
Successful solution
---------------------------------------------------
<!-- end snippet -->
The model file is as follows:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
Model
Constants
link_sum_0 = 0
link_sum_1 = 0
alloc_sum_0_0_ = 0
alloc_sum_0_1_ = 0
alloc_sum_1_0_ = 0
alloc_sum_1_1_ = 0
alloc_sum_1_2_ = 0
final_objective = 0
objective_0 = 0
objective_1 = 0
End Constants
Variables
int_v1 = 0, <= 1, >= 0
int_v2 = 0, <= 1, >= 0
int_v3 = 0, <= 1, >= 0
int_v4 = 0, <= 1, >= 0
int_v5 = 0, <= 1, >= 0
int_v6 = 0, <= 1, >= 0
int_v7 = 0, <= 1, >= 0
int_v8 = 0, <= 1, >= 0
int_v9 = 0, <= 1, >= 0
int_v10 = 0, <= 1, >= 0
int_v11 = 0, <= 1, >= 0
int_v12 = 0, <= 1, >= 0
int_v13 = 0, <= 1, >= 0
int_v14 = 0, <= 1, >= 0
End Variables
Equations
((link_sum_0+int_v1)+int_v3)<=1
((link_sum_1+int_v2)+int_v4)<=1
((alloc_sum_0_0_+int_v5)+int_v6)<=1
((alloc_sum_0_1_+int_v7)+int_v8)<=1
((alloc_sum_1_0_+int_v9)+int_v10)<=1
((alloc_sum_1_1_+int_v11)+int_v12)<=1
((alloc_sum_1_2_+int_v13)+int_v14)<=1
maximize ((final_objective+log((1+(((((objective_0+((((int_v1)*(int_v5)))*(0.8442657485810173)))+((((int_v1)*(int_v7)))*(0.8442657485810173)))+((((int_v3)*(int_v9)))*(0.8472517387841254)))+((((int_v3)*(int_v11)))*(0.8472517387841254)))+((((int_v3)*(int_v13)))*(0.8472517387841254))))))+log((1+(((((objective_1+((((int_v2)*(int_v6)))*(0.8579456176227568)))+((((int_v2)*(int_v8)))*(0.8579456176227568)))+((((int_v4)*(int_v10)))*(0.6235636967859723)))+((((int_v4)*(int_v12)))*(0.6235636967859723)))+((((int_v4)*(int_v14)))*(0.6235636967859723))))))
End Equations
End Model
<!-- end snippet -->
And the results.json
file is as follows:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
{
"time" : [0.00],
"link_sum_0" : [ 0.00 ],
"link_sum_1" : [ 0.00 ],
"alloc_sum_0_0_" : [ 0.00 ],
"alloc_sum_0_1_" : [ 0.00 ],
"alloc_sum_1_0_" : [ 0.00 ],
"alloc_sum_1_1_" : [ 0.00 ],
"alloc_sum_1_2_" : [ 0.00 ],
"final_objective" : [ 0.00 ],
"objective_0" : [ 0.00 ],
"objective_1" : [ 0.00 ],
"int_v1" : [ 0.00 ],
"int_v2" : [ 1.0000000000E+00],
"int_v3" : [ 1.0000000000E+00],
"int_v4" : [ 0.00 ],
"int_v5" : [ 0.00 ],
"int_v6" : [ 1.0000000000E+00],
"int_v7" : [ 0.00 ],
"int_v8" : [ 1.0000000000E+00],
"int_v9" : [ 1.0000000000E+00],
"int_v10" : [ 0.00 ],
"int_v11" : [ 1.0000000000E+00],
"int_v12" : [ 0.00 ],
"int_v13" : [ 1.0000000000E+00],
"int_v14" : [ 0.00 ],
"slk_1" : [ 0.00 ],
"slk_2" : [ 0.00 ],
"slk_3" : [ 0.00 ],
"slk_4" : [ 0.00 ],
"slk_5" : [ 0.00 ],
"slk_6" : [ 0.00 ],
"slk_7" : [ 0.00 ]
}
<!-- end snippet -->
I am confused of the folllowing:
- Why does the
results.json
not match with what is being displayed in the prompt? - More importantly why am I getting an incorrect solution?
答案1
得分: 1
m.Const()
是一个常数声明,而不是一个约束。然后,像以下的循环会重新定义这个常数:
for i in range(u):
lv_sum = m.Const(value=0, name='Link Sum ' + str(i))
for j in range(b):
lv_sum += lv[j][i]
m.Equation(lv_sum <= 1)
相反,可以这样定义 lv_sum
和约束:
for i in range(u):
lv_sum = m.Var(value=0, ub=1, name='Link Sum ' + str(i))
m.Equation(lv_sum == sum(lv[1:b][i]))
使用 m.Var()
定义变量,使用 m.Equation()
定义方程,或者使用 m.Equations()
一次性定义多个方程。不要使用 +=
,因为它会重新定义 gekko 变量。不要使用循环,可以尝试使用列表推导、矩阵操作和向量求和。这里有示例(参见 test_arrays.py
、test_matrix.py
、test_summations.py
)。一旦修复了问题定义,它应该会给你一个正确的问题陈述,然后求解器可以解决。
英文:
The m.Const()
is a constant declaration, not a constraint. Loops such as the following then redefine the constant:
for i in range(u):
lv_sum = m.Const(value=0, name='Link Sum ' + str(i))
for j in range(b):
lv_sum += lv[j][i]
m.Equation(lv_sum <= 1)
Instead, define lv_sum
and the constraint this way:
for i in range(u):
lv_sum = m.Var(value=0, ub=1, name='Link Sum ' + str(i))
m.Equation(lv_sum = sum(lv[1:b][i]))
Use m.Var()
to define the variable and m.Equation()
to define the equation or m.Equations()
to define multiple equations at once. Don't use +=
because it redefines the gekko variable. Instead of loops, try list comprehensions, matrix operations, and vector summations. Here are examples (see test_arrays.py
, test_matrix.py
, test_summations.py
). Once you fix the problem definition, it should give you a correct problem statement that the solver can then solve.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论