Esempio n. 1
0
 def test_shuffled(self) -> None:
     """Test the ranks of the shuffled points are the same."""
     points = self._rng.normal(size=(151, 2))
     ranks, max_rank = non_dominated_sort(points)
     shuffled_idx = np.arange(151, dtype=int)
     self._rng.shuffle(shuffled_idx)
     ranks_shuffled, max_rank_shuffled = non_dominated_sort(
         points[shuffled_idx])
     self.assertTrue(max_rank == max_rank_shuffled, "Max. rank")
     self.assertTrue(np.all(ranks[shuffled_idx] == ranks_shuffled), "Ranks")
Esempio n. 2
0
 def test_max_rank_parameter(self) -> None:
     """Test the function with the max rank parameter."""
     points = self._rng.normal(size=(151, 2))
     ranks_nomax, _ = non_dominated_sort(points)
     ranks_max, max_rank = non_dominated_sort(points, 2)
     self.assertTrue(max_rank == 2, "Max. rank")
     idx1 = ranks_nomax == 1
     idx2 = ranks_nomax == 2
     self.assertTrue(np.all(ranks_nomax[idx1] == ranks_max[idx1]), "Rank 1")
     self.assertTrue(np.all(ranks_nomax[idx2] == ranks_max[idx2]), "Rank 2")
Esempio n. 3
0
 def test_example2(self):
     """Test a constructed 2D example"""
     # A set of non-dominated points
     # A line with negative slope
     points = np.array(
         [
             [0.0, 0.0],
             [1.0, -1.0],
             [2.0, -2.0],
             [3.0, -3.0],
             [4.0, -4.0],
             [5.0, -5.0],
             [6.0, -6.0],
             [7.0, -7.0],
             [8.0, -8.0],
             [9.0, -9.0],
         ]
     )
     expected = np.array(
         [True, False, True, False, True, False, True, False, False, True],
         dtype=bool,
     )
     ranks, _ = non_dominated_sort(points)
     selected = selection(points, ranks, len(points) - 5)
     self.assertTrue(
         np.all(selected == expected),
         "got: {}, expected: {}".format(selected, expected),
     )
Esempio n. 4
0
 def test_all_ranks_equal(self) -> None:
     """Test that all ranks are equal."""
     # Create a line with negative unitary slope
     # Values increase monotonically in the x dimension
     # and decrease monotonically in the y dimension
     # So no point dominates another
     size = 10
     points = get_objective_points(np.arange(0, size), line(-1, 0))
     ranks, max_rank = non_dominated_sort(points)
     self.assertTrue(np.all(ranks == np.repeat(1, size)), "Ranks")
     self.assertTrue(max_rank == 1, "Max. rank")
Esempio n. 5
0
 def test_all_ranks_different(self) -> None:
     """Test that all ranks are different."""
     # Create a line with positive unitary slope
     # Each point to the right in the x dimension
     # is dominated by all points to the left
     size = 10
     points = get_objective_points(np.arange(0, size), line(1, 0))
     ranks, max_rank = non_dominated_sort(points)
     self.assertTrue(np.all(ranks == np.arange(1, size + 1, dtype=int)),
                     "Ranks")
     self.assertTrue(max_rank == 10, "Max. rank")
Esempio n. 6
0
def indicator_selection(indicator: Indicator, points: np.ndarray,
                        target_size: int) -> Tuple[np.ndarray, np.ndarray]:
    """Perform selection using a quality indicator.

    Parameters
    ----------
    indicator
        The indicator.
    points
        The objective points.
    target_size
        The number of objective points to select.

    Returns
    -------
    Tuple[np.ndarray]
        A flag array indicating the selected points and the ranks array.

    Notes
    -----
    Based on the `IndicatorBasedSelection` class from :cite:`2008:shark`.
    """
    selected = np.zeros(len(points), dtype=bool)
    ranks, _ = non_dominated_sort(points)

    n_pending_select = target_size
    rank = 1
    while n_pending_select > 0:
        front = ranks == rank
        n_front = np.sum(front)
        diff = n_pending_select - n_front
        if diff > 0:
            # We must select all individuals in the current front.
            selected[front] = True
            n_pending_select = diff
            rank += 1
        elif diff == 0:
            # All pending individuals are exactly in this front.
            selected[front] = True
            n_pending_select = 0
        else:
            # We select the rest of pending individuals among individuals
            # in the current front by discarding the least contributors.
            # See also Lemma 1 in page 11 of [2007:mo-cma-es].
            idx = np.arange(len(ranks))[front]
            least_contributors = indicator.least_contributors(
                points[front],
                -diff,
            )
            selected[front] = True
            selected[idx[least_contributors]] = False
            n_pending_select = 0

    return selected, ranks
Esempio n. 7
0
 def test_dominated_points_ref_1(self) -> None:
     """Test input data with dominated points and reference."""
     # Random points generated using one of the utility
     # functions (random_2d_3d_front).
     points = np.array([
         [1.07525383, 9.9420234],
         [9.0063025, 4.34586186],
         [1.07525383, 9.9520234],
         [5.21288155, 8.53380723],
         [4.56317607, 8.90816971],
         [8.01491032, 5.98006794],
         [3.24097153, 9.46023803],
         [8.02491032, 5.98006794],
         [4.56317607, 8.89816971],
         [8.09812306, 5.8668904],
         [9.47977929, 3.18336057],
         [8.15916972, 5.78169088],
         [9.93329032, 1.15314504],
     ])
     ranks, _ = non_dominated_sort(points)
     nadir = np.array([10.0, 10.0])
     # The contributions were generated using the reference implementation
     # by A.P. Guerreiro, available at (https://github.com/apguerreiro/HVC).
     # For example: ```./hvc -P 1 -f 0 -r "10. 10. 1" | sort```
     # In the 2-D case, the z-component of the points is set to zero
     # and the z-component of the reference point is set to one.
     sorted_contribs = np.array([
         0.00690911080401627,
         0.0721753062322654,
         0.12556094880582,
         0.135435028337332,
         0.212503643566556,
         0.365178867638393,
         0.527207157404229,
         0.637018803519581,
         0.679831715378445,
         1.02095415166855,
     ])
     parameters = UPMOParameters(points.shape[1], 1.0)
     archive = UPMOArchive(parameters, nadir)
     for point in points:
         archive.insert(point, point)
     self.assertTrue(archive.size == np.sum(ranks == 1), "Size")
     output_contribs = np.array(
         sorted(map(lambda individual: individual.contribution, archive)))
     self.assertTrue(np.allclose(sorted_contribs, output_contribs),
                     "Contributions")
Esempio n. 8
0
 def test_curve_and_line(self) -> None:
     """Test the ranks of points created with a curve and a line."""
     # Sort the points wrt x dimension
     # The first and last point have the minimum and maximum ranks
     # Every next two points have the same rank
     start = 5
     end = 20
     true_max_rank = end - start + 1
     points = get_objective_points(np.arange(start, end), curve(1, 0),
                                   line(1, 0))
     sorted_points = np.array(sorted(points, key=lambda x: (x[0], x[1])))
     ranks, max_rank = non_dominated_sort(sorted_points)
     self.assertTrue(ranks[0] == 1, "First rank")
     self.assertTrue(ranks[-1] == true_max_rank, "Last rank")
     self.assertTrue(max_rank == true_max_rank, "Max. rank")
     for i in range(1, end - start, 2):
         self.assertTrue(ranks[i - 1] + 1 == ranks[i], "Prev. rank")
         self.assertTrue(ranks[i] == ranks[i + 1], "Peer rank")
         self.assertTrue(ranks[i] + 1 == ranks[i + 2], "Next rank")
Esempio n. 9
0
 def test_three_translated_lines(self) -> None:
     """Test ranks of three lines with same slope but different bias"""
     # Create three lines with the same slope but different bias
     # Sort the points wrt the x dimension
     # The rank of the first point is 1 and the last is size * 2 + 1
     size = 5
     true_max_rank = size * 2 + 1
     points = get_objective_points(np.arange(0, size), line(1, 2),
                                   line(1, 3), line(1, 4))
     sorted_points = np.array(sorted(points, key=lambda x: (x[0], x[1])))
     ranks, max_rank = non_dominated_sort(sorted_points)
     self.assertTrue(ranks[0] == 1, "First rank")
     self.assertTrue(ranks[-1] == true_max_rank, "Last rank")
     self.assertTrue(max_rank == true_max_rank, "Max. rank")
     for i in range(0, size * 3, 3):
         self.assertTrue(ranks[i] + 1 == ranks[i + 1], "Next point")
         self.assertTrue(ranks[i] + 2 == ranks[i + 2], "Second next point")
         if i > 0:
             self.assertTrue(ranks[i] == ranks[i - 1], "Previous point")
Esempio n. 10
0
 def test_example3(self):
     """Test an example in which the first front has size one."""
     points = np.array(
         [
             [0.67996405, 0.29296719],
             [0.16359694, 0.67606755],
             [0.18515826, 0.91830604],
             [0.09758624, 0.21536309],
             [0.58368728, 0.52277089],
             [0.74548241, 0.51495986],
         ]
     )
     ranks, _ = non_dominated_sort(points)
     selected = selection(points, ranks, 3)
     expected = np.array([True, True, False, True, False, False])
     self.assertTrue(
         np.all(selected == expected),
         "got: {}, expected: {}".format(selected, expected),
     )
Esempio n. 11
0
 def test_example1(self):
     """Test a constructed 2D example"""
     # A set of non-dominated points
     points = np.array(
         [
             [0.01245897, 0.27127751],
             [0.02213313, 0.23395707],
             [0.0233907, 0.22994154],
             [0.0392689, 0.1886141],
             [0.04339422, 0.17990426],
             [0.16521067, 0.05107939],
             [0.17855283, 0.0440614],
             [0.28619405, 0.00950565],
         ]
     )
     expected = np.array(
         [True, False, False, False, False, True, False, True], dtype=bool
     )
     ranks, _ = non_dominated_sort(points)
     selected = selection(points, ranks, len(points) - 5)
     self.assertTrue(
         np.all(selected == expected),
         "got: {}, expected: {}".format(selected, expected),
     )