def update_external_archive(self): feasible_solutions = [] for solution in self.solutions: if is_feasible(solution): feasible_solutions.append(copy.deepcopy(solution)) if len(feasible_solutions) > 0: feasible_solutions = feasible_solutions + self.archive ranking = FastNonDominatedRanking() ranking.compute_ranking(feasible_solutions) first_rank_solutions = ranking.get_subfront(0) if len(first_rank_solutions) <= self.population_size: self.archive = [] for solution in first_rank_solutions: self.archive.append(copy.deepcopy(solution)) else: crowding_distance = CrowdingDistance() while len(first_rank_solutions) > self.population_size: crowding_distance.compute_density_estimator( first_rank_solutions) first_rank_solutions = sorted( first_rank_solutions, key=lambda x: x.attributes['crowding_distance'], reverse=True) first_rank_solutions.pop() self.archive = [] for solution in first_rank_solutions: self.archive.append(copy.deepcopy(solution))
def execute(self, front: List[S]) -> List[S]: if front is None: raise Exception('The front is null') elif len(front) == 0: raise Exception('The front is empty') ranking = FastNonDominatedRanking(self.dominance_comparator) crowding_distance = CrowdingDistance() ranking.compute_ranking(front) ranking_index = 0 new_solution_list = [] while len(new_solution_list) < self.max_population_size: if len(ranking.get_subfront(ranking_index)) < (self.max_population_size - len(new_solution_list)): new_solution_list = new_solution_list + ranking.get_subfront(ranking_index) ranking_index += 1 else: subfront = ranking.get_subfront(ranking_index) crowding_distance.compute_density_estimator(subfront) sorted_subfront = sorted(subfront, key=lambda x: x.attributes['crowding_distance'], reverse=True) for i in range((self.max_population_size - len(new_solution_list))): new_solution_list.append(sorted_subfront[i]) return new_solution_list
def __init__( self, problem: Problem, population_size: int, neighborhood: Neighborhood, archive: BoundedArchive, mutation: Mutation, crossover: Crossover, selection: Selection = BinaryTournamentSelection( MultiComparator([ FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator() ])), termination_criterion: TerminationCriterion = store. default_termination_criteria, population_generator: Generator = store.default_generator, population_evaluator: Evaluator = store.default_evaluator, dominance_comparator: Comparator = store.default_comparator, ): """ MOCEll implementation as described in: :param problem: The problem to solve. :param population_size: Size of the population. :param mutation: Mutation operator (see :py:mod:`jmetal.operator.mutation`). :param crossover: Crossover operator (see :py:mod:`jmetal.operator.crossover`). :param selection: Selection operator (see :py:mod:`jmetal.operator.selection`). """ super(MOCell, self).__init__( problem=problem, population_size=population_size, offspring_population_size=1, mutation=mutation, crossover=crossover, selection=selection, termination_criterion=termination_criterion, population_evaluator=population_evaluator, population_generator=population_generator, ) self.dominance_comparator = dominance_comparator self.neighborhood = neighborhood self.archive = archive self.current_individual = 0 self.current_neighbors = [] self.comparator = MultiComparator([ FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator() ])
def __init__( self, problem: DynamicProblem[S], population_size: int, offspring_population_size: int, mutation: Mutation, crossover: Crossover, selection: Selection = BinaryTournamentSelection( MultiComparator([ FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator() ])), termination_criterion: TerminationCriterion = store. default_termination_criteria, population_generator: Generator = store.default_generator, population_evaluator: Evaluator = store.default_evaluator, dominance_comparator: DominanceComparator = DominanceComparator()): super(DynamicNSGAII, self).__init__( problem=problem, population_size=population_size, offspring_population_size=offspring_population_size, mutation=mutation, crossover=crossover, selection=selection, population_evaluator=population_evaluator, population_generator=population_generator, termination_criterion=termination_criterion, dominance_comparator=dominance_comparator) self.completed_iterations = 0 self.start_computing_time = 0 self.total_computing_time = 0
def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[S]]: result = self.dominance_comparator.compare(population[self.current_individual], offspring_population[0]) if result == 1: # the offspring individual dominates the current one population[self.current_individual] = offspring_population[0] self.archive.add(offspring_population[0]) elif result == 0: # the offspring and current individuals are non-dominated new_individual = offspring_population[0] self.current_neighbors.append(new_individual) ranking: Ranking = FastNonDominatedRanking() ranking.compute_ranking(self.current_neighbors) density_estimator: DensityEstimator = CrowdingDistance() for i in range(ranking.get_number_of_subfronts()): density_estimator.compute_density_estimator(ranking.get_subfront(i)) self.current_neighbors.sort(key=cmp_to_key(self.comparator.compare)) worst_solution = self.current_neighbors[-1] self.archive.add(new_individual) if worst_solution != new_individual: population[self.current_individual] = new_individual return population
def __init__( self, problem: Problem, population_size: int, mutation: Mutation, crossover: Crossover, number_of_cores: int, client, selection: Selection = BinaryTournamentSelection( MultiComparator([ FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator() ])), termination_criterion: TerminationCriterion = store. default_termination_criteria, dominance_comparator: DominanceComparator = DominanceComparator()): super(DistributedNSGAII, self).__init__() self.problem = problem self.population_size = population_size self.mutation_operator = mutation self.crossover_operator = crossover self.selection_operator = selection self.dominance_comparator = dominance_comparator self.termination_criterion = termination_criterion self.observable.register(termination_criterion) self.number_of_cores = number_of_cores self.client = client
def __init__( self, problem: Problem, dominance_comparator: Comparator = store.default_comparator, max_evaluations: int = 250, individual_population_size: int = 100, report_interval: int = 100, dataDirectory: str = "./decmopy/decmo2/weigths", ): super().__init__() self.problem = problem self.population_size = individual_population_size self.max_evaluations = max_evaluations self.report_interval = report_interval self.dataDirectory = dataDirectory self.mix_interval = 1 """Replacement""" ranking = FastNonDominatedRanking(dominance_comparator) density_estimator = CrowdingDistance() self.r = RankingAndDensityEstimatorReplacement( ranking, density_estimator, RemovalPolicyType.SEQUENTIAL) self.MIN_VALUES = 0 self.MAX_VALUES = 1 min_values: List[float] = [] max_values: List[float] = [] for _ in range(problem.number_of_objectives): min_values.append(sys.float_info.max) max_values.append(sys.float_info.min) self.extreme_values: List[List[float]] = [] self.extreme_values.append(min_values) self.extreme_values.append(max_values)
def __init__(self, maximum_size: int, reference_point: List[float]): super(CrowdingDistanceArchiveWithReferencePoint, self).__init__( maximum_size=maximum_size, reference_point=reference_point, comparator=SolutionAttributeComparator("crowding_distance", lowest_is_best=False), density_estimator=CrowdingDistance())
def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[S]]: """ This method joins the current and offspring populations to produce the population of the next generation by applying the ranking and crowding distance selection. :param population: Parent population. :param offspring_population: Offspring population. :return: New population after ranking and crowding distance selection is applied. """ ranking = FastNonDominatedRanking(self.dominance_comparator) density_estimator = CrowdingDistance() r = RankingAndDensityEstimatorReplacement(ranking, density_estimator, RemovalPolicyType.ONE_SHOT) solutions = r.replace(population, offspring_population) front = self.get_result() if type(front) is not list: solutions = [front] for solution in front: print(solution.variables[0]) for solution in front: print(str(front.index(solution)) + ": ", sep=' ', end='', flush=True) print(solution.objectives, sep=' ', end='', flush=True) print() return solutions
def __init__(self, reference_directions, problem: Problem, mutation: Mutation, crossover: Crossover, population_size: int = None, selection: Selection = BinaryTournamentSelection( MultiComparator([FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator()])), termination_criterion: TerminationCriterion = store.default_termination_criteria, population_generator: Generator = store.default_generator, population_evaluator: Evaluator = store.default_evaluator, dominance_comparator: Comparator = store.default_comparator): self.reference_directions = reference_directions.compute() if not population_size: population_size = len(self.reference_directions) if self.reference_directions.shape[1] != problem.number_of_objectives: raise Exception('Dimensionality of reference points must be equal to the number of objectives') super(NSGAIII, self).__init__( problem=problem, population_size=population_size, offspring_population_size=population_size, mutation=mutation, crossover=crossover, selection=selection, termination_criterion=termination_criterion, population_evaluator=population_evaluator, population_generator=population_generator, dominance_comparator=dominance_comparator ) self.extreme_points = None self.ideal_point = np.full(self.problem.number_of_objectives, np.inf) self.worst_point = np.full(self.problem.number_of_objectives, -np.inf)
def __init__(self, problem: Problem, population_size: int, offspring_population_size: int, mutation: Mutation, crossover: Crossover, selection: Selection = BinaryTournamentSelection( MultiComparator([ FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator() ])), termination_criterion: TerminationCriterion = store. default_termination_criteria, population_generator: Generator = store.default_generator, population_evaluator: Evaluator = store.default_evaluator, dominance_comparator: Comparator = store.default_comparator, target_value_threshold: List[float] = None, target_pattern: List[int] = None): """ NSGA-II implementation as described in * K. Deb, A. Pratap, S. Agarwal and T. Meyarivan, "A fast and elitist multiobjective genetic algorithm: NSGA-II," in IEEE Transactions on Evolutionary Computation, vol. 6, no. 2, pp. 182-197, Apr 2002. doi: 10.1109/4235.996017 NSGA-II is a genetic algorithm (GA), i.e. it belongs to the evolutionary algorithms (EAs) family. The implementation of NSGA-II provided in jMetalPy follows the evolutionary algorithm template described in the algorithm module (:py:mod:`jmetal.core.algorithm`). .. note:: A steady-state version of this algorithm can be run by setting the offspring size to 1. :param problem: The problem to solve. :param population_size: Size of the population. :param mutation: Mutation operator (see :py:mod:`jmetal.operator.mutation`). :param crossover: Crossover operator (see :py:mod:`jmetal.operator.crossover`). :param selection: Selection operator (see :py:mod:`jmetal.operator.selection`). """ super(NSGAII, self).__init__( problem=problem, population_size=population_size, offspring_population_size=offspring_population_size, mutation=mutation, crossover=crossover, selection=selection, termination_criterion=termination_criterion, population_evaluator=population_evaluator, population_generator=population_generator) self.dominance_comparator = dominance_comparator self.generation = 0 self.target_pattern = target_pattern self.problem_solved = False self.target_value_threshold = target_value_threshold self.file_pareto_front = os.getcwd() + '/' + str( time.strftime("%Y_%m_%d")) + '_PARETO_' if not os.path.exists(self.file_pareto_front): os.mkdir(self.file_pareto_front)
def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[S]]: ranking = FastNonDominatedRanking(self.dominance_comparator) density_estimator = CrowdingDistance() r = RankingAndDensityEstimatorReplacement(ranking, density_estimator, RemovalPolicyType.ONE_SHOT) solutions = r.replace(population, offspring_population) return solutions
def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[S]]: """ This method joins the current and offspring populations to produce the population of the next generation by applying the ranking and crowding distance selection. :param population: Parent population. :param offspring_population: Offspring population. :return: New population after ranking and crowding distance selection is applied. """ ranking = FastNonDominatedRanking(self.dominance_comparator) density_estimator = CrowdingDistance() r = RankingAndDensityEstimatorReplacement(ranking, density_estimator, RemovalPolicyType.ONE_SHOT) solutions = r.replace(population, offspring_population) return solutions
def __init__(self, problem: MultiTransfer.MultiTransferProblem, population_size: int, offspring_population_size: int, mutation: Mutation, crossover: Crossover, selection: Selection = BinaryTournamentSelection( MultiComparator([FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator()])), termination_criterion: TerminationCriterion = store.default_termination_criteria, population_generator: Generator = store.default_generator, population_evaluator: Evaluator = store.default_evaluator, dominance_comparator: Comparator = store.default_comparator): """ NSGA-II implementation as described in * K. Deb, A. Pratap, S. Agarwal and T. Meyarivan, "A fast and elitist multiobjective genetic algorithm: NSGA-II," in IEEE Transactions on Evolutionary Computation, vol. 6, no. 2, pp. 182-197, Apr 2002. doi: 10.1109/4235.996017 NSGA-II is a genetic algorithm (GA), i.e. it belongs to the evolutionary algorithms (EAs) family. The implementation of NSGA-II provided in jMetalPy follows the evolutionary algorithm template described in the algorithm module (:py:mod:`jmetal.core.algorithm`). .. note:: A steady-state version of this algorithm can be run by setting the offspring size to 1. :param problem: The problem to solve. :param population_size: Size of the population. :param mutation: Mutation operator (see :py:mod:`jmetal.operator.mutation`). :param crossover: Crossover operator (see :py:mod:`jmetal.operator.crossover`). :param selection: Selection operator (see :py:mod:`jmetal.operator.selection`). """ super(NSGAII_MEDA, self).__init__( problem=problem, population_size=population_size, offspring_population_size=offspring_population_size, mutation=mutation, crossover=crossover, selection=selection, termination_criterion=termination_criterion, population_evaluator=population_evaluator, population_generator=population_generator ) self.dominance_comparator = dominance_comparator
def __init__( self, problem: Problem, dominance_comparator: Comparator = store.default_comparator, max_iterations: int = 250, individual_population_size: int = 100, report_interval: int = 100, ): super().__init__() self.problem = problem self.population_size = individual_population_size self.max_iterations = max_iterations self.report_interval = report_interval self.mix_interval = self.population_size / 10 """Replacement""" ranking = FastNonDominatedRanking(dominance_comparator) density_estimator = CrowdingDistance() self.r = RankingAndDensityEstimatorReplacement( ranking, density_estimator, RemovalPolicyType.SEQUENTIAL)
def construct(self, hyperparameters: Mapping, scenario: Mapping, warm_startup_info: Mapping) -> None: # Constructing meta-heuristics initialization arguments (components + simple hyperparameters) init_args = dict(copy(hyperparameters)) if "crossover_type" in init_args: import jmetal.operator.crossover as crossover crossover_class = JMetalPyWrapper._get_class_from_module( name=init_args.pop("crossover_type"), module=crossover) init_args["crossover"] = crossover_class( init_args.pop("crossover_probability")) if "mutation_type" in init_args: import jmetal.operator.mutation as mutation mutation_class = JMetalPyWrapper._get_class_from_module( name=init_args.pop("mutation_type"), module=mutation) init_args["mutation"] = mutation_class( init_args.pop("mutation_probability")) if "selection_type" in init_args: selection_type = init_args.pop('selection_type') if selection_type == 'ReuletteWheelSelection': from jmetal.util.comparator import MultiComparator from jmetal.util.density_estimator import CrowdingDistance from jmetal.util.ranking import FastNonDominatedRanking init_args["selection"] = MultiComparator([ FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator() ]) else: import jmetal.operator.selection as selection selection_class = JMetalPyWrapper._get_class_from_module( name=selection_type, module=selection) init_args["selection"] = selection_class() # Add all non-component Metaheuristic parameters if "offspring_population_size" in init_args: offsp_population = init_args.pop("offspring_population_size") # offspring_population_size should be even offsp_population += offsp_population % 2 init_args['offspring_population_size'] = offsp_population # elitist should be bool if "elitist" in init_args: init_args['elitist'] = True if init_args.pop( 'elitist') == "True" else False if "population_size" in init_args: init_args["population_size"] = init_args.pop("population_size") termination_class = JMetalPyWrapper._get_class_from_module( name=scenario["Budget"]["Type"], module=termination) init_args["termination_criterion"] = termination_class( scenario["Budget"]["Amount"]) # making dict hashable enables using LRU cache problem_init_params = HashableDict( scenario['problem_initialization_parameters']) problem = JMetalPyWrapper._get_problem( problem_name=scenario['Problem'], init_params=problem_init_params) init_args["problem"] = problem # Attach initial solutions. self.load_initial_solutions(warm_startup_info, problem) llh_name = init_args.pop("low level heuristic") if llh_name == "jMetalPy.SimulatedAnnealing": init_args["solution_generator"] = self._solution_generator else: init_args['population_generator'] = self._solution_generator # Instantiate Metaheuristic object self._llh_algorithm = JMetalPyWrapper._get_algorithm_class(llh_name)( **init_args)
def __init__(self, maximum_size: int): super(CrowdingDistanceArchive, self).__init__( maximum_size=maximum_size, comparator=SolutionAttributeComparator("crowding_distance", lowest_is_best=False), density_estimator=CrowdingDistance())
from jmetal.util.termination_criterion import StoppingByEvaluations if __name__ == '__main__': problem = TSP(instance='../../resources/TSP_instances/kroA100.tsp') print('Cities: ', problem.number_of_variables) algorithm = GeneticAlgorithm( problem=problem, population_size=100, offspring_population_size=100, mutation=PermutationSwapMutation(1.0 / problem.number_of_variables), crossover=PMXCrossover(0.8), selection=BinaryTournamentSelection( MultiComparator([ FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator() ])), termination_criterion=StoppingByEvaluations(max=2500000)) algorithm.observable.register(observer=PrintObjectivesObserver(1000)) algorithm.run() result = algorithm.get_result() print('Algorithm: {}'.format(algorithm.get_name())) print('Problem: {}'.format(problem.get_name())) print('Solution: {}'.format(result.variables)) print('Fitness: {}'.format(result.objectives[0])) print('Computing time: {}'.format(algorithm.total_computing_time))
def run(self): """ Execute the algorithm. """ self.start_computing_time = time.time() create_solution = dask.delayed(self.problem.create_solution) evaluate_solution = dask.delayed(self.problem.evaluate) task_pool = as_completed([], with_results=True) for _ in range(self.number_of_cores): new_solution = create_solution() new_evaluated_solution = evaluate_solution(new_solution) future = self.client.compute(new_evaluated_solution) task_pool.add(future) batches = task_pool.batches() auxiliar_population = [] while len(auxiliar_population) < self.population_size: batch = next(batches) for _, received_solution in batch: auxiliar_population.append(received_solution) if len(auxiliar_population) < self.population_size: break # submit as many new tasks as we collected for _ in batch: new_solution = create_solution() new_evaluated_solution = evaluate_solution(new_solution) future = self.client.compute(new_evaluated_solution) task_pool.add(future) self.init_progress() # perform an algorithm step to create a new solution to be evaluated while not self.stopping_condition_is_met(): batch = next(batches) for _, received_solution in batch: offspring_population = [received_solution] # replacement ranking = FastNonDominatedRanking(self.dominance_comparator) density_estimator = CrowdingDistance() r = RankingAndDensityEstimatorReplacement( ranking, density_estimator, RemovalPolicyType.ONE_SHOT) auxiliar_population = r.replace(auxiliar_population, offspring_population) # selection mating_population = [] for _ in range(2): solution = self.selection_operator.execute( auxiliar_population) mating_population.append(solution) # Reproduction and evaluation new_task = self.client.submit(reproduction, mating_population, self.problem, self.crossover_operator, self.mutation_operator) task_pool.add(new_task) # update progress self.evaluations += 1 self.solutions = auxiliar_population self.update_progress() if self.stopping_condition_is_met(): break self.total_computing_time = time.time() - self.start_computing_time # at this point, computation is done for future, _ in task_pool: future.cancel()
def setUp(self): self.crowding = CrowdingDistance()
class CrowdingDistanceTestCases(unittest.TestCase): def setUp(self): self.crowding = CrowdingDistance() def test_should_the_crowding_distance_of_an_empty_set_do_nothing(self): solution_list = [] self.crowding.compute_density_estimator(solution_list) def test_should_the_crowding_distance_of_single_solution_be_infinity(self): solution = Solution(3, 3) solution_list = [solution] self.crowding.compute_density_estimator(solution_list) value = solution_list[0].attributes["crowding_distance"] self.assertEqual(float("inf"), value) def test_should_the_crowding_distance_of_two_solutions_be_infinity(self): solution1 = Solution(3, 3) solution2 = Solution(3, 3) solution_list = [solution1, solution2] 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"] self.assertEqual(float("inf"), value_from_solution1) self.assertEqual(float("inf"), value_from_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_the_crowding_distance_of_four_solutions_correctly_assigned(self): solution1 = Solution(2, 2) solution2 = Solution(2, 2) solution3 = Solution(2, 2) solution4 = 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 solution4.objectives[0] = 0.75 solution4.objectives[1] = 0.75 solution_list = [solution1, solution2, solution3, solution4] 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"] value_from_solution4 = solution_list[3].attributes["crowding_distance"] self.assertEqual(float("inf"), value_from_solution1) self.assertEqual(float("inf"), value_from_solution2) self.assertGreater(value_from_solution3, value_from_solution4)