1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
"""Convenience create functions for any of the nondominated archives.
The appropriate number of objectives, is derived from the input arguments.
"""
from moarchiving.moarchiving import BiobjectiveNondominatedSortedList as MOArchive2obj
from moarchiving.moarchiving3obj import MOArchive3obj
from moarchiving.moarchiving4obj import MOArchive4obj
from moarchiving.constrained_moarchive import CMOArchive
import warnings as _warnings
try:
import fractions
except ImportError:
_warnings.warn('`fractions` module not installed, arbitrary precision hypervolume computation not available')
def get_mo_archive(list_of_f_vals=None, reference_point=None, infos=None, n_obj=None):
"""Return a nondominated archive instance with the proper number of objectives.
`list_of_f_vals` is a list of objective vectors with `n_obj`
objectives. If `list_of_f_vals` is not provided, `n_obj` can be
provided to define the number of objectives which is by default 2.
`reference_point` is used for hypervolume computation and pruning of
the archive. A list of additional information for each objective
vector, for example the solution from which the objective values were
computed, can be provided in `infos`.
"""
if not hasattr(get_mo_archive, "hypervolume_final_float_type"):
try:
get_mo_archive.hypervolume_final_float_type = fractions.Fraction
except:
get_mo_archive.hypervolume_final_float_type = float
if not hasattr(get_mo_archive, "hypervolume_computation_float_type"):
try:
get_mo_archive.hypervolume_computation_float_type = fractions.Fraction
except:
get_mo_archive.hypervolume_computation_float_type = float
if (list_of_f_vals is None or len(list_of_f_vals) == 0) and n_obj is None and reference_point is None:
n_obj = 2
if n_obj is None:
if list_of_f_vals is not None and len(list_of_f_vals) > 0:
n_obj = len(list_of_f_vals[0])
else:
n_obj = len(reference_point)
# check if the number of objectives matches the number of objectives in the list of f_vals
# and the reference point if they are provided and not empty
if list_of_f_vals is not None and len(list_of_f_vals) > 0 and reference_point is not None:
if len(reference_point) != len(list_of_f_vals[0]):
raise ValueError(f"n_obj ({len(reference_point)}) does not match the number of "
f"objectives in the first element of list_of_f_vals "
f"({len(list_of_f_vals[0])})")
elif n_obj != len(list_of_f_vals[0]):
_warnings.warn(f"n_obj ({n_obj}) does not match the number of objectives in "
f"list_of_f_vals ({len(list_of_f_vals[0])})")
n_obj = len(list_of_f_vals[0])
elif list_of_f_vals is not None and len(list_of_f_vals) > 0:
if n_obj != len(list_of_f_vals[0]):
_warnings.warn(f"n_obj ({n_obj}) does not match the number of objectives in "
f"list_of_f_vals ({len(list_of_f_vals[0])})")
n_obj = len(list_of_f_vals[0])
elif reference_point is not None:
if n_obj != len(reference_point):
_warnings.warn(f"n_obj ({n_obj}) does not match the number of objectives in "
f"reference_point ({len(reference_point)})")
n_obj = len(reference_point)
if n_obj == 2:
return MOArchive2obj(list_of_f_vals, reference_point=reference_point, infos=infos,
hypervolume_final_float_type=get_mo_archive.hypervolume_final_float_type,
hypervolume_computation_float_type=get_mo_archive.hypervolume_computation_float_type)
elif n_obj == 3:
return MOArchive3obj(list_of_f_vals, reference_point=reference_point, infos=infos,
hypervolume_final_float_type=get_mo_archive.hypervolume_final_float_type,
hypervolume_computation_float_type=get_mo_archive.hypervolume_computation_float_type)
elif n_obj == 4:
return MOArchive4obj(list_of_f_vals, reference_point=reference_point, infos=infos,
hypervolume_final_float_type=get_mo_archive.hypervolume_final_float_type,
hypervolume_computation_float_type=get_mo_archive.hypervolume_computation_float_type)
else:
raise ValueError(f"Unsupported number of objectives: {n_obj}")
def get_cmo_archive(list_of_f_vals=None, list_of_g_vals=None, reference_point=None,
infos=None, n_obj=None, tau=1):
"""Return a constrained nondominated archive instance with the proper number of objectives.
`list_of_f_vals` is a list of objective vectors with `n_obj` objectives,
`list_of_g_vals` is a list of constraint violation vectors (or values).
If `list_of_f_vals` is not provided, `n_obj` can be provided to define
the number of objectives.
`reference_point` is used for the hypervolume computation and pruning of the archive.
A list of additional information for each objective vector can be provided in `infos`.
"""
if not hasattr(get_cmo_archive, "hypervolume_final_float_type"):
try:
get_cmo_archive.hypervolume_final_float_type = fractions.Fraction
except:
get_cmo_archive.hypervolume_final_float_type = float
if not hasattr(get_cmo_archive, "hypervolume_computation_float_type"):
try:
get_cmo_archive.hypervolume_computation_float_type = fractions.Fraction
except:
get_cmo_archive.hypervolume_computation_float_type = float
if (list_of_f_vals is None or len(list_of_f_vals) == 0) and n_obj is None and reference_point is None:
n_obj = 2
if n_obj is None:
if list_of_f_vals is not None and len(list_of_f_vals) > 0:
n_obj = len(list_of_f_vals[0])
else:
n_obj = len(reference_point)
# check if the number of objectives matches the number of objectives in the list of f_vals
# and the reference point if they are provided and not empty
if list_of_f_vals is not None and len(list_of_f_vals) > 0 and reference_point is not None:
if len(reference_point) != len(list_of_f_vals[0]):
raise ValueError(f"n_obj ({len(reference_point)}) does not match the number of "
f"objectives in the first element of list_of_f_vals "
f"({len(list_of_f_vals[0])})")
elif n_obj != len(list_of_f_vals[0]):
_warnings.warn(f"n_obj ({n_obj}) does not match the number of objectives in "
f"list_of_f_vals ({len(list_of_f_vals[0])})")
n_obj = len(list_of_f_vals[0])
elif list_of_f_vals is not None and len(list_of_f_vals) > 0:
if n_obj != len(list_of_f_vals[0]):
_warnings.warn(f"n_obj ({n_obj}) does not match the number of objectives in "
f"list_of_f_vals ({len(list_of_f_vals[0])})")
n_obj = len(list_of_f_vals[0])
elif reference_point is not None:
if n_obj != len(reference_point):
_warnings.warn(f"n_obj ({n_obj}) does not match the number of objectives in "
f"reference_point ({len(reference_point)})")
n_obj = len(reference_point)
if list_of_f_vals is None and list_of_g_vals is not None:
raise ValueError("list_of_f_vals must be provided if list_of_g_vals is provided")
if list_of_f_vals is not None and list_of_g_vals is None:
raise ValueError("list_of_g_vals must be provided if list_of_f_vals is provided")
if list_of_f_vals is not None and list_of_g_vals is not None and len(list_of_f_vals) != len(list_of_g_vals):
raise ValueError("list_of_f_vals and list_of_g_vals must have the same length")
return CMOArchive(list_of_f_vals=list_of_f_vals, list_of_g_vals=list_of_g_vals,
reference_point=reference_point, infos=infos, n_obj=n_obj, tau=tau,
hypervolume_final_float_type=get_cmo_archive.hypervolume_final_float_type,
hypervolume_computation_float_type=get_cmo_archive.hypervolume_computation_float_type)
|