【问题标题】:Setting Scipy inequality constraints for Minimisation为最小化设置 Scipy 不等式约束
【发布时间】:2020-10-05 13:55:40
【问题描述】:

我最近遇到了这个问题。

我的任务是解决这个优化问题。

这是我设置代码的方式。

# import libraries
from scipy.optimize import minimize
import numpy as np

# Declare objective function
def objective_fun(x):
    return 49500*x[0] + 50000*x[1] + 61000*x[2] + 63500*x[3] + 66500*x[4] + 71000*x[5] + 72500*x[6] + 80000*x[7]

# Declare equality constraint 1
def constraint1(x):
    sum_con1 = 1225
    for i in range(7):
         sum_con1 = sum_con1 - x[i]

    return sum_con1

# Declare inequality constraint 2
def constraint2(x):
    return x[0] + x[1] + x[3] + x[5] - 612.5

# Declare inequality constraint 3
def constraint3(x):
    
    return 650 - x[0] + x[2] + x[6] + x[7]

# Declare inequality constraint 4
def constraint4(x):
    
    return 720 - x[1] + x[3] + x[4] + x[5]

# Declare inequality constraint 5
def constraint5(x):
    
    return 0.15*x[0] + 0.16*x[1] + 0.18*x[2] + 0.2*x[3] + 0.21*x[4] + 0.22*x[5] + 0.23*x[6] + 0.25*x[7] - 232.75

# Set scipy constraints
con1 = {"type": "eq", "fun" : constraint1}
con2 = {"type": "ineq", "fun" : constraint2}
con3 = {"type": "ineq", "fun" : constraint3}
con4 = {"type": "ineq", "fun" : constraint4}
con5 = {"type": "ineq", "fun" : constraint5}
cons = [con1, con2, con3, con4, con5]

# Set boundaries
b_0 = (0.0, 300.0)
b_1 = (0.0, 600.0)
b_2 = (0.0, 510.0)
b_3 = (0.0, 655.0)
b_4 = (0.0, 575.0)
b_5 = (0.0, 680.0)
b_6 = (0.0, 450.0)
b_7 = (0.0, 490.0)
bnds = (b_0, b_1, b_2, b_3, b_4, b_5, b_6, b_7)

# Set initial guess
i_0 = [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]

# Optimise minimise the function using scipy minimise
sol = minimize(objective_fun, i_0, method='SLSQP', bounds = bnds, constraints = cons)

# visualising the solution
print(sol)

当我运行代码时,成功为 False,x 值似乎没有被优化。

我想知道我的设置是否不正确,或者我在尝试此任务时遗漏了什么。

【问题讨论】:

  • 您的实现是正确的,但问题严重扩展。例如,尝试将 objective_fun(x) 乘以 1/1000 。另请参阅this 问题。一条评论提到目标的最佳范围在 1 到 5 之间...

标签: python numpy scipy jupyter-notebook


【解决方案1】:

经过几次调查,我发现我的代码有问题。

关于不等式约束的返回语句需要 LHS 位上的括号。

例如,

def constraint2(x):
    return (x[0] + x[1] + x[3] + x[5]) - 612.5

# Declare inequality constraint 3
def constraint3(x):
    
    return 650 - (x[0] + x[2] + x[6] + x[7])

# Declare inequality constraint 4
def constraint4(x):
    
    return 720 - (x[1] + x[3] + x[4] + x[5])

# Declare inequality constraint 5
def constraint5(x):
    
    return (0.15*x[0] + 0.16*x[1] + 0.18*x[2] + 0.2*x[3] + 0.21*x[4] + 0.22*x[5] + 0.23*x[6] + 0.25*x[7]) - 232.75

没有括号,最小化的结果是

x = [0.0, 600.0, 0.0, 111.0, 184.0,0.0, 330.0, 0.0]

带括号,

x = [55.0, 600.0, 0.0, 20.0, 100.0, 0.0, 450.0, 0.0]

我知道括号中的结果是正确的,因为我事先使用 Excel 进行了计算。

网上很多教程都没有提到不等式约束需要括号。

【讨论】:

  • 我确实尝试过您提到的重新缩放。我将我的 objecitve_fun() 乘以 1/1000 和 1/100,但这些并没有给我正确的结果。我再次检查了我的工作,发现唯一需要括号的约束是约束 4。我不太确定它为什么会这样。
  • 啊,我明白了。我读得不够仔细。当然a-b+ca-(b+c) = a-b-c 不同,所以这些括号不仅仅是为了展示,而是为了数学目的。您必须正确建模您的约束。所以约束 3 和 4 需要括号。如果删除约束 3 的括号后结果相同,则表示此约束未激活。
  • 我也意识到了这一点。我最初将减号作为不等号。我所学的教程并没有真正提到括号的使用,这就是为什么我一开始不太确定并发布问题的原因。
猜你喜欢
  • 2017-07-07
  • 1970-01-01
  • 2013-12-03
  • 1970-01-01
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 2020-08-08
  • 2017-08-01
相关资源
最近更新 更多