我是 scipy.optimize 模块的新手。我正在使用其最小化函数尝试找到 x 来最小化多元函数,该函数接受矩阵输入但返回标量值。我有一个等式约束和一个不等式约束,两者都采用向量输入和返回向量值。特别是,这里是约束列表:
sum(x) = 1 ;
AST + np.log2(x) >= 0
其中
AST
只是一个参数。我定义了我的约束函数如下:
对于等式约束:
lambda x: sum(x) - 1
对于不等式约束:
def asset_cons(x):
#global AST
if np.logical_and.reduce( (AST + np.log2(x)) >= 0):
return 0.01
else:
return -1
然后我打电话
cons = ({'type':'eq', 'fun': lambda x: sum(x) - 1},
{'type':'ineq', 'fun': asset_cons})
res = optimize.minize(test_obj, [0.2, 0.8], constraints = cons)
但我仍然收到错误抱怨我的约束函数。是否允许返回约束函数的向量值,或者我必须返回标量才能使用此最小化函数?
谁能帮我看看我指定约束的方式是否有问题?
原则上这看起来并没有那么错误。然而,如果没有看到
test_obj
和实际错误的情况,就很难说。它是否抛出异常(暗示编程错误)或抱怨收敛(暗示数学挑战)?
你的基本想法是对的;您需要有一个函数接受具有 N 个元素的输入向量并返回要最小化的值。您的边界条件还应该接受相同的输入向量并返回单个标量作为其输出。
在我看来,你的边界条件有问题。第一个 (
sum(x) - 1
) 很好,但第二个在数学上具有挑战性,因为您将其定义为逐步函数。许多优化算法希望具有具有更好的相当平滑行为的连续函数。 (我不知道这个函数使用的算法是否能很好地处理逐步函数,所以这只是一个猜测。
如果上述情况成立,您可以通过以下方式使事情变得更容易:
np.amin(AST + np.log2(x))
如果全部
AST + log2(x[n]) >= 0
,该函数将是非负的。 (它仍然不是非常平滑,但如果这是一个问题,很容易改进。)现在它也适合一个lambda
。
如果您在收敛方面遇到困难,您可能应该尝试 COBYLA 和 SLSQP,除非您已经知道其中之一更适合您的问题。