class documentation

A list of objective values in an empirical Pareto front, meaning that no point strictly domminates another one in all objectives.

>>> from comocma.nondominatedarchive import NonDominatedList
>>> a = NonDominatedList([[1,0.9], [0,1], [0,2]], [2, 2])
Method __init__ elements of list_of_f_tuples not in the empirical front are pruned away reference_point is also used to compute the hypervolume, with the hv module of Simon Wessing.
Method add add f_tuple in self if it is not dominated in all objectives.
Method add_list add list of f_tuples, not using the add method to avoid calling self.prune() several times.
Method contributing_hypervolume Hypervolume improvement of f_tuple with respect to self. TODO: the argument should be an index, as in moarchiving.
Method distance_to_pareto_front Compute the distance of a dominated f_tuple to the empirical Pareto front.
Method dominates return True if any element of self dominates or is equal to f_tuple.
Method dominates_with return True if self[idx] dominates or is equal to f_tuple.
Method dominates_with_for returns true if self[idx] weakly dominates f_tuple
Method dominates_with_old deprecated code, now taken over by dominates_wit_for
Method dominators return the list of all f_tuple-dominating elements in self,
Method hypervolume_improvement return how much f_tuple would improve the hypervolume.
Method in_domain return True if f_tuple is dominating the reference point,
Method prune remove point dominated by another one in all objectives.
Method remove remove element f_pair.
Instance Variable reference_point Undocumented
Property hypervolume hypervolume of the entire list w.r.t. the "initial" reference point.
Property kink_points Create the 'kink' points from elements of self. If f_tuple is not None, also add the projections of f_tuple to the empirical front, with respect to the axes
Static Method _random_archive Undocumented
Static Method _random_archive_many Undocumented
Method _asserts make all kind of consistency assertions.
Method _projection Undocumented
Method _projection_to_empirical_front return the orthogonal projections of f_tuple on the empirical front, with respect to the coodinates axis.
Method _strictly_dominates return True if any element of self strictly dominates f_tuple.
Method _strictly_dominates_with return True if self[idx] strictly dominates f_tuple.
Instance Variable _hypervolume Undocumented
Instance Variable _kink_points Undocumented
def __init__(self, list_of_f_tuples=None, reference_point=None):

elements of list_of_f_tuples not in the empirical front are pruned away reference_point is also used to compute the hypervolume, with the hv module of Simon Wessing.

def add(self, f_tuple):

add f_tuple in self if it is not dominated in all objectives.

def add_list(self, list_of_f_tuples):

add list of f_tuples, not using the add method to avoid calling self.prune() several times.

def contributing_hypervolume(self, f_tuple):

Hypervolume improvement of f_tuple with respect to self. TODO: the argument should be an index, as in moarchiving.

def distance_to_pareto_front(self, f_tuple):

Compute the distance of a dominated f_tuple to the empirical Pareto front.

def dominates(self, f_tuple):

return True if any element of self dominates or is equal to f_tuple.

Otherwise return False.

>>> from comocma.nondominatedarchive import NonDominatedList as NDA
>>> a = NDA([[0.39, 0.075], [0.0087, 0.14]])
>>> a.dominates(a[0])  # is always True if `a` is not empty
True
>>> a.dominates([-1, 33]) or a.dominates([33, -1])
False
>>> a._asserts()
def dominates_with(self, idx, f_tuple):

return True if self[idx] dominates or is equal to f_tuple.

Otherwise return False or None if idx is out-of-range.

>>> from comocma.nondominatedarchive import NonDominatedList as NDA
>>> NDA().dominates_with(0, [1, 2]) is None  # empty NDA
True
Unknown Field: todo
add more doctests that actually test the functionality and not only whether the return value is correct if empty
def dominates_with_for(self, idx, f_tuple):

returns true if self[idx] weakly dominates f_tuple

replaces dominates_with_old because it turned out to run quicker

def dominates_with_old(self, idx, f_tuple):

deprecated code, now taken over by dominates_wit_for

def dominators(self, f_tuple, number_only=False):

return the list of all f_tuple-dominating elements in self,

including an equal element. len(....dominators(...)) is hence the number of dominating elements which can also be obtained without creating the list with number_only=True.

>>> from comocma.nondominatedarchive import NonDominatedList as NDA
>>> a = NDA([[1.2, 0.1], [0.5, 1]])
>>> len(a)
2
>>> a.dominators([2, 3]) == a
True
>>> a.dominators([0.5, 1])
[(0.5, 1)]
>>> len(a.dominators([0.6, 3])), a.dominators([0.6, 3], number_only=True)
(1, 1)
>>> a.dominators([0.5, 0.9])
[]
def hypervolume_improvement(self, f_tuple):

return how much f_tuple would improve the hypervolume.

If dominated, return the distance to the empirical pareto front multiplied by -1. Else if not in domain, return distance to the reference point dominating area times -1.

def in_domain(self, f_tuple, reference_point=None):

return True if f_tuple is dominating the reference point,

False otherwise. True means that f_tuple contributes to the hypervolume if not dominated by other elements.

f_tuple may also be an index in self in which case self[f_tuple] is tested to be in-domain.

>>> from comocma.nondominatedarchive import NonDominatedList as NDA
>>> a = NDA([[2.2, 0.1], [0.5, 1]], reference_point=[2, 2])
>>> assert len(a) == 1
>>> a.in_domain([0, 0])
True
>>> a.in_domain([2, 1])
False
>>> all(a.in_domain(ai) for ai in a)
True
>>> a.in_domain(0)
True

TODO: improve name?

def prune(self, prune_domain=False):

remove point dominated by another one in all objectives.

def remove(self, f_tuple):

remove element f_pair.

Raises a ValueError (like list) if f_pair is not in self. To avoid the error, checking if f_pair is in self first is a possible coding solution, like

>>> from moarchiving import BiobjectiveNondominatedSortedList
>>> nda = BiobjectiveNondominatedSortedList([[2, 3]])
>>> f_pair = [1, 2]
>>> assert [2, 3] in nda and f_pair not in nda
>>> if f_pair in nda:
...     nda.remove(f_pair)
>>> nda = BiobjectiveNondominatedSortedList._random_archive(p_ref_point=1)
>>> for pair in list(nda):
...     len_ = len(nda)
...     state = nda._state()
...     nda.remove(pair)
...     assert len(nda) == len_ - 1
...     if 100 * pair[0] - int(100 * pair[0]) < 0.7:
...         res = nda.add(pair)
...         assert all(state[i] == nda._state()[i] for i in [0, 2, 3])

Return None (like list.remove).

reference_point =

Undocumented

@property
hypervolume =

hypervolume of the entire list w.r.t. the "initial" reference point.

Raise ValueError when no reference point was given initially.

>>> from comocma.nondominatedarchive import NonDominatedList as NDA
>>> a = NDA([[0.5, 0.4], [0.3, 0.7]], [2, 2.1])
>>> a._asserts()
>>> a.reference_point == [2, 2.1]
True
>>> a._asserts()
@property
kink_points =

Create the 'kink' points from elements of self. If f_tuple is not None, also add the projections of f_tuple to the empirical front, with respect to the axes

@staticmethod
def _random_archive(max_size=500, p_ref_point=0.5):

Undocumented

@staticmethod
def _random_archive_many(k, max_size=500, p_ref_point=0.5):

Undocumented

def _asserts(self):

make all kind of consistency assertions.

>>> from comocma import nondominatedarchive
>>> a = nondominatedarchive.NonDominatedList(
...    [[-0.749, -1.188], [-0.557, 1.1076],
...    [0.2454, 0.4724], [-1.146, -0.110]], [10, 10])
>>> a._asserts()
>>> for p in list(a):
...     a.remove(p)
>>> assert len(a) == 0
>>> try: a.remove([0, 0])
... except ValueError: pass
... else: raise AssertionError("remove did not raise ValueError")
>>> from numpy.random import rand
>>> for _ in range(120):
...     a = nondominatedarchive.NonDominatedList._random_archive()
...     if a.reference_point:
...         for f_tuple in rand(10, 2):
...             h0 = a.hypervolume
...             hi = a.hypervolume_improvement(list(f_tuple))
...             assert a.hypervolume == h0  # works OK with Fraction
>>> for _ in range(10):
...     for k in range(3,10):
...         a = nondominatedarchive.NonDominatedList._random_archive_many(k)
...         if a.reference_point:
...             for f_tuple in rand(10, k):
...                 h0 = a.contributing_hypervolume(list(f_tuple))
...                 hi = a.hypervolume_improvement(list(f_tuple))
...                 assert h0 >= 0
...                 assert h0 == hi or (h0 == 0 and hi < 0)
def _projection(self, f_tuple, i, x):

Undocumented

def _projection_to_empirical_front(self, f_tuple):

return the orthogonal projections of f_tuple on the empirical front, with respect to the coodinates axis.

def _strictly_dominates(self, f_tuple):

return True if any element of self strictly dominates f_tuple.

Otherwise return False.

>>> from comocma.nondominatedarchive import NonDominatedList as NDA
>>> a = NDA([[0.39, 0.075], [0.0087, 0.14]])
>>> a.dominates(a[0])  # is always True if `a` is not empty
True
>>> a.dominates([-1, 33]) or a.dominates([33, -1])
False
>>> a._asserts()
def _strictly_dominates_with(self, idx, f_tuple):

return True if self[idx] strictly dominates f_tuple.

Otherwise return False or None if idx is out-of-range.

>>> from comocma.nondominatedarchive import NonDominatedList as NDA
>>> NDA()._strictly_dominates_with(0, [1, 2]) is None  # empty NDA
True
_hypervolume =

Undocumented

_kink_points =

Undocumented