Global minimization of a non-expensive scalar function
- Driver:
- Download script:
The target of the study is to minimize a scalar function. The scalar function is assumed to be inexpensive to evaluate (i.e. evaluation time shorter than a second) and to have no known derivatives. In this case a heuristic global optimization is advisable. Differential evolution (DE) is an evolutionary optimization algorithm inspired by the mutation, crossover and selection processes occurring in nature.
As an example, the 2D Rastrigin function on a circular domain is minimized,
\[ \begin{align}\begin{aligned}&\text{min.}\,& f(x_1,x_2) = 2\cdot10 + \sum_{i=1,2} \left(x_i^2 - 10\cos(2\pi x_i)\right)\\&\text{s.t.}\,& \sqrt{x_1^2 + x_2^2} \leq 1.5.\end{aligned}\end{align} \]
1import sys,os
2import numpy as np
3import time
4
5jcm_optimizer_path = r"<JCM_OPTIMIZER_PATH>"
6sys.path.insert(0, os.path.join(jcm_optimizer_path, "interface", "python"))
7from jcmoptimizer import Server, Client, Study, Observation
8server = Server()
9client = Client(server.host)
10
11# Definition of the search domain
12design_space = [
13 {'name': 'x1', 'type': 'continuous', 'domain': (-1.5,1.5)},
14 {'name': 'x2', 'type': 'continuous', 'domain': (-1.5,1.5)},
15]
16
17# Definition of fixed environment parameter
18environment = [
19 {'name': 'radius', 'type': 'fixed', 'domain': 1.5},
20]
21
22# Definition of a constraint on the search domain
23constraints = [
24 {'name': 'circle', 'expression': 'sqrt(x1^2 + x2^2) <= radius'}
25]
26
27# Creation of the study object with study_id 'differential_evolution'
28study = client.create_study(
29 design_space=design_space,
30 environment=environment,
31 constraints=constraints,
32 driver="DifferentialEvolution",
33 name="Global minimization of a non-expensive scalar function",
34 study_id="differential_evolution"
35)
36
37# Configure study parameters
38study.configure(max_iter=80, num_parallel=2)
39
40# Evaluation of the black-box function for specified design parameters
41def evaluate(study: Study, x1: float, x2: float, radius: float) -> Observation:
42
43 observation = study.new_observation()
44 observation.add(10*2
45 + (x1**2-10*np.cos(2*np.pi*x1))
46 + (x2**2-10*np.cos(2*np.pi*x2))
47 )
48 return observation
49
50# Run the minimization
51study.set_evaluator(evaluate)
52study.run()
53best = study.driver.best_sample
54print(f"Best sample at: x1={best['x1']:.3f}, x2={best['x2']:.3f}")