comocma.nondominatedarchive.NonDominatedList(list)
class documentationcomocma.nondominatedarchive
(View In Hierarchy)
A list of objective values in an empirical Pareto front, meaning that no point strictly domminates another one in all objectives.
>>> from 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 | remove | remove element f_pair . |
Method | add_list | add list of f_tuples, not using the add method to avoid calling self.prune() several times. |
Method | prune | remove point dominated by another one in all objectives. |
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_old | deprecated code, now taken over by dominates_wit_for |
Method | dominates_with_for | returns true if self[idx] weakly dominates f_tuple |
Method | dominators | return the list of all f_tuple -dominating elements in self , |
Method | in_domain | return True if f_tuple is dominating the reference point, |
Method | 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 |
Method | hypervolume | hypervolume of the entire list w.r.t. the "initial" reference point. |
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 | hypervolume_improvement | return how much f_tuple would improve the hypervolume. |
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 . |
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. |
Static Method | _random_archive | Undocumented |
Static Method | _random_archive_many | Undocumented |
Method | _asserts | make all kind of consistency assertions. |
reference_point
is also used to compute the hypervolume, with the hv
module of Simon Wessing.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
).
return True
if any element of self
dominates or is equal to f_tuple
.
Otherwise return False
.
>>> from 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()
return True
if self[idx] dominates or is equal to f_tuple
.
Otherwise return False
or None
if idx
is out-of-range.
>>> from 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 |
returns true if self[idx] weakly dominates f_tuple
replaces dominates_with_old because it turned out to run quicker
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 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]) []
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 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?
return True
if any element of self
strictly dominates f_tuple
.
Otherwise return False
.
>>> from 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()
hypervolume of the entire list w.r.t. the "initial" reference point.
Raise ValueError
when no reference point was given initially.
>>> from 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()
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.
make all kind of consistency assertions.
>>> 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)