Tutorial 1: introduction to BenchmarkFunction classο
Benchmark functions are essential for testing optimization algorithms. In this tutorial, youβll learn how to use the BenchmarkFunction class, which provides a structured way to define and evaluate benchmark functions for optimization purposes.
The BenchmarkFunction class allows you to:
Define a (multidimensional) function;
Specify bounds along each dimension;
Evaluate the function at specific points;
Retrieve the optimal value of the function.
As an example, we will consider the Rastringin function, which is a popular benchmark for optimization algorithms. It is known to be a multimodal function with many local minima, defined as follows:
where \(x_i \in [-5.12, 5.12]\) and \(D\) is the dimension of the problem.
It has global minimum at \(f(\mathbf{x}^*) = 0\) for \(\mathbf{x}^* = (0, 0, \ldots, 0)\).
A general BenchmarkFunction object should be initialized with:
A name for the function (optional);
The function itself (as a callable object);
The bounds for each variable (as a NumPy-array);
The optimal solution (as a NumPy-array).
Letβs see how we can define the Rastringin function for \(D=5\).
[2]:
import numpy as np
from beeoptimal.benchmarks import BenchmarkFunction
[3]:
D = 5
name = f"Rastringin-{D}d"
function = lambda x: (10*len(x) + np.sum((x**2 - 10*np.cos(2*np.pi*x))))
bounds = np.array([[-5.12, 5.12]]*D)
optimal_solution = np.zeros(D)
[4]:
Rastringin2dBenchmark = BenchmarkFunction(
name = name,
fun = function,
bounds = bounds,
optimal_solution = optimal_solution
)
[5]:
print(f"\nBenchmark:\n {Rastringin2dBenchmark.name}")
print(f"\nDefault Bounds:\n {Rastringin2dBenchmark.bounds}")
print(f"\nOptimal Solution:\n {Rastringin2dBenchmark.optimal_solution}")
print(f"\nOptimal Value:\n {Rastringin2dBenchmark.optimal_value}")
Benchmark:
Rastringin-5d
Default Bounds:
[[-5.12 5.12]
[-5.12 5.12]
[-5.12 5.12]
[-5.12 5.12]
[-5.12 5.12]]
Optimal Solution:
[0. 0. 0. 0. 0.]
Optimal Value:
0.0
Given a new point \(\mathbf{x} \in \mathbb{R}^{5}\), the function can be evaluated as follows:
[6]:
x = np.random.uniform(low=Rastringin2dBenchmark.bounds[:,0], high=Rastringin2dBenchmark.bounds[:,1], size=D)
f_x = Rastringin2dBenchmark.evaluate(x)
print(f"{Rastringin2dBenchmark.name} function evaluated at point x={x} --> f(x)={f_x}")
Rastringin-5d function evaluated at point x=[ 0.10538191 -4.49508415 -3.52525349 5.09557108 3.70357909] --> f(x)=128.9333795057978