到目前为止,似乎不可能在搜索空间的维度之间指定这种类型的依赖关系。但是,您可以将约束a2 <= 2*a1
合并到传递给优化器的目标中。
f
在下面的示例中,仅在满足约束时才评估“真正的”(且昂贵的)目标。否则立即返回一个高值。
在图中,虚线左侧的所有内容都违反了a2 <= 2*a1
。红十字是目标 f 的真实最小值,黑点是客观评价。由于该行左侧的目标值较高,因此搜索焦点位于搜索空间的有效部分。当然,在无效子空间中也可能存在评估(在初始随机采样期间或在“探索”而不是“利用”时),但这些不会涉及对昂贵目标的评估f
。
import numpy as np
from matplotlib import pyplot as plt
from skopt import gp_minimize
from skopt.space import Real
from skopt.utils import use_named_args
# search space
dimensions = [Real(name='a1', low=1, high=10),
Real(name='a2', low=1, high=10)]
# expensive target function to minimize
def f(a1, a2):
x1 = a1 - 4.5
x2 = a2 - 7
return 1.5*x1**2 + x2**2 - 0.9*x1*x2
# objective function passed to optimizer incorporates constraint
@use_named_args(dimensions)
def objective(a1, a2):
# if constraint violated quickly return a high value ...
if a2 > 2*a1:
return 1e4
# ... otherwise expensive target can be evaluated
else:
return f(a1, a2)
# run optimization
res = gp_minimize(objective, dimensions, n_calls=50, n_initial_points=20, random_state=92)
# evaluate f on regular grid for plotting
a1_grid = np.linspace(0, 10, 50)
a2_grid = np.linspace(0, 10, 50)
f_grid = np.array([f(i, j) for j in a2_grid for i in a1_grid]).reshape(
len(a1_grid), len(a2_grid))
# visualize results
fig, ax = plt.subplots()
ax.set_xlabel('a1')
ax.set_ylabel('a2')
# contours of f
ax.contourf(a1_grid, a2_grid, f_grid, 20)
# true minimum
ax.plot(4.5, 7, 'rx')
# constraint
ax.plot([0, 5], [0, 10], 'k--')
# evaluations
for x in res.x_iters:
ax.plot(x[0], x[1], 'k.')