Single-Objective with Constraints

In this tutorial, we will introduce how to optimize a constrained problem with OpenBox.

Problem Setup

First, define search space and define objective function to minimize. Here we use the constrained Mishra function.

import numpy as np
from openbox import space as sp

def mishra(config: sp.Configuration):
    X = np.array([config['x%d' % i] for i in range(2)])
    x, y = X[0], X[1]
    t1 = np.sin(y) * np.exp((1 - np.cos(x))**2)
    t2 = np.cos(x) * np.exp((1 - np.sin(y))**2)
    t3 = (x - y)**2

    result = dict()
    result['objectives'] = [t1 + t2 + t3, ]
    result['constraints'] = [np.sum((X + 5)**2) - 25, ]
    return result

params = {
    'float': {
        'x0': (-10, 0, -5),
        'x1': (-6.5, 0, -3.25)
    }
}
space = sp.Space()
space.add_variables([
    sp.Real(name, *para) for name, para in params['float'].items()
])

After evaluation, the objective function returns a dict (Recommended). The result dictionary should contain:

  • 'objectives': A list/tuple of objective values (to be minimized). In this example, we have only one objective so the tuple contains a single value.

  • 'constraints': A list/tuple of constraint values. Non-positive constraint values (“<=0”) imply feasibility.

Optimization

After defining the search space and the objective function, we can run the optimization process as follows:

from openbox import Optimizer

opt = Optimizer(
    mishra,
    space,
    num_constraints=1,
    num_objectives=1,
    surrogate_type='gp',                # try using 'auto'!
    acq_optimizer_type='random_scipy',  # try using 'auto'!
    max_runs=50,
    task_id='soc',
    # Have a try on the new HTML visualization feature!
    # visualization='advanced',   # or 'basic'. For 'advanced', run 'pip install "openbox[extra]"' first
    # auto_open_html=True,        # open the visualization page in your browser automatically
)
history = opt.run()

Here we create a Optimizer instance, and pass the objective function and the search space to it. The other parameters are:

  • num_objectives=1 and num_constraints=1 indicate that our function returns a single value with one constraint.

  • max_runs=50 means the optimization will take 50 rounds (optimizing the objective function 50 times).

  • task_id is set to identify the optimization process.

  • visualization: 'none', 'basic' or 'advanced'. See HTML Visualization.

  • auto_open_html: whether to open the visualization page in your browser automatically. See HTML Visualization.

Then, opt.run() is called to start the optimization process.

Visualization

After the optimization, opt.run() returns the optimization history. Or you can call opt.get_history() to get the history. Then, call print(history) to see the result:

history = opt.get_history()
print(history)
+-------------------------+---------------------+
| Parameters              | Optimal Value       |
+-------------------------+---------------------+
| x0                      | -3.172421           |
| x1                      | -1.506397           |
+-------------------------+---------------------+
| Optimal Objective Value | -105.72769850551406 |
+-------------------------+---------------------+
| Num Configs             | 50                  |
+-------------------------+---------------------+

Call history.plot_convergence() to visualize the optimization process:

import matplotlib.pyplot as plt
history.plot_convergence(true_minimum=-106.7645367)
plt.show()
../_images/plot_convergence_mishra.png

(New Feature!) Call history.visualize_html() to visualize the optimization process in an HTML page. For show_importance and verify_surrogate, run pip install "openbox[extra]" first. See HTML Visualization for more details.

history.visualize_html(open_html=True, show_importance=True,
                       verify_surrogate=True, optimizer=opt)
../_images/html_example_soc.jpg