我试图最小化长度为 20 的向量的函数,但我想将解决方案限制为单调的,即
x[1] <= x[2]... <= x[20]
我尝试使用此例程的"约束"通过以下方式实现这一点:
cons = tuple([{'type':'ineq', 'fun': lambda x: x[i]- x[i-1]} for i in range(1, len(node_vals))])
res = sp.optimize.minimize(localisation, b, args=(d), constraints = cons) #optimize
但是,我得到的结果不是单调的,即使最初的猜测b
,优化器似乎完全忽略了约束。可能出现什么问题?我也尝试将约束更改为x[i]**3 - x[i+1]**3
以使其"更平滑",但根本没有帮助。我的目标函数localisation
是特征值问题的解的积分,其参数是预先定义的:
def localisation(node_vals, domain): #calculate localisation for solutions with piecewise linear grading
f = piecewise(node_vals, domain) #create piecewise linear function using given values at nodes
#plt.plot(domain, f(domain))
M = diff_matrix(f(domain)) #differentiation matrix created from piecewise linear function
m = np.concatenate(([0], get_solutions(M)[1][:, 0], [0]))
integral = num_int(domain, m)
return integral
您没有发布我们可以运行的最小可重现示例。但是,您是否尝试指定在 SciPy 中使用哪种优化算法?像这样:
res = sp.optimize.minimize(localisation, b, args=(d), constraints = cons, method=‘SLSQP’)
我遇到了一个非常相似的问题,但在单调性属性上增加了上限和下限。我正在像这样解决问题(也许它对您有所帮助):
- 使用 scipy 给出的信任区域约束算法。这为我们提供了一种以矩阵方式处理线性约束的方法:
lb <= A.dot(x) <= ub
其中lb
和ub
是这个约束问题的下限(上限),A
是矩阵,表示线性约束问题。
矩阵
A
的每一行都是定义约束的线性项例如,如果
x[0] <= x[1]
,那么这可以转换为x[0] - x[1] <= 0
,就线性约束矩阵而言,A
看起来像这样[1, -1,...]
,前提是上界向量在这个水平上当然有一个 0 值(反之亦然也是可能的,但无论哪种方式,至少具有两者之一, 下限或上限,使这变得容易)设置足够多的这些不平等,同时将其中的几个合并为一个单一的不平等,可能会创建一个足够的矩阵来解决这个问题。
希望这有所帮助,它为我的问题完成了工作。