我正在使用scipy.optimize.minimize(method='COBYLA')
.
为了评估成本函数,我需要运行相对昂贵的计算来根据输入变量计算数据集,而成本函数是该数据集的一个(计算成本低)属性。但是,我的两个约束也依赖于昂贵的数据。到目前为止,我发现约束优化的唯一方法是让每个约束函数重新计算成本函数已经拥有的相同数据集。
简化的准代码:
# universal cost function evaluator
def criterion_from_x(x, cfun):
data = expensive_fun(x)
return(cfun(data))
def costfun(data):
return(cheap_fun1(data))
def constr1(data):
return(cheap_fun2(data))
def constr2(data):
return(cheap_fun3(data))
constraints = [{'type':'ineq', 'fun':criterion_from_x, 'args':(constr1,)},
{'type':'ineq', 'fun':criterion_from_x, 'args':(constr2,)}
# initial guess
x0 = np.ones((6,))
opt_result = minimize(criterion_from_x, x0, method='COBYLA',
args=(costfun,), constraints=constraints)
所以我有一个通用的“评估一些成本”函数,它运行昂贵的计算,然后评估它给出的任何标准。但它需要为优化器的每次迭代运行 3 次。
我还没有找到任何方法来设置x
用于生成的东西data
,然后将其传递给目标函数和约束函数。
这样的事情存在吗?我注意到 的callback
参数minimize()
,但这是一个在每一步之后调用的函数。我需要某种预处理器,在每一步x
之前调用它,然后使用其结果而不是x
. 也许有办法以某种方式潜入它?我想避免编写自己的优化器。
解决此问题的一种传统方法是将违反约束的惩罚函数添加到主成本函数中,并在没有显式约束的情况下运行优化器,但我之前尝试过,发现主成本函数在在违反约束的情况下,优化器可能会卡在某个违反约束的地方而无法再次发现。
代码需要在 Python v2.7.6 到 2.7.13 和 scipy 0.13 到 0.17 的机器上工作。