设置Scipy不等式约束以最小化

问题描述

我最近遇到了这个问题。

我有一个任务来解决此优化问题。

enter image description here

这是我设置代码的方式。

# 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]

# 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值似乎没有得到优化。

我想知道我的设置是否不正确,或者在尝试执行此任务时是否遗漏了一些东西。

解决方法

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

关于不等式约束的return语句需要在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进行了计算。

许多在线教程都没有提到不平等约束中括号的要求。