scipy.optimize.minimize如何传入多个向量(矩阵)
记一次困扰了一周的问题
向量
一般情况下,对于一个多维函数的优化,往往是把$x_0, x_1, … ,x_n$放进一个$1 \times n$的数组中,然后把这个数组作为minimize的参数x0。但现在碰到了一个这样的问题,优化函数为:$$min||x-z||_2$$
约束为$Ax-b\leq0$并且$z\geq0$,其中A是一个$m \times n$的矩阵,b是$m \times 1$的矩阵。也就是说,x和z均为一个n维的向量。
起初我的思路是将x和z强行放在一个数组x0里,x作为x0[0],z作为x0[1]。但这样在添加约束的时候会发生错误,大概是因为在约束函数里x0[0]被当作了一个1x1的元素,无法点乘也无法与b进行相减。
这个思路没有错,但是把x和z压成一个向量的话,需要用到numpy里的hstack函数,这样等于是把x和z拼接成一个1x2n的向量而非一个2xn的矩阵。这样的话在优化函数中需要重新将这个1x2n的向量拆成两个1xn的向量:
1 | x = np.zeros(A.shape[1]) |
在约束中也是一样,需要对x0进行拆分。再返回结果的时候也是同样。
1 | cons = [{'type': 'ineq', 'fun': lambda x: b-np.dot(A, to_x_z(x)[0])}, {'type': 'ineq', 'fun': lambda x: to_x_z(x)[1] - 1e-10}] |
矩阵
若传入的是矩阵而非向量,思路也是一样,但是需要利用numpy里的flatten来先对每个矩阵进行压缩:
1 | np.hstack([w.flatten(), z.flatten()]) |
在拆分的时候,需要reshape一下让其恢复成矩阵:
1 | def to_x_z(x0): |
参考
scipy.optimize.minimize如何传入多个向量(矩阵)
http://xnsi.github.io/2020/11/19/scipy-minimize-with-vectors/