目的関数同士の依存関係¶
多目的最適化において、複数の目的関数間の依存関係には主に 2 つの種類があります。
決定変数を介した依存関係 — 複数の目的関数が共通の決定変数を使用する
制約条件を介した依存関係 — 複数の目的関数の決定変数が、制約条件によって結びついている
これらは単独でも組み合わせても考慮できます。
決定変数を介した依存関係¶
最も基本的なケースです。g(x, y) と h(y, z) のように、複数の目的関数が変数 y を共有している場合が該当します。
from amplify_bbopt import blackbox, RealVariable
@blackbox
def bbfunc(
x: float = RealVariable((0, 1)),
y: float = RealVariable((0, 1)),
z: float = RealVariable((0, 1)),
) -> list[float]:
return [g(x, y), h(y, z)]
共有変数 y の値が変わると両方の目的関数値が変化します。この依存関係はブラックボックス関数の定義だけで表現でき、MultiOptimizer に追加の設定は不要です。
from amplify_bbopt import KMTrainer, MultiOptimizer
optimizer = MultiOptimizer(
blackbox=bbfunc,
trainer=[KMTrainer(), KMTrainer()],
client=my_client,
)
optimizer.add_random_training_data(num_data=10)
optimizer.optimize(10)
Optimizer を使う場合
from amplify_bbopt import blackbox, KMTrainer, Optimizer, RealVariable
w_g = 10
w_h = 2
@blackbox
def bbfunc(
x: float = RealVariable((0, 1)),
y: float = RealVariable((0, 1)),
z: float = RealVariable((0, 1)),
) -> float:
return w_g * g(x, y) + w_h * h(y, z)
optimizer = Optimizer(
blackbox=bbfunc,
trainer=KMTrainer(),
client=my_client,
)
optimizer.add_random_training_data(num_data=10)
optimizer.optimize(10)
制約条件を介した依存関係¶
g(x, y) と h(z) のように、各目的関数が参照する決定変数が重複していない場合でも、x + z ≤ 2 のような制約条件を課すことで、間接的な依存関係を持たせることができます。
from amplify_bbopt import blackbox, RealVariable
import amplify
@blackbox
def bbfunc(
x: float = RealVariable((0, 2)),
y: float = RealVariable((0, 1)),
z: float = RealVariable((0, 2)),
) -> list[float]:
return [g(x, y), h(z)]
# 決定変数オブジェクトを取り出して制約条件を定義
var = bbfunc.variables
constraint = amplify.less_equal(var.x + var.z, 2)
制約条件は MultiOptimizer のインスタンス化時に渡します。
from amplify_bbopt import KMTrainer, MultiOptimizer
optimizer = MultiOptimizer(
blackbox=bbfunc,
trainer=[KMTrainer(), KMTrainer()],
client=my_client,
constraints=constraint,
)
optimizer.add_random_training_data(num_data=10)
optimizer.optimize(10)
Note
制約条件の詳細な設定方法(ハード制約・ソフト制約)については、こちらを参照してください。
Optimizer を使う場合
from amplify_bbopt import blackbox, KMTrainer, Optimizer, RealVariable
import amplify
w_g = 10
w_h = 2
@blackbox
def bbfunc(
x: float = RealVariable((0, 2)),
y: float = RealVariable((0, 1)),
z: float = RealVariable((0, 2)),
) -> float:
return w_g * g(x, y) + w_h * h(z)
var = bbfunc.variables
constraint = amplify.less_equal(var.x + var.z, 2)
optimizer = Optimizer(
blackbox=bbfunc,
trainer=KMTrainer(),
client=my_client,
constraints=constraint,
)
optimizer.add_random_training_data(num_data=10)
optimizer.optimize(10)
その両方¶
決定変数による依存と制約条件による依存を同時に持つケースを扱うこともできます。例えば、g(x, y) と h(y, z) が変数 y を共有しつつ、さらに x + z ≤ 2 という制約条件もある場合です。
from amplify_bbopt import blackbox, RealVariable
import amplify
@blackbox
def bbfunc(
x: float = RealVariable((0, 2)),
y: float = RealVariable((0, 1)),
z: float = RealVariable((0, 2)),
) -> list[float]:
return [g(x, y), h(y, z)] # y を共有
var = bbfunc.variables
constraint = amplify.less_equal(var.x + var.z, 2) # かつ制約条件も考慮
optimizer = MultiOptimizer(
blackbox=bbfunc,
trainer=[KMTrainer(), KMTrainer()],
client=my_client,
constraints=constraint,
)
optimizer.add_random_training_data(num_data=10)
optimizer.optimize(10)
Optimizer を使う場合
from amplify_bbopt import blackbox, KMTrainer, Optimizer, RealVariable
import amplify
w_g = 10
w_h = 2
@blackbox
def bbfunc(
x: float = RealVariable((0, 2)),
y: float = RealVariable((0, 1)),
z: float = RealVariable((0, 2)),
) -> float:
return w_g * g(x, y) + w_h * h(y, z) # y を共有
var = bbfunc.variables
constraint = amplify.less_equal(var.x + var.z, 2) # かつ制約条件も考慮
optimizer = Optimizer(
blackbox=bbfunc,
trainer=KMTrainer(),
client=my_client,
constraints=constraint,
)
optimizer.add_random_training_data(num_data=10)
optimizer.optimize(10)