当我尝试使用for循环设置约束时,Scipy优化未运行 [英] Scipy Optimization Not Running when I try to set constraints using a for loop
问题描述
我试图在使用for循环设置约束时使目标函数最小化,以使x1 = x2 = ... xn.但是,优化似乎没有用. IE.结束x仍然等于初始x.而且我收到一条错误消息"LSQ子问题中的奇异矩阵C".
I was trying to minimize the objective function while using a for loop to set the constraints such that x1 = x2 = ... xn. However, the optimization doesn't seem to work. I.e. the end x still equals to the initial x. And I am getting an error message of 'Singular matrix C in LSQ subproblem'.
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
But if I append the constraints one by one, then it works perfectly, meaning the result gives me 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
推荐答案
(Note: while the details are different, this question is about the same problem as 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闭包是后期绑定" .这意味着调用函数时使用的i
值与创建函数时使用的i
值不同.循环后,i
的值为2,因此循环中创建的所有函数所求值的表达式为x[2] - x[3]
. (这也解释了错误消息中提到的奇异矩阵C".)
The problem is the use of i
in the lambda expression. Python closures are "late binding". That means value of i
that is used when the function is called is not the same as the value of i
when the function was created. After the loop, the value of i
is 2, so the expression evaluated by all the functions created in the loop is x[2] - x[3]
. (That also explains the "singular matrix C" referred to in the error message.)
解决此问题的一种方法是将i
用作默认值为当前i
的lambda表达式的参数:
One way to fix this is to make i
an argument of the lambda expression whose default value is the current i
:
con = {'type': 'eq', 'fun': lambda x, i=i: x[i] - x[i+1]}
这篇关于当我尝试使用for循环设置约束时,Scipy优化未运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!