File: get_archive.py

package info (click to toggle)
python-moarchiving 1.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 404 kB
  • sloc: python: 2,989; makefile: 6
file content (153 lines) | stat: -rw-r--r-- 8,303 bytes parent folder | download
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)