我希望在功能优化上指定一些多变量约束(例如,数组中的max-min应该小于X,解决方案数组的平均值应该高于Y等),所以我从一个简单的开始所有元素的约束应该是正的(所以我可以通过指定边界将其与结果进行比较)。
这是设置:我有一个化合物的目标组成,我有一个现有的组成,我想尽可能接近(通过元素数量的差异的绝对值的总和来衡量)通过改变现有的成分来确定目标配方。
from numpy import array
from scipy import optimize
from functools import partial
from pprint import pprint as pp
def allPositive(x):
return(1 if all([True if xi >= 0 else False for xi in x]) else -1)
def allPositiveAsArray(x):
return(all([1.0 if xi >= 0 else -1.0 for xi in x]))
def recipeDeviation(x, startComposition, recipeCompostion):
return sum( map(abs,array(x) + array(startComposition) - array(recipeCompostion)))
startComposition = [1.0,4.0,12.0]
recipeCompostion = [7.0,4.0,10.0]
funcToMinimize = partial(recipeDeviation, startComposition = startComposition, recipeCompostion = recipeCompostion)
result_constrained_1 = optimize.fmin_cobyla(funcToMinimize ,[0.0]*len(startComposition), cons=[allPositive]) # fails and gives wrong number
result_constrained_2 = optimize.fmin_slsqp(funcToMinimize ,[0.0]*len(startComposition), bounds = [(0.0, float("inf"))]*len(startComposition))
result_constrained_3 = optimize.fmin_slsqp(funcToMinimize ,[0.0]*len(startComposition), f_ieqcons = allPositive ) # does not work
result_constrained_4 = optimize.fmin_slsqp(funcToMinimize ,[0.0]*len(startComposition), f_ieqcons = allPositiveAsArray ) # does not work
result_constrained_5 = optimize.fmin_slsqp(funcToMinimize ,[0.0]*len(startComposition), f_ieqcons = lambda x: 1.0 if x >=0.0 else -1.0 ) # does not work
答案是[6.0,0.0,0.0](受限制)。
对于fmin_cobyla
,它失败了,但至少它告诉我出错了:COBYLA failed to find a solution: Did not converge to a solution satisfying the constraints. See
maxcv for magnitude of violation.
指定边界可以在fmin_slsqp
上提供正确的解决方案,但它无法帮助我推广到可行的函数。选项3和4给出了无约束的结果(告诉我规范是错误的)。
我需要一个用于在多变量设置中指定此类约束(可能使用上面的示例)的语法示例。