Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WFG benchmark (optproblems) #219

Merged
merged 11 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions package/benchmarks/wfg/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Preferred Networks, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
83 changes: 83 additions & 0 deletions package/benchmarks/wfg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
author: Optuna team
title: The WFG Problem Collection
description: The WFG Problem Collection (Huband et al. 2006) is a widely-used benchmark suite for multi-objective optimization. This package is a wrapper of the optproblems library.
tags: [benchmark, continuous optimization, multi-objective, WFG, optproblems]
optuna_versions: [4.1.0]
license: MIT License
---

## Abstract

This package provides a wrapper of the [optproblems](https://www.simonwessing.de/optproblems/doc/index.html) library's WFG test suite, which consists of 9 kinds of continuous problems with variadic objectives and variables. For the details of the benchmark problems, please take a look at the original paper (Huband et al., 2006) in the reference section.

## APIs

### class `Problem(function_id: int, num_objectives: int, num_variables: int, k: int | None = None, **kwargs: Any)`

- `function_id`: Function ID of the WFG problem in \[1, 9\].
- `num_objectives`: Number of objectives.
- `num_variables`: Number of variables.
- `k`: Number of position parameters. It must hold k \< num_variables and k must be a multiple of num_objectives - 1. Huband et al. recommend k = 4 for two objectives and k = 2 * (m - 1) for m objectives. If `None` is set, this recommendation is used.
- `kwargs`: Arbitrary keyword arguments, please refer to [the optproblems documentation](https://www.simonwessing.de/optproblems/doc/wfg.html) for more details.

#### Methods and Properties

- `search_space`: Return the search space.
- Returns: `dict[str, optuna.distributions.BaseDistribution]`
- `directions`: Return the optimization directions.
- Returns: `list[optuna.study.StudyDirection]`
- `__call__(trial: optuna.Trial)`: Evaluate the objective function and return the objective value.
nabenabe0928 marked this conversation as resolved.
Show resolved Hide resolved
- Args:
- `trial`: Optuna trial object.
- Returns: `float`
- `evaluate(params: dict[str, float])`: Evaluate the objective function and return the objective value.
nabenabe0928 marked this conversation as resolved.
Show resolved Hide resolved
- Args:
- `params`: Decision variable like `{"x0": x1_value, "x1": x1_value, ..., "xn": xn_value}`. The number of parameters must be equal to `num_variables`.
- Returns: `float`

The properties defined by [optproblems](https://www.simonwessing.de/optproblems/doc/wfg.html) are also available such as `get_optimal_solutions`.

## Installation

Please install the [optproblems](https://pypi.org/project/optproblems/) package.

```shell
pip install -U optproblems
```

## Example

```python
import optuna
import optunahub


wfg = optunahub.load_module("benchmarks/wfg")
wfg4 = wfg.Problem(function_id=4, num_objectives=2, num_variables=3, k=1)

study_pareto = optuna.create_study(
study_name="ParetoFront", directions=wfg4.directions
)
for x in wfg4.get_optimal_solutions(1000): # Generate 1000 Pareto optimal solutions
study_pareto.enqueue_trial(params={
f"x{i}": x.phenome[i] for i in range(3)
})
study_pareto.optimize(wfg4, n_trials=1000)

study_tpe = optuna.create_study(
study_name="TPESampler",
sampler=optuna.samplers.TPESampler(seed=42), directions=wfg4.directions
)
study_tpe.optimize(wfg4, n_trials=1000)

optunahub.load_module("visualization/plot_pareto_front_multi").plot_pareto_front(
[study_pareto, study_tpe]
).show()
```

![Result](images/wfg4.png)

## Reference

Huband, S., Hingston, P., Barone, L., & While, L. (2006). [A review of multiobjective test problems and a scalable test problem toolkit](https://doi.org/10.1109/TEVC.2005.861417). IEEE Transactions on Evolutionary Computation, 10(5), 477-506.
4 changes: 4 additions & 0 deletions package/benchmarks/wfg/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from ._wfg import Problem


__all__ = ["Problem"]
71 changes: 71 additions & 0 deletions package/benchmarks/wfg/_wfg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from __future__ import annotations

from typing import Any

import optproblems.wfg
import optuna
import optunahub


class Problem(optunahub.benchmarks.BaseProblem):
"""Wrapper class for the WFG test suite of optproblems."""

def __init__(
self,
function_id: int,
num_objectives: int,
num_variables: int,
k: int | None = None,
**kwargs: Any,
) -> None:
"""Initialize the problem.
Args:
function_id: Function ID of the WFG problem in [1, 9].
num_objectives: Number of objectives.
num_variables: Number of variables.
k: Number of position parameters. It must hold k < num_variables and k must be a multiple of num_objectives - 1. Huband et al. recommend k = 4 for two objectives and k = 2 * (m - 1) for m objectives.
kwargs: Arbitrary keyword arguments, please refer to the optproblems documentation for more details.

Please refer to the optproblems documentation for the details of the available properties.
https://www.simonwessing.de/optproblems/doc/wfg.html
"""
assert 1 <= function_id <= 9, "function_id must be in [1, 9]"

if k is None:
k = 2 * (num_objectives - 1) if num_objectives > 2 else 4

self._problem = optproblems.wfg.WFG(num_objectives, num_variables, k, **kwargs)[
function_id - 1
]

self._search_space = {
f"x{i}": optuna.distributions.FloatDistribution(
self._problem.min_bounds[i], self._problem.max_bounds[i]
)
for i in range(num_variables)
}

@property
def search_space(self) -> dict[str, optuna.distributions.BaseDistribution]:
"""Return the search space."""
return self._search_space.copy()

@property
def directions(self) -> list[optuna.study.StudyDirection]:
"""Return the optimization directions."""
return [optuna.study.StudyDirection.MINIMIZE for _ in range(self._problem.num_objectives)]
y0z marked this conversation as resolved.
Show resolved Hide resolved

def evaluate(self, params: dict[str, float]) -> float:
"""Evaluate the objective function.
Args:
params:
Decision variable, e.g., evaluate({"x0": 1.0, "x1": 2.0}).
The number of parameters must be equal to the dimension of the problem.
Returns:
The objective value.

"""
return self._problem.objective_function([params[name] for name in self._search_space])

def __getattr__(self, name: str) -> Any:
return getattr(self._problem, name)
Binary file added package/benchmarks/wfg/images/wfg4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package/benchmarks/wfg/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
optproblems
Loading