GEKKO(Python)提供了不正确的解决方案。

huangapple go评论93阅读模式
英文:

GEKKO (Python) giving incorrect solution

问题

  1. 为什么 results.json 文件与提示中显示的内容不匹配?

    这个问题可能是由于GEKKO求解器的设置或代码中的某些问题导致的。要解决这个问题,你可以检查以下几个方面:

    • 检查GEKKO模型的设置,包括求解器、参数和约束条件是否正确设置。确保模型的目标函数和约束条件与你的预期一致。

    • 检查代码中的随机数生成部分,确保随机数生成的方式和范围是正确的。np.random.randintnp.random.random 的使用应该是符合你的需求的。

    • 检查结果文件 results.json 是否包含了正确的输出数据。如果结果文件不正确,可能是代码中输出结果的部分存在问题。

  2. 为什么我得到了错误的解决方案?

    得到错误的解决方案可能是由于以下原因之一引起的:

    • 模型的约束条件可能不正确或不完整,导致求解器找到了一个满足约束条件的局部最优解,但这个解并不是全局最优解。你应该仔细检查模型的约束条件,确保它们涵盖了问题的所有限制。

    • 求解器选择和参数设置可能会影响结果。你可以尝试不同的求解器、不同的求解器选项或参数来寻找更好的解决方案。

    • 模型的目标函数可能不正确。确保你的目标函数正确地描述了问题的优化目标。

    • 代码中的数据生成部分可能存在问题,导致输入数据不符合预期。

要解决这个问题,你可以逐步调试代码,检查模型设置、约束条件和目标函数是否正确,以及检查输入数据是否合理。还可以尝试不同的求解器和参数设置来查找更好的解决方案。

英文:

Consider the following GEKKO code:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

  1. import numpy as np
  2. from gekko import GEKKO
  3. import matplotlib.pyplot as plt
  4. # Build model
  5. #initialize GEKKO model
  6. m = GEKKO()
  7. m.options.solver = 1
  8. # Seed
  9. np.random.seed(0)
  10. max_r = 5
  11. min_r = 2
  12. b = 2
  13. b_r = {}
  14. for i in range(b):
  15. b_r[i] = np.random.randint(low=min_r,high=max_r)
  16. u = 2
  17. br = np.random.random((b,u))
  18. lv = m.Array(m.Var,(b, u),lb=0,ub=1, integer=True)
  19. av = {}
  20. for i in range(b):
  21. av[i] = m.Array(m.Var,(b_r[i], u),lb=0,ub=1, integer=True)
  22. ## Constraints
  23. for i in range(u):
  24. lv_sum = m.Const(value=0, name=&#39;Link Sum &#39; + str(i))
  25. for j in range(b):
  26. lv_sum += lv[j][i]
  27. m.Equation(lv_sum &lt;= 1)
  28. for i in range(b):
  29. for j in range(b_r[i]):
  30. av_sum = m.Const(value=0, name=&#39;Alloc Sum &#39; + str((i,j)))
  31. for k in range(u):
  32. av_sum += av[i][j][k]
  33. m.Equation(av_sum &lt;= 1)
  34. # Objective function
  35. obj_u = m.Const(value=0, name=&#39;Final Objective&#39;)
  36. for i in range(u):
  37. obj_b = m.Const(value=0, name=&#39;Objective &#39;+str(i))
  38. for j in range(b):
  39. for k in range(b_r[j]):
  40. obj_b += lv[j][i]*av[j][k][i]*br[j][i]
  41. obj_u += m.log(1+obj_b)
  42. # Maximize/Minimize objective
  43. m.Maximize(obj_u)
  44. #Set global options
  45. m.options.IMODE = 3 #steady state optimization
  46. # m.options.IMODE = 6 #Dynamic optimization
  47. print(m.path)
  48. #Solve simulation
  49. 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 &lt;= x. Yet somehow GEKKO gives the following output:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

  1. /tmp/tmpw15jz3zhgk_model0
  2. apm 203.192.204.172_gk_model0 &lt;br&gt;&lt;pre&gt; ----------------------------------------------------------------
  3. APMonitor, Version 1.0.1
  4. APMonitor Optimization Suite
  5. ----------------------------------------------------------------
  6. Warning: there is insufficient data in CSV file 203.192.204.172_gk_model0.csv
  7. --------- APM Model Size ------------
  8. Each time step contains
  9. Objects : 0
  10. Constants : 10
  11. Variables : 21
  12. Intermediates: 0
  13. Connections : 0
  14. Equations : 8
  15. Residuals : 8
  16. Number of state variables: 21
  17. Number of total equations: - 7
  18. Number of slack variables: - 7
  19. ---------------------------------------
  20. Degrees of freedom : 7
  21. ----------------------------------------------
  22. Steady State Optimization with APOPT Solver
  23. ----------------------------------------------
  24. Iter: 1 I: 0 Tm: 0.00 NLPi: 7 Dpth: 0 Lvs: 0 Obj: -2.26E+00 Gap: 0.00E+00
  25. Successful solution
  26. ---------------------------------------------------
  27. Solver : APOPT (v1.0)
  28. Solution time : 1.460000000952277E-002 sec
  29. Objective : -2.26374259105544
  30. Successful solution
  31. ---------------------------------------------------

<!-- end snippet -->

The model file is as follows:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

  1. Model
  2. Constants
  3. link_sum_0 = 0
  4. link_sum_1 = 0
  5. alloc_sum_0_0_ = 0
  6. alloc_sum_0_1_ = 0
  7. alloc_sum_1_0_ = 0
  8. alloc_sum_1_1_ = 0
  9. alloc_sum_1_2_ = 0
  10. final_objective = 0
  11. objective_0 = 0
  12. objective_1 = 0
  13. End Constants
  14. Variables
  15. int_v1 = 0, &lt;= 1, &gt;= 0
  16. int_v2 = 0, &lt;= 1, &gt;= 0
  17. int_v3 = 0, &lt;= 1, &gt;= 0
  18. int_v4 = 0, &lt;= 1, &gt;= 0
  19. int_v5 = 0, &lt;= 1, &gt;= 0
  20. int_v6 = 0, &lt;= 1, &gt;= 0
  21. int_v7 = 0, &lt;= 1, &gt;= 0
  22. int_v8 = 0, &lt;= 1, &gt;= 0
  23. int_v9 = 0, &lt;= 1, &gt;= 0
  24. int_v10 = 0, &lt;= 1, &gt;= 0
  25. int_v11 = 0, &lt;= 1, &gt;= 0
  26. int_v12 = 0, &lt;= 1, &gt;= 0
  27. int_v13 = 0, &lt;= 1, &gt;= 0
  28. int_v14 = 0, &lt;= 1, &gt;= 0
  29. End Variables
  30. Equations
  31. ((link_sum_0+int_v1)+int_v3)&lt;=1
  32. ((link_sum_1+int_v2)+int_v4)&lt;=1
  33. ((alloc_sum_0_0_+int_v5)+int_v6)&lt;=1
  34. ((alloc_sum_0_1_+int_v7)+int_v8)&lt;=1
  35. ((alloc_sum_1_0_+int_v9)+int_v10)&lt;=1
  36. ((alloc_sum_1_1_+int_v11)+int_v12)&lt;=1
  37. ((alloc_sum_1_2_+int_v13)+int_v14)&lt;=1
  38. 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))))))
  39. End Equations
  40. End Model

<!-- end snippet -->

And the results.json file is as follows:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

  1. {
  2. &quot;time&quot; : [0.00],
  3. &quot;link_sum_0&quot; : [ 0.00 ],
  4. &quot;link_sum_1&quot; : [ 0.00 ],
  5. &quot;alloc_sum_0_0_&quot; : [ 0.00 ],
  6. &quot;alloc_sum_0_1_&quot; : [ 0.00 ],
  7. &quot;alloc_sum_1_0_&quot; : [ 0.00 ],
  8. &quot;alloc_sum_1_1_&quot; : [ 0.00 ],
  9. &quot;alloc_sum_1_2_&quot; : [ 0.00 ],
  10. &quot;final_objective&quot; : [ 0.00 ],
  11. &quot;objective_0&quot; : [ 0.00 ],
  12. &quot;objective_1&quot; : [ 0.00 ],
  13. &quot;int_v1&quot; : [ 0.00 ],
  14. &quot;int_v2&quot; : [ 1.0000000000E+00],
  15. &quot;int_v3&quot; : [ 1.0000000000E+00],
  16. &quot;int_v4&quot; : [ 0.00 ],
  17. &quot;int_v5&quot; : [ 0.00 ],
  18. &quot;int_v6&quot; : [ 1.0000000000E+00],
  19. &quot;int_v7&quot; : [ 0.00 ],
  20. &quot;int_v8&quot; : [ 1.0000000000E+00],
  21. &quot;int_v9&quot; : [ 1.0000000000E+00],
  22. &quot;int_v10&quot; : [ 0.00 ],
  23. &quot;int_v11&quot; : [ 1.0000000000E+00],
  24. &quot;int_v12&quot; : [ 0.00 ],
  25. &quot;int_v13&quot; : [ 1.0000000000E+00],
  26. &quot;int_v14&quot; : [ 0.00 ],
  27. &quot;slk_1&quot; : [ 0.00 ],
  28. &quot;slk_2&quot; : [ 0.00 ],
  29. &quot;slk_3&quot; : [ 0.00 ],
  30. &quot;slk_4&quot; : [ 0.00 ],
  31. &quot;slk_5&quot; : [ 0.00 ],
  32. &quot;slk_6&quot; : [ 0.00 ],
  33. &quot;slk_7&quot; : [ 0.00 ]
  34. }

<!-- end snippet -->

I am confused of the folllowing:

  1. Why does the results.json not match with what is being displayed in the prompt?
  2. More importantly why am I getting an incorrect solution?

答案1

得分: 1

m.Const() 是一个常数声明,而不是一个约束。然后,像以下的循环会重新定义这个常数:

  1. for i in range(u):
  2. lv_sum = m.Const(value=0, name='Link Sum ' + str(i))
  3. for j in range(b):
  4. lv_sum += lv[j][i]
  5. m.Equation(lv_sum <= 1)

相反,可以这样定义 lv_sum 和约束:

  1. for i in range(u):
  2. lv_sum = m.Var(value=0, ub=1, name='Link Sum ' + str(i))
  3. m.Equation(lv_sum == sum(lv[1:b][i]))

使用 m.Var() 定义变量,使用 m.Equation() 定义方程,或者使用 m.Equations() 一次性定义多个方程。不要使用 +=,因为它会重新定义 gekko 变量。不要使用循环,可以尝试使用列表推导、矩阵操作和向量求和。这里有示例(参见 test_arrays.pytest_matrix.pytest_summations.py)。一旦修复了问题定义,它应该会给你一个正确的问题陈述,然后求解器可以解决。

英文:

The m.Const() is a constant declaration, not a constraint. Loops such as the following then redefine the constant:

  1. for i in range(u):
  2. lv_sum = m.Const(value=0, name=&#39;Link Sum &#39; + str(i))
  3. for j in range(b):
  4. lv_sum += lv[j][i]
  5. m.Equation(lv_sum &lt;= 1)

Instead, define lv_sum and the constraint this way:

  1. for i in range(u):
  2. lv_sum = m.Var(value=0, ub=1, name=&#39;Link Sum &#39; + str(i))
  3. 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.

huangapple
  • 本文由 发表于 2023年6月29日 19:27:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76580596.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定