hypervolume#

moocore.hypervolume(data, /, ref, *, maximise=False)[source]#

Hypervolume indicator.

Compute the hypervolume metric with respect to a given reference point assuming minimization of all objectives.

See also

For details about the hypervolume, see Hypervolume metric.

Parameters:
  • data (ArrayLike) – Numpy array of numerical values, where each row gives the coordinates of a point. If the array is created from the read_datasets() function, remove the last column.

  • ref (ArrayLike) – Reference point as a 1D vector. Must be same length as a single point in the data.

  • maximise (bool | list[bool], default: False) – Whether the objectives must be maximised instead of minimised. Either a single boolean value that applies to all objectives or a list of booleans, with one value per objective. Also accepts a 1D numpy array with value 0/1 for each objective

Returns:

float – A single numerical value, the hypervolume indicator.

See also

Hypervolume

object-oriented interface.

RelativeHypervolume

Compute hypervolume relative to a reference set.

Notes

For 2D and 3D, the algorithms used [1][2] have \(O(n \log n)\) complexity, where \(n\) is the number of input points. The 3D case uses the HV3D+ algorithm [3], which has the same complexity as the HV3D algorithm [1][2], but it is faster in practice.

For 4D, the algorithm used is HV4D+ [3], which has \(O(n^2)\) complexity. Compared to the original implementation, this implementation correctly handles weakly dominated points and has been further optimized for speed.

For 5D or higher, it uses a recursive algorithm [1] with HV4D+ as the base case, resulting in a \(O(n^{d-2})\) time complexity and \(O(n)\) space complexity in the worst-case, where \(d\) is the dimension of the points. Experimental results show that the pruning techniques used may reduce the time complexity even further. The original proposal [1] had the HV3D algorithm as the base case, giving a time complexity of \(O(n^{d-2} \log n)\). Andreia P. Guerreiro enhanced the numerical stability of the recursive algorithm by avoiding floating-point comparisons of partial hypervolumes.

References

Examples

>>> dat = np.array([[5, 5], [4, 6], [2, 7], [7, 4]])
>>> moocore.hypervolume(dat, ref=[10, 10])
38.0

This function assumes that objectives must be minimized by default. We can easily specify maximization:

>>> dat = np.array([[5, 5], [4, 6], [2, 7], [7, 4]])
>>> moocore.hypervolume(dat, ref=0, maximise=True)
39.0

Merge all the sets of a dataset by removing the set number column:

>>> dat = moocore.get_dataset("input1.dat")[:, :-1]
>>> len(dat)
100

Dominated points are ignored, so this:

>>> moocore.hypervolume(dat, ref=[10, 10])
93.55331425585321

gives the same hypervolume as this:

>>> dat = moocore.filter_dominated(dat)
>>> len(dat)
6
>>> moocore.hypervolume(dat, ref=[10, 10])
93.55331425585321