def test_should_add_work_properly_case7(self): """ Case 7: add a non-dominated solution when the archive is full should remove all the dominated solutions. """ archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] solution2 = Solution(2, 2) solution2.objectives = [1.0, 2.0] solution3 = Solution(2, 2) solution3.objectives = [2.0, 1.5] solution4 = Solution(2, 2) solution4.objectives = [3.0, 0.0] new_solution = Solution(2, 2) new_solution.objectives = [-1.0, -1.0] archive.add(solution1) archive.add(solution2) archive.add(solution3) archive.add(solution4) archive.add(new_solution) self.assertEqual(1, archive.size()) self.assertTrue(new_solution in archive.solution_list)
def test_should_compare_return_zero_if_both_solutions_have_the_same_attribute_value(self): solution1 = Solution(1, 1) solution2 = Solution(1, 1) solution1.attributes["attribute"] = 1.0 solution2.attributes["attribute"] = 1.0 self.assertEqual(0, self.comparator.compare(solution1, solution2))
def test_should_add_work_properly_case6(self): """ Case 6: add a non-dominated solution when the archive is full should not include the solution if it has the highest distance crowding value. """ archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] solution2 = Solution(2, 2) solution2.objectives = [1.0, 2.0] solution3 = Solution(2, 2) solution3.objectives = [2.0, 1.5] solution4 = Solution(2, 2) solution4.objectives = [3.0, 0.0] new_solution = Solution(2, 2) new_solution.objectives = [1.1, 1.9] archive.add(solution1) archive.add(solution2) archive.add(solution3) archive.add(solution4) archive.add(new_solution) self.assertEqual(4, archive.size()) self.assertTrue(new_solution not in archive.solution_list)
def test_should_compare_work_properly_case_2(self): """ Case 2: solution1.ranking > solution2.ranking """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) solution1.attributes["dominance_ranking"] = 2.0 solution2.attributes["dominance_ranking"] = 1.0 self.assertEqual(1, self.comparator.compare(solution1, solution2))
def test_should_compare_works_properly_case2(self): """ Case 2: solution1.attribute > solution2.attribute (lowest is best) """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) solution1.attributes["attribute"] = 1.0 solution2.attributes["attribute"] = 0.0 self.assertEqual(1, self.comparator.compare(solution1, solution2))
def test_should_compare_works_properly_case4(self): """ Case 4: solution1.attribute > solution2.attribute (highest is best) """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) solution1.attributes["attribute"] = 1.0 solution2.attributes["attribute"] = 0.0 comparator = SolutionAttributeComparator("attribute", False) self.assertEqual(-1, comparator.compare(solution1, solution2))
def test_should_adding_two_solutions_work_properly_if_one_is_dominated(self): dominated_solution = Solution(1, 2) dominated_solution.objectives = [2.0, 2.0] dominant_solution = Solution(1, 2) dominant_solution.objectives = [1.0, 1.0] self.archive.add(dominated_solution) self.archive.add(dominant_solution) self.assertEqual(1, self.archive.size()) self.assertEqual(dominant_solution, self.archive.solution_list[0])
def test_should_adding_two_solutions_work_properly_if_both_are_non_dominated(self): solution1 = Solution(1, 2) solution1.objectives = [1.0, 0.0] solution2 = Solution(1, 2) solution2.objectives = [0.0, 1.0] self.archive.add(solution1) self.archive.add(solution2) self.assertEqual(2, self.archive.size()) self.assertTrue(solution1 in self.archive.solution_list and solution2 in self.archive.solution_list)
def test_should_compute_density_estimator_work_properly_case1(self): """ Case 1: The archive contains one solution. """ archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] archive.add(solution1) archive.compute_density_estimator() self.assertEqual(1, archive.size()) self.assertEqual(float("inf"), solution1.attributes["crowding_distance"])
def test_should_add_work_properly_case1(self): """ Case 1: add a dominated solution when the archive size is 1 must not include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [3, 4] self.archive.add(solution1) self.archive.add(solution2) self.assertEqual(1, self.archive.size()) self.assertEqual(solution1, self.archive.get(0))
def test_should_add_work_properly_case2(self): """ Case 2: add a non-dominated solution when the archive size is 1 must include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [0, 4] self.archive.add(solution1) self.archive.add(solution2) self.assertEqual(2, self.archive.size()) self.assertTrue(solution1 in self.archive.solution_list) self.assertTrue(solution2 in self.archive.solution_list)
def test_should_hypervolume_return_5_0(self): reference_point = [2, 2, 2] solution1 = Solution(1, 3) solution1.objectives = [1, 0, 1] solution2 = Solution(1, 3) solution2.objectives = [0, 1, 0] front = [solution1, solution2] hv = HyperVolume(reference_point) value = hv.compute(front) self.assertEqual(5.0, value)
def test_should_compute_density_estimator_work_properly_case3(self): """Case 3: The archive contains two solutions.""" archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] solution2 = Solution(2, 2) solution2.objectives = [1.0, 2.0] solution3 = Solution(2, 2) solution3.objectives = [2.0, 1.5] archive.add(solution1) archive.add(solution2) archive.add(solution3) archive.compute_density_estimator() self.assertEqual(3, archive.size()) self.assertEqual(float("inf"), solution1.attributes["crowding_distance"]) self.assertEqual(float("inf"), solution3.attributes["crowding_distance"]) self.assertTrue(solution2.attributes["crowding_distance"] < float("inf"))
def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_solutions( self): solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] solution_list = [solution1, solution2] self.assertTrue(self.selection.execute(solution_list) in solution_list)
def test_should_execute_work_if_the_solution_list_contains_two_solutions_and_one_them_is_dominated( self): solution1 = Solution(2, 2) solution1.objectives = [1.0, 4.0] solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] solution_list = [solution1, solution2] self.assertEqual(solution2, self.selection.execute(solution_list))
def test_should_compare_works_properly_case3(self): """ Case 3: solution1.attribute < solution2.attribute (highest is best) """ comparator = SolutionAttributeComparator("attribute", False) solution1 = Solution(1, 1) solution2 = Solution(1, 1) solution1.attributes["attribute"] = 0.0 solution2.attributes["attribute"] = 1.0 self.assertEqual(1, comparator.compare(solution1, solution2))
def test_should_get_neighbors_return_four_neighbors_case3(self): """ Solution list: 0, 1 Solution location: 1; the neighborhood is: 0, 1 """ rows = 1 columns = 2 solution_list = [Solution(i, 2) for i in range(rows * columns)] neighborhood = L5(rows, columns) result = neighborhood.get_neighbors(1, solution_list) self.assertEqual(4, len(result)) self.assertTrue(solution_list[0] in result) self.assertTrue(solution_list[1] in result) self.assertEqual(2, result.count(solution_list[0])) self.assertEqual(2, result.count(solution_list[1]))
def test_should_get_neighbors_work_properly_with_two_objectives(self): number_of_weight_vectors = 100 neighborhood_size = 20 neighborhood: WeightVectorNeighborhood = WeightVectorNeighborhood(number_of_weight_vectors, neighborhood_size) solution_list = [Solution(2, 2) for _ in range(number_of_weight_vectors)] neighbors = neighborhood.get_neighbors(0, solution_list) self.assertEqual(neighborhood_size, len(neighbors)) self.assertTrue(solution_list[0] == neighbors[0]) self.assertTrue(solution_list[19] == neighbors[19]) neighbors = neighborhood.get_neighbors(69, solution_list) self.assertEqual(neighborhood_size, len(neighbors)) self.assertTrue(solution_list[69] == neighbors[0]) self.assertTrue(solution_list[79] == neighbors[19])
def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_solutions( self): solution1 = Solution(2, 2) solution1.variables = [1.0, 2.0] solution2 = Solution(2, 2) solution2.variables = [0.0, 3.0] solution_list = [solution1, solution2] assert_that(any_of(solution1, solution2), self.selection.execute(solution_list))
def test_should_find_an_ideal_point(self): solution1 = Solution(3, 2) solution1.objectives = [1.0, 0.1] solution2 = Solution(3, 2) solution2.objectives = [0.5, 2.0] solutions = [solution1, solution2] selection = EnvironmentalSelection(2, 100) self.assertEqual([0.5, 0.1], selection.find_ideal_point(solutions))
def test_should_add_work_properly_case1(self): """Case 1: add a dominated solution when the archive size is 1 must not include the solution.""" solution1 = Solution(2, 2) solution1.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [3, 4] self.archive.add(solution1) self.archive.add(solution2) self.assertEqual(1, self.archive.size()) self.assertEqual(solution1, self.archive.get(0))
def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_solutions(self): selection = NaryRandomSolutionSelection[Solution](2) solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] solution_list = [solution1, solution2] selection_result = selection.execute(solution_list) self.assertTrue(selection_result[0] in solution_list) self.assertTrue(selection_result[1] in solution_list)
def test_should_compare_work_properly_case_5(self): """ Case 5: solution1.ranking == solution2.ranking solution1.crowding == solution2.crowding """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) solution1.attributes["dominance_ranking"] = 1.0 solution2.attributes["dominance_ranking"] = 1.0 solution1.attributes["crowding_distance"] = 2.0 solution2.attributes["crowding_distance"] = 2.0 self.assertEqual(0, self.comparator.compare(solution1, solution2))
def test_should_the_crowding_distance_of_three_solutions_correctly_assigned(self): solution1 = Solution(2, 2) solution2 = Solution(2, 2) solution3 = Solution(2, 2) solution1.objectives[0] = 0.0 solution1.objectives[1] = 1.0 solution2.objectives[0] = 1.0 solution2.objectives[1] = 0.0 solution3.objectives[0] = 0.5 solution3.objectives[1] = 0.5 solution_list = [solution1, solution2, solution3] self.crowding.compute_density_estimator(solution_list) value_from_solution1 = solution_list[0].attributes["crowding_distance"] value_from_solution2 = solution_list[1].attributes["crowding_distance"] value_from_solution3 = solution_list[2].attributes["crowding_distance"] self.assertEqual(float("inf"), value_from_solution1) self.assertEqual(float("inf"), value_from_solution2) self.assertEqual(2.0, value_from_solution3)
def test_should_gd_return_0(self): solution1 = Solution(1, 3) solution1.objectives = [1, 0, 1] solution2 = Solution(1, 3) solution2.objectives = [0, 1, 0] reference_front = [solution1, solution2] gd = GenerationalDistance(reference_front) value = gd.compute(reference_front) self.assertEqual(0.0, value)
def test_should_gd_return_the_closest_point_case_a(self): solution1 = Solution(1, 3) solution1.objectives = [1, 1, 1] solution2 = Solution(1, 3) solution2.objectives = [2, 2, 2] reference_front = [solution1, solution2] gd = GenerationalDistance(reference_front) value = gd.compute([solution1]) self.assertEqual(0, value)
def test_should_compute_ranking_return_a_subfront_if_the_solution_list_contains_two_nondominated_solutions(self): solution = Solution(2, 2) solution.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [2, 1] solution_list = [solution, solution2] ranking = self.ranking.compute_ranking(solution_list) self.assertEqual(1, self.ranking.get_number_of_subfronts()) self.assertEqual(2, len(self.ranking.get_subfront(0))) self.assertEqual(solution, ranking[0][0]) self.assertEqual(solution2, ranking[0][1])
def test_should_adding_four_solutions_work_properly_if_one_dominates_the_others(self): solution1 = Solution(1, 2) solution1.objectives = [1.0, 1.0] solution2 = Solution(1, 2) solution2.objectives = [0.0, 2.0] solution3 = Solution(1, 2) solution3.objectives = [0.5, 1.5] solution4 = Solution(1, 2) solution4.objectives = [0.0, 0.0] self.archive.add(solution1) self.archive.add(solution2) self.archive.add(solution3) self.archive.add(solution4) self.assertEqual(1, self.archive.size()) self.assertEqual(solution4, self.archive.solution_list[0])
def test_should_add_work_properly_case2(self): """Case 2: add a non-dominated solution when the archive size is 1 must include the solution.""" solution1 = Solution(2, 2) solution1.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [0, 4] self.archive.add(solution1) self.archive.add(solution2) self.assertEqual(2, self.archive.size()) self.assertTrue(solution1 in self.archive.solution_list) self.assertTrue(solution2 in self.archive.solution_list)
def test_should_get_neighbors_return_four_neighbors_case6(self): """ Case 1 Solution list: 0 1 2 3 4 5 The solution location is 0, so the neighborhood is 1, 3, 3, 2 """ rows = 2 columns = 3 solution_list = [Solution(i, 2) for i in range(rows * columns)] neighborhood = TwoDimensionalMesh(rows, columns, [[-1, 0], [1, 0], [0, 1], [0, -1]]) result = neighborhood.get_neighbors(0, solution_list) self.assertEqual(4, len(result)) self.assertTrue(solution_list[1] in result) self.assertTrue(solution_list[3] in result) self.assertTrue(solution_list[2] in result)
def execute(self, solution: Solution) -> Solution: if random.random() <= self.probability: mutant = copy.copy(solution.variables) lix = [i for (i, j) in mutant] index = random.randint(0, len(mutant) - 1) idx, idy = mutant[index] is_mutate_idx = False if random.random() > 0.5: idx = random.randint(solution.lower_bound[0], solution.upper_bound[0]) while idx in lix: idx = random.randint(solution.lower_bound[0], solution.upper_bound[0]) is_mutate_idx = True lv = random.randint(solution.lower_bound[1], solution.upper_bound[1]) if not is_mutate_idx: while lv == idy: lv = random.randint(solution.lower_bound[1], solution.upper_bound[1]) mutant[index] = (idx, lv) solution.variables = mutant return solution
def test_should_add_work_properly_case5(self): """ Case 5: add a dominated solution when the archive is full should not include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] solution2 = Solution(2, 2) solution2.objectives = [0.0, 4.0] solution3 = Solution(2, 2) solution3.objectives = [1.5, 1.5] solution4 = Solution(2, 2) solution4.objectives = [5.0, 6.0] self.archive.add(solution1) self.archive.add(solution2) self.archive.add(solution3) self.archive.add(solution4) self.assertEqual(3, self.archive.size()) self.assertTrue(solution1 in self.archive.solution_list) self.assertTrue(solution2 in self.archive.solution_list) self.assertTrue(solution3 in self.archive.solution_list)
def test_should_add_work_properly_case3(self): """ Case 3: add a non-dominated solution when the archive size is 3 must include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] solution2 = Solution(2, 2) solution2.objectives = [0.0, 4.0] solution3 = Solution(2, 2) solution3.objectives = [1.5, 1.5] solution4 = Solution(2, 2) solution4.objectives = [1.6, 1.2] self.archive.add(solution1) self.archive.add(solution2) self.archive.add(solution3) self.archive.add(solution4) self.assertEqual(4, self.archive.size()) self.assertTrue(solution1 in self.archive.solution_list) self.assertTrue(solution2 in self.archive.solution_list) self.assertTrue(solution3 in self.archive.solution_list) self.assertTrue(solution4 in self.archive.solution_list)
def test_should_compute_ranking_work_properly_case1(self): """ The list contains two solutions and one of them is dominated by the other one """ solution = Solution(2, 2) solution.objectives = [2, 3] solution2 = Solution(2, 2) solution2.objectives = [3, 6] solution_list = [solution, solution2] ranking = self.ranking.compute_ranking(solution_list) self.assertEqual(2, self.ranking.get_number_of_subfronts()) self.assertEqual(1, len(self.ranking.get_subfront(0))) self.assertEqual(1, len(self.ranking.get_subfront(1))) self.assertEqual(solution, ranking[0][0]) self.assertEqual(solution2, ranking[1][0])
def test_should_get_neighbors_return_four_neighbors_case4(self): """ Solution list: 0 1 2 3 Solution location: 0; the neighborhood is: 1, 2 """ rows = 2 columns = 2 solution_list = [Solution(i, 2) for i in range(rows * columns)] neighborhood = L5(rows, columns) result = neighborhood.get_neighbors(0, solution_list) self.assertEqual(4, len(result)) self.assertTrue(solution_list[1] in result) self.assertTrue(solution_list[2] in result) self.assertTrue(solution_list[3] not in result) self.assertTrue(solution_list[0] not in result) self.assertEqual(2, result.count(solution_list[1])) self.assertEqual(2, result.count(solution_list[2]))
def test_should_add_work_properly_case1(self): """ Case 1: add a dominated solution when the archive size is 1 must not include the solution """ archive = CrowdingDistanceArchive[Solution](5) solution1 = Solution(2, 2) solution1.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [3, 4] archive.add(solution1) archive.add(solution2) self.assertEqual(1, archive.size()) self.assertEqual(solution1, archive.get(0))
def test_should_add_work_properly_case2(self): """ Case 2: add a non-dominated solution when the archive size is 1 must include the solution """ archive = CrowdingDistanceArchive[Solution](5) solution1 = Solution(2, 2) solution1.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [0, 4] archive.add(solution1) archive.add(solution2) self.assertEqual(2, archive.size()) self.assertTrue(solution1 in archive.get_solution_list()) self.assertTrue(solution2 in archive.get_solution_list())
def test_should_adding_three_solutions_work_properly_if_two_of_them_are_equal(self): solution1 = Solution(1, 2) solution1.objectives = [1.0, 1.0] solution2 = Solution(1, 2) solution2.objectives = [0.0, 2.0] solution3 = Solution(1, 2) solution3.objectives = [1.0, 1.0] self.archive.add(solution1) self.archive.add(solution2) result = self.archive.add(solution3) self.assertEqual(2, self.archive.size()) self.assertFalse(result) self.assertTrue(solution1 in self.archive.solution_list or solution3 in self.archive.solution_list)
def test_should_compute_density_estimator_work_properly_case3(self): """ Case 3: The archive contains two solutions. """ archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] solution2 = Solution(2, 2) solution2.objectives = [1.0, 2.0] solution3 = Solution(2, 2) solution3.objectives = [2.0, 1.5] archive.add(solution1) archive.add(solution2) archive.add(solution3) archive.compute_density_estimator() self.assertEqual(3, archive.size()) self.assertEqual(float("inf"), solution1.attributes["crowding_distance"]) self.assertEqual(float("inf"), solution3.attributes["crowding_distance"]) self.assertTrue(solution2.attributes["crowding_distance"] < float("inf"))
def test_should_ranking_of_a_population_with_five_solutions_work_properly( self): solution1 = Solution(2, 2) solution2 = Solution(2, 2) solution3 = Solution(2, 2) solution4 = Solution(2, 2) solution5 = Solution(2, 2) solution1.objectives[0] = 1.0 solution1.objectives[1] = 0.0 solution2.objectives[0] = 0.5 solution2.objectives[1] = 0.5 solution3.objectives[0] = 0.0 solution3.objectives[1] = 1.0 solution4.objectives[0] = 0.6 solution4.objectives[1] = 0.6 solution5.objectives[0] = 0.7 solution5.objectives[1] = 0.5 solution_list = [solution1, solution2, solution3, solution4, solution5] ranking = self.ranking.compute_ranking(solution_list) self.assertEqual(2, self.ranking.get_number_of_subfronts()) self.assertEqual(3, len(self.ranking.get_subfront(0))) self.assertEqual(2, len(self.ranking.get_subfront(1))) self.assertEqual(solution1, ranking[0][0]) self.assertEqual(solution2, ranking[0][1]) self.assertEqual(solution3, ranking[0][2]) self.assertEqual(solution4, ranking[1][0]) self.assertEqual(solution5, ranking[1][1])
def test_should_adding_four_solutions_work_properly_if_one_dominates_the_others( self): solution1 = Solution(1, 2) solution1.objectives = [1.0, 1.0] solution2 = Solution(1, 2) solution2.objectives = [0.0, 2.0] solution3 = Solution(1, 2) solution3.objectives = [0.5, 1.5] solution4 = Solution(1, 2) solution4.objectives = [0.0, 0.0] self.archive.add(solution1) self.archive.add(solution2) self.archive.add(solution3) self.archive.add(solution4) self.assertEqual(1, self.archive.size()) self.assertEqual(solution4, self.archive.solution_list[0])
def test_should_adding_one_solution_work_properly(self): solution = Solution(1, 1) self.archive.add(solution) self.assertEqual(1, self.archive.size()) self.assertEqual(solution, self.archive.solution_list[0])
def test_should_compare_return_zero_if_the_second_solution_has_no_the_attribute(self): solution1 = Solution(1, 1) solution2 = Solution(1, 1) solution1.attributes["attribute"] = 1.0 self.assertEqual(0, self.comparator.compare(solution1, solution2))