我使用scipy.optimize.minimize的COBYLA方法为一个范畴分布寻找一个参数矩阵,我需要施加这样的约束:每个参数都大于零,并且参数矩阵的行和是一个列。
我不清楚如何在scipy.minimize中实现这一点,因为约束是检查非负面的,而不是真实的。如果我只是将数组作为约束传递,最小化就会引发异常。
有人知道如何实现这类约束吗?
发布于 2016-02-25 15:39:26
第一个约束x > 0可以非常简单地表示:
{'type':'ineq', 'fun': lambda x: x}第二个约束是相等约束,COBYLA本机不支持这个约束。但是,您可以将其表示为两个独立的不平等约束:
{'type':'ineq', 'fun': lambda x: np.sum(x, 0) - 1} # row sum >= 1
{'type':'ineq', 'fun': lambda x: 1 - np.sum(x, 0)} # row sum <= 1否则,您可以尝试SLSQP,它确实支持等式约束。
发布于 2016-02-25 15:40:08
您需要执行np.sum(x, 1) == 1的等式约束,而对于x >= 0则需要不等式约束。
但是,COBYLA方法只能处理不等式约束,正如minimize文档中所解释的那样(参见解释constraints参数的部分)。相反,您可以使用序列最小SQuares编程(SLSQP),它支持两种类型的约束。minimize函数应该根据您指定的约束自动为您选择正确的求解器。
您需要的约束可以实现如下所示:
def ineq_constraint(x):
"""constrain all elements of x to be >= 0"""
return x
def eq_constraint(x):
"""constrain the sum of all rows to be equal to 1"""
return np.sum(x, 1) - 1
constraints = [{'type': 'ineq', 'fun': ineq_constraint},
{'type': 'eq', 'fun': eq_constraint}]
result = minimize(objective_function, x0, constraints=constraints)https://stackoverflow.com/questions/35631192
复制相似问题