Coverage for moptipy / api / mo_utils.py: 22%
27 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
1"""Utilities for multi-objective optimization."""
3import numba # type: ignore
4import numpy as np
7@numba.njit(cache=True)
8def dominates(a: np.ndarray, b: np.ndarray) -> int:
9 """
10 Check if one objective vector dominates or is dominated by another one.
12 :param a: the first objective vector
13 :param b: the second objective value
14 :returns: an integer value indicating the domination relationship
15 :retval -1: if `a` dominates `b`
16 :retval 1: if `b` dominates `a`
17 :retval 2: if `b` equals `a`
18 :retval 0: if `a` and `b` are mutually non-dominated, i.e., if neither `a`
19 dominates `b` not `b` dominates `a` and `b` is also different from `a`
21 >>> from numpy import array
22 >>> dominates(array([1, 1, 1]), array([2, 2, 2]))
23 -1
24 >>> dominates(array([1.0, 1.0, 2.0]), array([2.0, 2.0, 1.0]))
25 0
26 >>> dominates(array([2, 2, 2]), array([1, 1, 1]))
27 1
28 >>> dominates(array([2, 2, 2]), array([2, 2, 2]))
29 2
30 """
31 res: int = 0
32 for i, av in enumerate(a):
33 bv = b[i]
34 if av < bv:
35 if res == 0:
36 res = -1
37 elif res == 1:
38 return 0
39 elif bv < av:
40 if res == 0:
41 res = 1
42 elif res == -1:
43 return 0
44 return 2 if res == 0 else res
47@numba.njit(cache=True)
48def lexicographic(a: np.ndarray, b: np.ndarray) -> int:
49 """
50 Compare two arrays lexicographically.
52 :param a: the first objective vector
53 :param b: the second objective value
54 :returns: `-1` if `a` is lexicographically less than `b`, `1` if `b` is
55 less than `a`, `0` otherwise
56 :retval -1: if `a` is lexicographically less than `b`
57 :retval 1: if `b` is lexicographically less than `a`
58 :retval 2: if `b` equals `a`
60 >>> from numpy import array
61 >>> lexicographic(array([1, 1, 1]), array([2, 2, 2]))
62 -1
63 >>> lexicographic(array([1, 1, 1]), array([1, 1, 2]))
64 -1
65 >>> lexicographic(array([2, 2, 2]), array([1, 1, 1]))
66 1
67 >>> lexicographic(array([2, 2, 2]), array([2, 2, 1]))
68 1
69 >>> lexicographic(array([2, 2, 2]), array([2, 2, 2]))
70 0
71 """
72 for i, f in enumerate(a):
73 k = b[i]
74 if f < k:
75 return -1
76 if f > k:
77 return 1
78 return 0