1

我正在尝试使用 scipy 最小化 SLSQP 中的边界来解决约束最大化问题。但为什么我会收到此消息:“LSQ 子问题中的奇异矩阵 C”?如何解决这个问题?当我删除约束并尝试最小化目标函数时,它工作正常,但是当我试图最大化它时,它显示“线搜索的正方向导数”。代码如下:

#Import libs
import numpy as np 
import matplotlib.pyplot as plt 
from scipy.optimize import minimize, Bounds

#Initial activity level
x0 = np.array([60, 40])

#Revenue function
def revenue(X):
    dollarperTRx = 300
    coeff_x1 = 0.234
    coeff_x2 = 0.127
    predwo= 1.245
    nhcp = 400
    r = dollarperTRx * nhcp * predwo * (pow(1 + (1+ X[0]),coeff_x1)) * (pow((1 + X[1]),coeff_x2))
    return r 

#Objective function
def objective(X, sign = -1.0):
    return sign * revenue(X)

#Spend
cost_per_promo = np.array([400, 600])
def spend(X):
    return np.dot(cost_per_promo, x0.transpose()) 

#Initial Spend
s0 = spend(x0)

#Spend constraint
def spend_constraint(X):
    return spend(X) - s0

#Getting the constraints into a dictionary
cons = ({'type':'eq', 'fun': spend_constraint})    

#Bounds
bounds1 = (30, 90)
bounds2 = (20, 60)

#Optimize
minimize(objective, x0, method='SLSQP', constraints = cons, bounds = (bounds1, bounds2))
4

1 回答 1

0

您的spend功能不依赖于您的设计向量,因此您的约束也不依赖于它。这使问题变得单一。我在您的示例中将 X0 更改为当前设计向量,这样它就会收敛。您必须验证这是否是您要对约束执行的操作。但是对于 X0,它总是给出 0。

#Import libs
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize, Bounds

#Initial activity level
x0 = np.array([60, 40])


#Revenue function
def revenue(X):
    dollarperTRx = 300
    coeff_x1 = 0.234
    coeff_x2 = 0.127
    predwo= 1.245
    nhcp = 400
    r = dollarperTRx * nhcp * predwo * (pow(1 + (1+ X[0]),coeff_x1)) * (pow((1 + X[1]),coeff_x2))
    return r

revenue0 = revenue(x0)

#Objective function
def objective(X):
    return -revenue(X) / revenue0

#Spend
cost_per_promo = np.array([400., 600.])
def spend(X):
    return np.dot(cost_per_promo, X.transpose())

#Initial Spend
s0 = spend(x0)

#Spend constraint
def spend_constraint(X):
    return spend(X) - s0

#Getting the constraints into a dictionary
cons = ({'type':'eq', 'fun': spend_constraint})

#Bounds
bounds1 = (30., 90.)
bounds2 = (20., 60.)

#Optimize
res = minimize(objective, x0, method='SLSQP',
               constraints = cons,
               bounds = (bounds1, bounds2))
print(res)

结果是:

     fun: -1.0157910949030706
     jac: array([-0.00297113, -0.00444862])
 message: 'Optimization terminated successfully.'
    nfev: 36
     nit: 9
    njev: 9
  status: 0
 success: True
       x: array([78.0015639, 27.9989574])
于 2019-11-25T19:18:01.820 回答