我正在尝试用 Python 包装外部代码,然后对其执行约束优化。我认为
scipy.optimize
应该有效,但我不确定如何设置约束。我的实际代码无法共享,但我想我可以在没有它的情况下说明问题。
假设我的外部代码采用这种形式:
def external_code(x):
# does stuff with the x[0] through x[2] inputs
# calculates all the outputs, y[0] through y[5]
return y
假设我的优化目标是最小化
y[0]
,这是在外部代码中计算的内容之一,受到许多约束。首先,各个 x
输入的可接受值存在限制,我认为我可以这样处理:bounds = Bounds([0.0, -np.inf, 0.0], [10.0, 10.0, 2.0])
。为了实现有效的最优,还必须遵守一些约束。与我发现的文档或讲座示例中的示例不同,我的约束是外部代码的其他输出(即,y[1]
到y[5]
),而不是的直接/简单组合。 x
输入。我想我需要设置一个像这样的约束函数:
def constraint_fcn(y):
return np.array([5.0 - y[1],
1.0 - y[2],
1.0 - (y[3]+y[4]+y[5])
])
我相信我需要将外部代码包装在一个附加层中,这样优化器就只有一个返回值可以操作,即
def minimize_this(x):
y = external_code(x)
return y[0]
对优化器的调用将类似于:
x0 = np.array([1.0, 0.0, 1.0])
res = scipy.optimize.minimize(minimize_this, x0, method='SLSQP', bounds=bounds,
constraints={'fun': constraint_fcn, 'type': 'ineq'})
问题是,虽然
minimize_this
设置为在 x0
上运行以及优化器每次连续选择 x
,但 constraint_fcn
并不意味着在 x
上运行,而是在那些附加的 y
上运行
调用 external_code
返回的值。理论上我可以设置 constraint_fcn
来代替接收 x
,自己调用 external_code
,然后根据 y[1]
到 y[5]
设置限制,但这意味着 minimize_this
和 constraint_fcn
正在对 external_code
进行 单独调用,出于计算性能原因,这是不可接受的。我在文档中看到要最小化的函数和约束函数都可以传递附加参数,但我没有看到如何将函数中的东西传递给我最小化到约束函数。我怀疑我只需要重新表述一些东西,但我一直无法找到更像我的设置的示例。
我认为你将被迫更多地评估你的外部功能。您可以更新
constraint_fcn
以将 x
作为参数,并通过外部函数求值获取 y 值。
def constraint_fcn(x):
y = external_code(x)
return np.array([5.0 - y[1],
1.0 - y[2],
1.0 - (y[3]+y[4]+y[5])
])