Example Optim 2 Objectives 1D

"""Auto-generated example: Optimise 2 objective(s), 1D input."""

import math
import random

import bencher as bn

class ServerOptimizer(bn.ParametrizedSweep):
    """Optimizes server configuration for performance vs cost tradeoff."""

    cpu_cores = bn.FloatSweep(default=4, bounds=[1, 32], doc="Number of CPU cores")
    memory_gb = bn.FloatSweep(default=8, bounds=[1, 64], doc="Memory in GB")

    performance = bn.ResultFloat("score", bn.OptDir.maximize, doc="Performance score (maximize)")
    cost = bn.ResultFloat("$/hr", bn.OptDir.minimize, doc="Hourly cost (minimize)")

    noise_scale = bn.FloatSweep(default=0.0, bounds=[0.0, 1.0], doc="Noise scale")

    def benchmark(self):
        self.performance = math.log2(self.cpu_cores + 1) * math.sqrt(self.memory_gb) * 10
        self.cost = 0.05 * self.cpu_cores + 0.02 * self.memory_gb
        if self.noise_scale > 0:
            self.performance += random.gauss(0, self.noise_scale * 5)
            self.cost += random.gauss(0, self.noise_scale * 0.1)


def example_optim_2_objectives_1d(run_cfg: bn.BenchRunCfg | None = None) -> bn.Bench:
    """Optimise 2 objective(s), 1D input."""
    bench = ServerOptimizer().to_bench(run_cfg)
    bench.plot_sweep(input_vars=["cpu_cores"], result_vars=["performance", "cost"], const_vars=dict(noise_scale=0.1), description='Multi-objective optimization over 1D input space using Optuna. The optimizer finds the Pareto front trading off performance vs cost.', post_description='The Pareto front shows optimal trade-offs — no point can improve one objective without worsening the other.')

    return bench


if __name__ == "__main__":
    bn.run(example_optim_2_objectives_1d, subsampling_divisions=3, repeats=3, optimise=30)