使用SLSQP进行scipy.optimize。 'LSQ子问题中的奇异矩阵C'

时间:2018-05-14 22:48:58

标签: python optimization scipy linear-programming minimize

我正在尝试最小化2个向量的点积,但它不起作用,我不知道为什么。有人可以帮助我吗?

我有一个这种形式的矩阵c:

c =  [[c11, c12, c13, c14, c15],
      [c21, c22, c23, c24, c25]]

我想得到这种形式的矩阵p:

 p =  [[p11, p12, p13, p14, p15],
      [p21, p22, p23, p24, p25]]

我想最大化这个值:

c11*p11 + c12*p12 +c13*p13 + c14*p14 + c15*p15 + c21*p21 + c22*p22 +c23*p23 + c24*p24 + c25*p25

为此,我将c和p转换为1-D向量并执行点积,以便我的函数最大化:

f(p) = c.dot(p)

约束是:

c11 + c12 + c13 + c14 + c15 = 1
c21 + c22 + c23 + c24 + c25 = 1

p中的每个元素必须介于0.01和0.99之间。

我尝试过scipy.optimize.linprog并且有效:

from scipy.optimize import linprog

c = np.array([0. , 0. , 0. , 0. , 0. , 0. , 20094.21019108, 4624.08079143, 6625.51724138, 3834.81081081])

A_eq = np.array([[1,1,1,1,1,0,0,0,0,0],
                 [0,0,0,0,0,1,1,1,1,1]])

b_eq = np.array([1, 1])

res = linprog(-c, A_eq=A_eq, b_eq=b_eq, bounds=(0.01, 0.99))


res
Out[561]: 
 fun: -19441.285871873002
 message: 'Optimization terminated successfully.'
 nit: 13
 slack: array([0.03, 0.98, 0.98, 0.98, 0.98, 0.98, 0.03, 0.98, 0.98, 0.98, 0.  ,
   0.  , 0.95, 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ])
 status: 0
 success: True
   x: array([0.96, 0.01, 0.01, 0.01, 0.01, 0.01, 0.96, 0.01, 0.01, 0.0

但我正在尝试用SLSQP替换scipy.optimize.minimize,这就是我在LSQ子问题中得到'奇异矩阵C'的地方。这就是我所做的:

from scipy.optimize import minimize

def build_objective(ck, sign = -1.00):
    """
    Builds the objective fuction for matrix ck
    """
    # Here I turn my c matrix to a 1-D matrix
    ck = np.concatenate(ck)
    def objective(P):
         return sign*(ck.dot(P))
    return objective

def build_constraint_rows(ck):
    """
    Builds the constraint functions that specify that the sum of the proportions for
    each bin equals 1
    """

    ncol = ck.shape[1]
    nrow = ck.shape[0]
    constrain_dict = []
    for i in range(nrow):

        vector = np.zeros((nrow,ncol))
        vector[i, :] =  1
        vector  = np.concatenate(vector)

        def row_constrain(P):
            return 1 - vector.dot(P) 

        constrain_dict.append({'type': 'eq', 'fun': row_constrain})

    return constrain_dict

# Matrix: Notice that this is not in vector form yet
c = np.array([[0. , 0. , 0. ,  0.,  0.], 
              [0. , 20094.21019108,  4624.08079143,  6625.51724138, 3834.81081081]])

# I need some initial p matrix for the function 'minimize'. I look for the value of the row that is the highest and assign it a proportion p of 0.96 and the rest 0.01 so the sum in 1 per row

P_initial = np.ones(c.shape)*0.01
nrow = test.shape[0]
for i in range(nrow):

    index= np.where(c[i,] == np.max(c[i,]))[0]

    if index.shape[0] > 1:
        index = int(np.random.choice(index, size = 1))
    else:
        index = int(index)
    P_initial[i,index] = 0.96

# I turn the P_initial to vector form
P_initial =  np.concatenate(P_initial)

# These are the bounds of each p value
b = (0.01,0.99)
bnds = (b,)*c.size


# I then use my previous functions

objective_fun = build_objective(c)
cons = build_constraint_rows(c)
res =  minimize(objective_fun,P_initial,method='SLSQP',\
                    bounds=bnds,constraints=cons)

这是我的最终结果:

res
Out[546]: 
 fun: -19434.501741138763
 jac: array([0. , 0.,0. , 0. ,0. , 0., -20094.21020508, -4624.08056641, -6625.51708984,  -3834.81079102])
 message: 'Singular matrix C in LSQ subproblem'
 nfev: 24
 nit: 2
 njev: 2
 status: 6
 success: False
 x: array([0.96      , 0.01      , 0.01      , 0.01      , 0.01      ,
   0.01020202, 0.95962502, 0.01006926, 0.01001178, 0.01009192])

请帮助我理解我做错了什么。

先谢谢你,

的Karol

0 个答案:

没有答案