Scipy最小化因不等式约束或界限而失败

数据挖掘 优化 scipy
2022-03-03 21:50:01

我正在尝试使用 scipy.optimize 来解决最小化问题,但在使用不等式约束或界限时会失败。寻找有关正确使用约束与界限的任何建议,以及在这种情况下是否适合任何其他算法。

问题是:

在此处输入图像描述

这是一个可重现的代码(res['success'] 和 res1['success'] 都是 False- 优化失败):

import pandas as pd
import numpy as np
from scipy.optimize import minimize as scimin

def obj(wc, M, wb, S):
    return (wc.dot(M.T) - wb).dot(S).dot(wc.dot(M.T) - wb)

n=278
k= 16

c_labels = ['c'+ str(i) for i in range(k)]
r_labels_1 = ['r' + str(i) +s for i in range(k) for s in ['a', 'b']]
r_labels_2 = ['r' + str(i) for i in range(k, n-k)]
r_labels = r_labels_1 + r_labels_2

wb = pd.Series(index=r_labels, data=np.random.triangular(0, 1.0/n, 0.3, n))
wb = wb/wb.sum()
cc = pd.Series(index=c_labels, data=4 + 2*np.random.random(k))
cb = pd.Series(index=r_labels, data=3 + 10*np.random.random(n))
s_pre = np.random.rand(n, n)
S = pd.DataFrame(index=r_labels, columns= r_labels, data=s_pre.dot(s_pre.T))

M = pd.DataFrame(data=np.eye(k), index= ['r'+ str(i) +'a' for i in range(k)], columns = c_labels)
for i in range(k):
    M.loc['r' + str(i)+ 'b'] = M.loc['r' + str(i) + 'a']
M = M.loc[r_labels_1].applymap(lambda x: x* np.random.rand())
M = M / M.sum()
for i in r_labels_2:
    M.loc[i] = 0

one_k = pd.DataFrame(index=M.columns, data=np.ones(len(M.columns)))
con1 = {'type': 'eq', 'fun': lambda x: x.sum() - 1}
con2 = {'type': 'eq', 'fun': lambda x: cc.dot(x) - cb.dot(wb)}

# try 1 with inequality constraint
con3 = {'type': 'ineq', 'fun': lambda x: min(x)}
consts = [con1, con2, con3]
res = scimin(obj, x0=one_k, args=(M, wb, S), constraints=consts, method='SLSQP')
assert (res['success'] == True)
wc = res['x']
oj = obj(wc, M, wb, S)

# try 2 with bounds instead of inequality constraint
bounds = [(0, 1000)] *len(M.columns)
consts = [con1, con2]
res1 = scimin(obj, x0=one_k, args=(M, wb, S), constraints=consts, bounds= bounds, method='SLSQP')
assert (res1['success'] == True)
wc1 = res1['x']
oj1 = obj(wc1, M, wb, S)
0个回答
没有发现任何回复~