英文:
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.jsonnot 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论