目的関数同士の依存関係

多目的最適化において、複数の目的関数間の依存関係には主に 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)