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")
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")
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), )
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")
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")
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
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")
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")
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")
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), )
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), )