我正在尝试最小化目标函数,同时使用for循环来设置约束,使得x1 = x2 = ... xn。但是,优化似乎不起作用。即结束x仍然等于初始x。我收到LSQ子问题中的奇异矩阵C的错误信息'。
covariance_matrix = np.matrix([[0.159775519, 0.022286316, 0.00137635, -0.001861736],
[0.022286316, 0.180593862, -5.5578e-05, 0.00451056],
[0.00137635, -5.5578e-05, 0.053093075, 0.02240866],
[-0.001861736, 0.00451056, 0.02240866, 0.053778594]])
x0 = np.matrix([0.2,0.2,0.3,0.4])
fun = lambda x: x.dot(covariance_matrix).dot(x.transpose())
cons = np.array([])
for i in range(0,x0.size-1):
con = {'type': 'eq', 'fun': lambda x: x[i] - x[i+1]}
cons = np.append(cons, con)
con = {'type': 'eq', 'fun': lambda x: sum(x)-1}
cons = np.append(cons, con)
solution = minimize(fun,x0,method='SLSQP',constraints = cons)
solution message: Singular matrix C in LSQ subproblem
solution status: 6
solution success: False
但是如果我逐个附加约束,那么它的效果很好,这意味着结果给了我x1 = x2 = x3 = x4
con1 = {'type': 'eq', 'fun': lambda x: sum(x)-1}
con2 = {'type': 'eq', 'fun': lambda x: x[1]-x[0]}
con3 = {'type': 'eq', 'fun': lambda x: x[2]-x[1]}
con4 = {'type': 'eq', 'fun': lambda x: x[3]-x[2]}
cons = np.append(cons, con1)
cons = np.append(cons, con2)
cons = np.append(cons, con3)
cons = np.append(cons, con4)
solution message: Optimization terminated successfully.
solution status: 0
solution success: True
答案 0 :(得分:1)
(注意:虽然细节不同,但这个问题与Scipy.optimize.minimize SLSQP with linear constraints fails的问题大致相同。)
你的循环是
for i in range(0,x0.size-1):
con = {'type': 'eq', 'fun': lambda x: x[i] - x[i+1]}
cons = np.append(cons, con)
问题是在lambda表达式中使用i
。 Python closures are "late binding"。这意味着在调用函数时使用的i
的值与创建函数时i
的值不同。在循环之后,i
的值为2,因此循环中创建的所有函数计算的表达式为x[2] - x[3]
。 (这也解释了错误消息中提到的“奇异矩阵C”。)
解决此问题的一种方法是使i
成为lambda表达式的参数,其默认值为当前i
:
con = {'type': 'eq', 'fun': lambda x, i=i: x[i] - x[i+1]}