diff --git a/pygad/pygad.py b/pygad/pygad.py index 4d98416..5d175a6 100644 --- a/pygad/pygad.py +++ b/pygad/pygad.py @@ -880,7 +880,7 @@ def __init__(self, self.select_parents = self.rank_selection else: self.valid_parameters = False - raise TypeError(f"Undefined parent selection type: {parent_selection_type}. \nThe assigned value to the 'parent_selection_type' parameter does not refer to one of the supported parent selection techniques which are: \n-sss (for steady state selection)\n-rws (for roulette wheel selection)\n-sus (for stochastic universal selection)\n-rank (for rank selection)\n-random (for random selection)\n-tournament (for tournament selection).\n") + raise TypeError(f"Undefined parent selection type: {parent_selection_type}. \nThe assigned value to the 'parent_selection_type' parameter does not refer to one of the supported parent selection techniques which are: \n-sss (steady state selection)\n-rws (roulette wheel selection)\n-sus (stochastic universal selection)\n-rank (rank selection)\n-random (random selection)\n-tournament (tournament selection)\n-tournament_nsga2: (Tournament selection for NSGA-II)\n-nsga2: (NSGA-II parent selection).\n") # For tournament selection, validate the K value. if (parent_selection_type == "tournament"): diff --git a/pygad/utils/mutation.py b/pygad/utils/mutation.py index 75db685..303dea6 100644 --- a/pygad/utils/mutation.py +++ b/pygad/utils/mutation.py @@ -578,10 +578,31 @@ def adaptive_mutation_by_space(self, offspring): # Adaptive mutation changes one or more genes in each offspring randomly. # The number of genes to mutate depends on the solution's fitness value. for offspring_idx in range(offspring.shape[0]): - if offspring_fitness[offspring_idx] < average_fitness: - adaptive_mutation_num_genes = self.mutation_num_genes[0] + ## TODO Make edits to work with multi-objective optimization. + # Compare the fitness of each offspring to the average fitness of each objective function. + fitness_comparison = offspring_fitness[offspring_idx] < average_fitness + + # Check if the problem is single or multi-objective optimization. + if type(fitness_comparison) in [bool, numpy.bool_]: + # Single-objective optimization problem. + if offspring_fitness[offspring_idx] < average_fitness: + adaptive_mutation_num_genes = self.mutation_num_genes[0] + else: + adaptive_mutation_num_genes = self.mutation_num_genes[1] else: - adaptive_mutation_num_genes = self.mutation_num_genes[1] + # Multi-objective optimization problem. + + # Get the sum of the pool array (result of comparison). + # True is considered 1 and False is 0. + fitness_comparison_sum = sum(fitness_comparison) + # Check if more than or equal to 50% of the objectives have fitness greater than the average. + # If True, then use the first percentage. + # If False, use the second percentage. + if fitness_comparison_sum >= len(fitness_comparison)/2: + adaptive_mutation_num_genes = self.mutation_num_genes[0] + else: + adaptive_mutation_num_genes = self.mutation_num_genes[1] + mutation_indices = numpy.array(random.sample(range(0, self.num_genes), adaptive_mutation_num_genes)) for gene_idx in mutation_indices: @@ -703,6 +724,7 @@ def adaptive_mutation_randomly(self, offspring): ## TODO Make edits to work with multi-objective optimization. # Compare the fitness of each offspring to the average fitness of each objective function. fitness_comparison = offspring_fitness[offspring_idx] < average_fitness + # Check if the problem is single or multi-objective optimization. if type(fitness_comparison) in [bool, numpy.bool_]: # Single-objective optimization problem. @@ -791,10 +813,30 @@ def adaptive_mutation_probs_by_space(self, offspring): # Adaptive random mutation changes one or more genes in each offspring randomly. # The probability of mutating a gene depends on the solution's fitness value. for offspring_idx in range(offspring.shape[0]): - if offspring_fitness[offspring_idx] < average_fitness: - adaptive_mutation_probability = self.mutation_probability[0] + ## TODO Make edits to work with multi-objective optimization. + # Compare the fitness of each offspring to the average fitness of each objective function. + fitness_comparison = offspring_fitness[offspring_idx] < average_fitness + + # Check if the problem is single or multi-objective optimization. + if type(fitness_comparison) in [bool, numpy.bool_]: + # Single-objective optimization problem. + if offspring_fitness[offspring_idx] < average_fitness: + adaptive_mutation_probability = self.mutation_probability[0] + else: + adaptive_mutation_probability = self.mutation_probability[1] else: - adaptive_mutation_probability = self.mutation_probability[1] + # Multi-objective optimization problem. + + # Get the sum of the pool array (result of comparison). + # True is considered 1 and False is 0. + fitness_comparison_sum = sum(fitness_comparison) + # Check if more than or equal to 50% of the objectives have fitness greater than the average. + # If True, then use the first percentage. + # If False, use the second percentage. + if fitness_comparison_sum >= len(fitness_comparison)/2: + adaptive_mutation_probability = self.mutation_probability[0] + else: + adaptive_mutation_probability = self.mutation_probability[1] probs = numpy.random.random(size=offspring.shape[1]) for gene_idx in range(offspring.shape[1]): @@ -914,10 +956,30 @@ def adaptive_mutation_probs_randomly(self, offspring): # Adaptive random mutation changes one or more genes in each offspring randomly. # The probability of mutating a gene depends on the solution's fitness value. for offspring_idx in range(offspring.shape[0]): - if offspring_fitness[offspring_idx] < average_fitness: - adaptive_mutation_probability = self.mutation_probability[0] + ## TODO Make edits to work with multi-objective optimization. + # Compare the fitness of each offspring to the average fitness of each objective function. + fitness_comparison = offspring_fitness[offspring_idx] < average_fitness + + # Check if the problem is single or multi-objective optimization. + if type(fitness_comparison) in [bool, numpy.bool_]: + # Single-objective optimization problem. + if offspring_fitness[offspring_idx] < average_fitness: + adaptive_mutation_probability = self.mutation_probability[0] + else: + adaptive_mutation_probability = self.mutation_probability[1] else: - adaptive_mutation_probability = self.mutation_probability[1] + # Multi-objective optimization problem. + + # Get the sum of the pool array (result of comparison). + # True is considered 1 and False is 0. + fitness_comparison_sum = sum(fitness_comparison) + # Check if more than or equal to 50% of the objectives have fitness greater than the average. + # If True, then use the first percentage. + # If False, use the second percentage. + if fitness_comparison_sum >= len(fitness_comparison)/2: + adaptive_mutation_probability = self.mutation_probability[0] + else: + adaptive_mutation_probability = self.mutation_probability[1] probs = numpy.random.random(size=offspring.shape[1]) for gene_idx in range(offspring.shape[1]): diff --git a/tests/test_adaptive_mutation.py b/tests/test_adaptive_mutation.py index 9b427df..8a9d390 100644 --- a/tests/test_adaptive_mutation.py +++ b/tests/test_adaptive_mutation.py @@ -24,21 +24,39 @@ def output_adaptive_mutation(gene_space=None, init_range_low=-4, init_range_high=4, initial_population=None, - mutation_probability=[0.2, 0.1], + mutation_probability=None, + mutation_num_genes=None, fitness_batch_size=None, - mutation_type="adaptive"): + mutation_type="adaptive", + parent_selection_type='sss', + multi_objective=False): - def fitness_func_single(ga, solution, idx): + def fitness_func_no_batch_single(ga, solution, idx): return random.random() - def fitness_func_batch(ga, soluions, idxs): + def fitness_func_batch_single(ga, soluions, idxs): return numpy.random.uniform(size=len(soluions)) - if fitness_batch_size in [1, None]: - fitness_func = fitness_func_single - else: - fitness_func = fitness_func_batch - + def fitness_func_no_batch_multi(ga, solution, idx): + return [random.random(), random.random()] + + def fitness_func_batch_multi(ga, soluions, idxs): + f = [] + for sol in soluions: + f.append([random.random(), random.random()]) + return f + + if fitness_batch_size is None or (type(fitness_batch_size) in pygad.GA.supported_int_types and fitness_batch_size == 1): + if multi_objective == True: + fitness_func = fitness_func_no_batch_multi + else: + fitness_func = fitness_func_no_batch_single + elif (type(fitness_batch_size) in pygad.GA.supported_int_types and fitness_batch_size > 1): + if multi_objective == True: + fitness_func = fitness_func_batch_multi + else: + fitness_func = fitness_func_batch_single + ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=5, fitness_func=fitness_func, @@ -49,11 +67,13 @@ def fitness_func_batch(ga, soluions, idxs): initial_population=initial_population, init_range_low=init_range_low, init_range_high=init_range_high, + parent_selection_type=parent_selection_type, random_mutation_min_val=random_mutation_min_val, random_mutation_max_val=random_mutation_max_val, allow_duplicate_genes=True, mutation_by_replacement=mutation_by_replacement, save_solutions=True, + mutation_num_genes=mutation_num_genes, mutation_probability=mutation_probability, mutation_type=mutation_type, suppress_warnings=True, @@ -64,28 +84,58 @@ def fitness_func_batch(ga, soluions, idxs): return None, ga_instance -def test_adaptive_mutation(): - result, ga_instance = output_adaptive_mutation() +def test_adaptive_mutation(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_gene_space(): - result, ga_instance = output_adaptive_mutation(gene_space=range(10)) +def test_adaptive_mutation_gene_space(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(gene_space=range(10), + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_int_gene_type(): - result, ga_instance = output_adaptive_mutation(gene_type=int) +def test_adaptive_mutation_int_gene_type(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(gene_type=int, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_gene_space_gene_type(): +def test_adaptive_mutation_gene_space_gene_type(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): result, ga_instance = output_adaptive_mutation(gene_space={"low": 0, "high": 10}, - gene_type=[float, 2]) + gene_type=[float, 2], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_nested_gene_space(): +def test_adaptive_mutation_nested_gene_space(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): result, ga_instance = output_adaptive_mutation(gene_space=[[0, 1, 2, 3, 4], numpy.arange(5, 10), range(10, 15), @@ -95,15 +145,29 @@ def test_adaptive_mutation_nested_gene_space(): numpy.arange(30, 35), numpy.arange(35, 40), numpy.arange(40, 45), - [45, 46, 47, 48, 49]]) + [45, 46, 47, 48, 49]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_nested_gene_type(): - result, ga_instance = output_adaptive_mutation(gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) +def test_adaptive_mutation_nested_gene_type(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_nested_gene_space_nested_gene_type(): +def test_adaptive_mutation_nested_gene_space_nested_gene_type(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): result, ga_instance = output_adaptive_mutation(gene_space=[[0, 1, 2, 3, 4], numpy.arange(5, 10), range(10, 15), @@ -114,109 +178,606 @@ def test_adaptive_mutation_nested_gene_space_nested_gene_type(): numpy.arange(35, 40), numpy.arange(40, 45), [45, 46, 47, 48, 49]], - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_initial_population(): +def test_adaptive_mutation_initial_population(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): global initial_population - result, ga_instance = output_adaptive_mutation(initial_population=initial_population) + result, ga_instance = output_adaptive_mutation(initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_initial_population_nested_gene_type(): +def test_adaptive_mutation_initial_population_nested_gene_type(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): global initial_population result, ga_instance = output_adaptive_mutation(initial_population=initial_population, - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) # assert result == True -def test_adaptive_mutation_fitness_batch_size_1(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=1) +def test_adaptive_mutation_fitness_batch_size_1(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=1, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_2(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=2, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_3(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=3, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_4(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=4, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_5(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=5, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_6(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=6, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_7(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=7, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_8(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=8, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_9(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=9, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +def test_adaptive_mutation_fitness_batch_size_10(multi_objective=False, + parent_selection_type='sss', + mutation_num_genes=None, + mutation_probability=None): + result, ga_instance = output_adaptive_mutation(fitness_batch_size=10, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective, + mutation_num_genes=mutation_num_genes, + mutation_probability=mutation_probability) + +if __name__ == "__main__": + #### Single-objective mutation_probability + print() + test_adaptive_mutation(mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_int_gene_type(mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_gene_space(mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_gene_space_gene_type(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_2(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=2) + test_adaptive_mutation_nested_gene_space(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_3(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=3) + test_adaptive_mutation_nested_gene_type(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_4(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=4) + test_adaptive_mutation_initial_population(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_5(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=5) + test_adaptive_mutation_initial_population_nested_gene_type(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_6(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=6) + test_adaptive_mutation_fitness_batch_size_1(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_7(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=7) + test_adaptive_mutation_fitness_batch_size_1(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_8(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=8) + test_adaptive_mutation_fitness_batch_size_2(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_9(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=9) + test_adaptive_mutation_fitness_batch_size_3(mutation_probability=[0.2, 0.1]) + print() -def test_adaptive_mutation_fitness_batch_size_10(): - result, ga_instance = output_adaptive_mutation(fitness_batch_size=10) + test_adaptive_mutation_fitness_batch_size_4(mutation_probability=[0.2, 0.1]) + print() -if __name__ == "__main__": + test_adaptive_mutation_fitness_batch_size_5(mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_6(mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_7(mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_8(mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_9(mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_10(mutation_probability=[0.2, 0.1]) + print() + + #### Single-objective mutation_num_genes + print() + test_adaptive_mutation(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_int_gene_type(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_gene_space(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_gene_space_gene_type(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_nested_gene_space(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_nested_gene_type(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_initial_population(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_initial_population_nested_gene_type(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_1(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_1(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_2(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_3(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_4(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_5(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_6(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_7(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_8(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_9(mutation_num_genes=[6, 3]) + print() + + test_adaptive_mutation_fitness_batch_size_10(mutation_num_genes=[6, 3]) + print() + + #### Multi-objective mutation_probability + print() + test_adaptive_mutation(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_int_gene_type(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_gene_space(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_gene_space_gene_type(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_nested_gene_space(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_nested_gene_type(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_initial_population(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_initial_population_nested_gene_type(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_1(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_1(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_2(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_3(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_4(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_5(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_6(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_7(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_8(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_9(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_10(multi_objective=True, + mutation_probability=[0.2, 0.1]) + print() + + #### Multi-objective mutation_num_genes + test_adaptive_mutation(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_int_gene_type(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_gene_space(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_gene_space_gene_type(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_nested_gene_space(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_nested_gene_type(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_initial_population(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_initial_population_nested_gene_type(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_1(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_1(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_2(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_3(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_4(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_5(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_6(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_7(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_8(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_9(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + test_adaptive_mutation_fitness_batch_size_10(multi_objective=True, + mutation_num_genes=[6, 4]) + print() + + + #### Multi-objective NSGA-II Parent Selection mutation_probability + print() + test_adaptive_mutation(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_int_gene_type(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_gene_space(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_gene_space_gene_type(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_nested_gene_space(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_initial_population(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_initial_population_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_1(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_1(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_2(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_3(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_4(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_5(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_6(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_7(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_8(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_9(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + print() + + test_adaptive_mutation_fitness_batch_size_10(multi_objective=True, + parent_selection_type='nsga2', + mutation_probability=[0.2, 0.1]) + + #### Multi-objective NSGA-II Parent Selection mutation_num_genes print() - test_adaptive_mutation() + test_adaptive_mutation(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_int_gene_type() + test_adaptive_mutation_int_gene_type(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_gene_space() + test_adaptive_mutation_gene_space(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_gene_space_gene_type() + test_adaptive_mutation_gene_space_gene_type(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_nested_gene_space() + test_adaptive_mutation_nested_gene_space(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_nested_gene_type() + test_adaptive_mutation_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_initial_population() + test_adaptive_mutation_initial_population(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_initial_population_nested_gene_type() + test_adaptive_mutation_initial_population_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_1() + test_adaptive_mutation_fitness_batch_size_1(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_1() + test_adaptive_mutation_fitness_batch_size_1(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_2() + test_adaptive_mutation_fitness_batch_size_2(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_3() + test_adaptive_mutation_fitness_batch_size_3(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_4() + test_adaptive_mutation_fitness_batch_size_4(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_5() + test_adaptive_mutation_fitness_batch_size_5(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_6() + test_adaptive_mutation_fitness_batch_size_6(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_7() + test_adaptive_mutation_fitness_batch_size_7(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_8() + test_adaptive_mutation_fitness_batch_size_8(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_9() + test_adaptive_mutation_fitness_batch_size_9(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() - test_adaptive_mutation_fitness_batch_size_10() + test_adaptive_mutation_fitness_batch_size_10(multi_objective=True, + parent_selection_type='nsga2', + mutation_num_genes=[6, 4]) print() diff --git a/tests/test_allow_duplicate_genes.py b/tests/test_allow_duplicate_genes.py index f485419..27bdb29 100644 --- a/tests/test_allow_duplicate_genes.py +++ b/tests/test_allow_duplicate_genes.py @@ -24,11 +24,21 @@ def number_duplicate_genes(gene_space=None, init_range_low=-4, init_range_high=4, random_seed=123, - initial_population=None): + initial_population=None, + parent_selection_type='sss', + multi_objective=False): - def fitness_func(ga, solution, idx): + def fitness_func_no_batch_single(ga, solution, idx): return random.random() + def fitness_func_no_batch_multi(ga, solution, idx): + return [random.random(), random.random()] + + if multi_objective == True: + fitness_func = fitness_func_no_batch_multi + else: + fitness_func = fitness_func_no_batch_single + ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=5, fitness_func=fitness_func, @@ -37,6 +47,7 @@ def fitness_func(ga, solution, idx): gene_space=gene_space, gene_type=gene_type, initial_population=initial_population, + parent_selection_type=parent_selection_type, init_range_low=init_range_low, init_range_high=init_range_high, random_mutation_min_val=random_mutation_min_val, @@ -64,23 +75,30 @@ def test_number_duplicates_default(): assert num_duplicates == 0 -def test_number_duplicates_default_initial_population(): - num_duplicates = number_duplicate_genes(initial_population=initial_population) +def test_number_duplicates_default_initial_population(multi_objective=False, + parent_selection_type='sss'): + num_duplicates = number_duplicate_genes(initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_float_gene_type(): +def test_number_duplicates_float_gene_type(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 num_duplicates = number_duplicate_genes(gene_type=float, num_genes=num_genes, init_range_low=0, init_range_high=1, random_mutation_min_val=0, - random_mutation_max_val=1) + random_mutation_max_val=1, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_float_gene_type_initial_population(): +def test_number_duplicates_float_gene_type_initial_population(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 num_duplicates = number_duplicate_genes(gene_type=float, num_genes=num_genes, @@ -88,11 +106,14 @@ def test_number_duplicates_float_gene_type_initial_population(): init_range_high=1, initial_population=initial_population, random_mutation_min_val=0, - random_mutation_max_val=1) + random_mutation_max_val=1, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_int_gene_type(): +def test_number_duplicates_int_gene_type(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 init_range_low = 0 init_range_high = init_range_low + num_genes @@ -104,11 +125,14 @@ def test_number_duplicates_int_gene_type(): init_range_low=init_range_low, init_range_high=init_range_high, random_mutation_min_val=random_mutation_min_val, - random_mutation_max_val=random_mutation_max_val) + random_mutation_max_val=random_mutation_max_val, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_int_gene_type_initial_population(): +def test_number_duplicates_int_gene_type_initial_population(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 init_range_low = 0 init_range_high = init_range_low + num_genes @@ -121,11 +145,14 @@ def test_number_duplicates_int_gene_type_initial_population(): init_range_high=init_range_high, initial_population=initial_population, random_mutation_min_val=random_mutation_min_val, - random_mutation_max_val=random_mutation_max_val) + random_mutation_max_val=random_mutation_max_val, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_int_gene_type_replacement(): +def test_number_duplicates_int_gene_type_replacement(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 init_range_low = 0 init_range_high = init_range_low + num_genes @@ -137,11 +164,14 @@ def test_number_duplicates_int_gene_type_replacement(): init_range_low=init_range_low, init_range_high=init_range_high, random_mutation_min_val=random_mutation_min_val, - random_mutation_max_val=random_mutation_max_val) + random_mutation_max_val=random_mutation_max_val, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_int_gene_type_replacement_initial_population(): +def test_number_duplicates_int_gene_type_replacement_initial_population(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 init_range_low = 0 init_range_high = init_range_low + num_genes @@ -154,54 +184,75 @@ def test_number_duplicates_int_gene_type_replacement_initial_population(): init_range_high=init_range_high, initial_population=initial_population, random_mutation_min_val=random_mutation_min_val, - random_mutation_max_val=random_mutation_max_val) + random_mutation_max_val=random_mutation_max_val, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_single_gene_space(): +def test_number_duplicates_single_gene_space(multi_objective=False, + parent_selection_type='sss'): num_duplicates = number_duplicate_genes(gene_space=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - num_genes=10) + num_genes=10, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_single_gene_space_initial_population(): +def test_number_duplicates_single_gene_space_initial_population(multi_objective=False, + parent_selection_type='sss'): num_duplicates = number_duplicate_genes(gene_space=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], num_genes=10, - initial_population=initial_population) + initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_single_range_gene_space(): +def test_number_duplicates_single_range_gene_space(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 num_duplicates = number_duplicate_genes(gene_space=range(num_genes), - num_genes=num_genes) + num_genes=num_genes, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_single_range_gene_space_initial_population(): +def test_number_duplicates_single_range_gene_space_initial_population(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 num_duplicates = number_duplicate_genes(gene_space=range(num_genes), num_genes=num_genes, - initial_population=initial_population) + initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_single_numpy_range_gene_space(): +def test_number_duplicates_single_numpy_range_gene_space(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 num_duplicates = number_duplicate_genes(gene_space=numpy.arange(num_genes), - num_genes=num_genes) + num_genes=num_genes, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_single_numpy_range_gene_space_initial_population(): +def test_number_duplicates_single_numpy_range_gene_space_initial_population(multi_objective=False, + parent_selection_type='sss'): num_genes = 10 num_duplicates = number_duplicate_genes(gene_space=numpy.arange(num_genes), num_genes=num_genes, - initial_population=initial_population) + initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_nested_gene_space(): +def test_number_duplicates_nested_gene_space(multi_objective=False, + parent_selection_type='sss'): num_duplicates = number_duplicate_genes(gene_space=[[0, 1], [1, 2], [2, 3], @@ -213,11 +264,14 @@ def test_number_duplicates_nested_gene_space(): [8, 9], [9, 10]], gene_type=int, - num_genes=10) + num_genes=10, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 -def test_number_duplicates_nested_gene_space_initial_population(): +def test_number_duplicates_nested_gene_space_initial_population(multi_objective=False, + parent_selection_type='sss'): num_duplicates = number_duplicate_genes(gene_space=[[0, 1], [1, 2], [2, 3], @@ -230,7 +284,9 @@ def test_number_duplicates_nested_gene_space_initial_population(): [9, 10]], gene_type=int, num_genes=10, - initial_population=initial_population) + initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 @@ -274,7 +330,8 @@ def test_number_duplicates_nested_gene_space_initial_population(): # assert num_duplicates == 0 -def test_number_duplicates_nested_gene_space_nested_gene_type_initial_population(): +def test_number_duplicates_nested_gene_space_nested_gene_type_initial_population(multi_objective=False, + parent_selection_type='sss'): num_duplicates = number_duplicate_genes(gene_space=[[0, 1], [1, 2], [2, 3], @@ -287,11 +344,14 @@ def test_number_duplicates_nested_gene_space_nested_gene_type_initial_population [9, 10]], gene_type=[int, int, int, int, int, int, int, int, int, int], num_genes=10, - initial_population=initial_population) + initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_duplicates == 0 if __name__ == "__main__": + #### Single-objective print() test_number_duplicates_default() print() @@ -339,3 +399,112 @@ def test_number_duplicates_nested_gene_space_nested_gene_type_initial_population test_number_duplicates_nested_gene_space_nested_gene_type_initial_population() print() + #### Multi-objective + print() + test_number_duplicates_default_initial_population(multi_objective=True) + print() + + test_number_duplicates_float_gene_type(multi_objective=True) + print() + test_number_duplicates_float_gene_type_initial_population(multi_objective=True) + print() + + test_number_duplicates_int_gene_type(multi_objective=True) + print() + test_number_duplicates_int_gene_type_initial_population(multi_objective=True) + print() + + test_number_duplicates_int_gene_type_replacement(multi_objective=True) + print() + test_number_duplicates_int_gene_type_replacement_initial_population(multi_objective=True) + print() + + test_number_duplicates_single_gene_space(multi_objective=True) + print() + test_number_duplicates_single_gene_space_initial_population(multi_objective=True) + print() + + test_number_duplicates_single_range_gene_space(multi_objective=True) + print() + test_number_duplicates_single_range_gene_space_initial_population(multi_objective=True) + print() + + test_number_duplicates_single_numpy_range_gene_space(multi_objective=True) + print() + test_number_duplicates_single_numpy_range_gene_space_initial_population(multi_objective=True) + print() + + test_number_duplicates_nested_gene_space(multi_objective=True) + print() + test_number_duplicates_nested_gene_space_initial_population(multi_objective=True) + print() + + # This example causes duplicates that can only be solved by changing a chain of genes. + # test_number_duplicates_nested_gene_space_nested_gene_type(multi_objective=True) + # print() + test_number_duplicates_nested_gene_space_nested_gene_type_initial_population(multi_objective=True) + print() + + #### Multi-objective NSGA-II Parent Selection + print() + test_number_duplicates_default_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_number_duplicates_float_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_duplicates_float_gene_type_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_number_duplicates_int_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_duplicates_int_gene_type_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_number_duplicates_int_gene_type_replacement(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_duplicates_int_gene_type_replacement_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_number_duplicates_single_gene_space(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_duplicates_single_gene_space_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_number_duplicates_single_range_gene_space(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_duplicates_single_range_gene_space_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_number_duplicates_single_numpy_range_gene_space(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_duplicates_single_numpy_range_gene_space_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_number_duplicates_nested_gene_space(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_duplicates_nested_gene_space_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + # This example causes duplicates that can only be solved by changing a chain of genes. + # test_number_duplicates_nested_gene_space_nested_gene_type(multi_objective=True, + # parent_selection_type='nsga2') + # print() + test_number_duplicates_nested_gene_space_nested_gene_type_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + diff --git a/tests/test_crossover_mutation.py b/tests/test_crossover_mutation.py index 6b964c2..a11d65c 100644 --- a/tests/test_crossover_mutation.py +++ b/tests/test_crossover_mutation.py @@ -27,11 +27,21 @@ def output_crossover_mutation(gene_space=None, crossover_probability=None, mutation_probability=None, crossover_type=None, - mutation_type=None): + mutation_type=None, + parent_selection_type='sss', + multi_objective=False): - def fitness_func(ga, solution, idx): + def fitness_func_no_batch_single(ga, solution, idx): return random.random() + def fitness_func_no_batch_multi(ga, solution, idx): + return [random.random(), random.random()] + + if multi_objective == True: + fitness_func = fitness_func_no_batch_multi + else: + fitness_func = fitness_func_no_batch_single + ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=5, fitness_func=fitness_func, @@ -39,6 +49,7 @@ def fitness_func(ga, solution, idx): num_genes=num_genes, gene_space=gene_space, gene_type=gene_type, + parent_selection_type=parent_selection_type, initial_population=initial_population, init_range_low=init_range_low, init_range_high=init_range_high, @@ -69,30 +80,42 @@ def fitness_func(ga, solution, idx): print(f"Comparison result is {result}") return result, ga_instance -def test_no_crossover_no_mutation(): - result, ga_instance = output_crossover_mutation() +def test_no_crossover_no_mutation(multi_objective=False, + parent_selection_type='sss'): + result, ga_instance = output_crossover_mutation(parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_no_crossover_no_mutation_gene_space(): - result, ga_instance = output_crossover_mutation(gene_space=range(10)) +def test_no_crossover_no_mutation_gene_space(multi_objective=False, + parent_selection_type='sss'): + result, ga_instance = output_crossover_mutation(gene_space=range(10), + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_no_crossover_no_mutation_int_gene_type(): - result, ga_instance = output_crossover_mutation(gene_type=int) +def test_no_crossover_no_mutation_int_gene_type(multi_objective=False, + parent_selection_type='sss'): + result, ga_instance = output_crossover_mutation(gene_type=int, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_no_crossover_no_mutation_gene_space_gene_type(): +def test_no_crossover_no_mutation_gene_space_gene_type(multi_objective=False, + parent_selection_type='sss'): result, ga_instance = output_crossover_mutation(gene_space={"low": 0, "high": 10}, - gene_type=[float, 2]) + gene_type=[float, 2], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_no_crossover_no_mutation_nested_gene_space(): +def test_no_crossover_no_mutation_nested_gene_space(multi_objective=False, + parent_selection_type='sss'): result, ga_instance = output_crossover_mutation(gene_space=[[0, 1, 2, 3, 4], numpy.arange(5, 10), range(10, 15), @@ -102,15 +125,21 @@ def test_no_crossover_no_mutation_nested_gene_space(): numpy.arange(30, 35), numpy.arange(35, 40), numpy.arange(40, 45), - [45, 46, 47, 48, 49]]) + [45, 46, 47, 48, 49]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_no_crossover_no_mutation_nested_gene_type(): - result, ga_instance = output_crossover_mutation(gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) +def test_no_crossover_no_mutation_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): + result, ga_instance = output_crossover_mutation(gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_no_crossover_no_mutation_nested_gene_space_nested_gene_type(): +def test_no_crossover_no_mutation_nested_gene_space_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): result, ga_instance = output_crossover_mutation(gene_space=[[0, 1, 2, 3, 4], numpy.arange(5, 10), range(10, 15), @@ -121,43 +150,60 @@ def test_no_crossover_no_mutation_nested_gene_space_nested_gene_type(): numpy.arange(35, 40), numpy.arange(40, 45), [45, 46, 47, 48, 49]], - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_no_crossover_no_mutation_initial_population(): +def test_no_crossover_no_mutation_initial_population(multi_objective=False, + parent_selection_type='sss'): global initial_population - result, ga_instance = output_crossover_mutation(initial_population=initial_population) + result, ga_instance = output_crossover_mutation(initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_no_crossover_no_mutation_initial_population_nested_gene_type(): +def test_no_crossover_no_mutation_initial_population_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): global initial_population result, ga_instance = output_crossover_mutation(initial_population=initial_population, - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_crossover_no_mutation_zero_crossover_probability(): +def test_crossover_no_mutation_zero_crossover_probability(multi_objective=False, + parent_selection_type='sss'): global initial_population result, ga_instance = output_crossover_mutation(crossover_type="single_point", - crossover_probability=0.0) + crossover_probability=0.0, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_zero_crossover_probability_zero_mutation_probability(): +def test_zero_crossover_probability_zero_mutation_probability(multi_objective=False, + parent_selection_type='sss'): global initial_population result, ga_instance = output_crossover_mutation(crossover_type="single_point", crossover_probability=0.0, mutation_type="random", - mutation_probability=0.0) + mutation_probability=0.0, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert result == True -def test_random_mutation_manual_call(): +def test_random_mutation_manual_call(multi_objective=False, + parent_selection_type='sss'): result, ga_instance = output_crossover_mutation(mutation_type="random", random_mutation_min_val=888, - random_mutation_max_val=999) + random_mutation_max_val=999, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) ga_instance.mutation_num_genes = 9 temp_offspring = numpy.array(initial_population[0:1]) @@ -171,10 +217,13 @@ def test_random_mutation_manual_call(): assert len(comp_sorted) in range(1, 1 + 1 + ga_instance.mutation_num_genes) assert comp_sorted[0] == 0 -def test_random_mutation_manual_call2(): +def test_random_mutation_manual_call2(multi_objective=False, + parent_selection_type='sss'): result, ga_instance = output_crossover_mutation(mutation_type="random", random_mutation_min_val=888, - random_mutation_max_val=999) + random_mutation_max_val=999, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) ga_instance.mutation_num_genes = 10 temp_offspring = numpy.array(initial_population[0:1]) @@ -188,14 +237,17 @@ def test_random_mutation_manual_call2(): assert len(comp_sorted) in range(1, 1 + 1 + ga_instance.mutation_num_genes) # assert comp_sorted[0] == 0 -def test_random_mutation_manual_call3(): +def test_random_mutation_manual_call3(multi_objective=False, + parent_selection_type='sss'): # Use random_mutation_min_val & random_mutation_max_val as numbers. random_mutation_min_val = 888 random_mutation_max_val = 999 result, ga_instance = output_crossover_mutation(mutation_type="random", random_mutation_min_val=random_mutation_min_val, random_mutation_max_val=random_mutation_max_val, - mutation_by_replacement=True) + mutation_by_replacement=True, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) ga_instance.mutation_num_genes = 10 temp_offspring = numpy.array(initial_population[0:1]) @@ -209,14 +261,17 @@ def test_random_mutation_manual_call3(): for value in comp_sorted: assert value in value_space -def test_random_mutation_manual_call4(): +def test_random_mutation_manual_call4(multi_objective=False, + parent_selection_type='sss'): # Use random_mutation_min_val & random_mutation_max_val as lists. random_mutation_min_val = [888]*10 random_mutation_max_val = [999]*10 result, ga_instance = output_crossover_mutation(mutation_type="random", random_mutation_min_val=random_mutation_min_val, random_mutation_max_val=random_mutation_max_val, - mutation_by_replacement=True) + mutation_by_replacement=True, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) ga_instance.mutation_num_genes = 10 temp_offspring = numpy.array(initial_population[0:1]) @@ -231,6 +286,7 @@ def test_random_mutation_manual_call4(): assert value in value_space if __name__ == "__main__": + #### Single-objective print() test_no_crossover_no_mutation() print() @@ -274,3 +330,106 @@ def test_random_mutation_manual_call4(): test_random_mutation_manual_call4() print() + #### Multi-objective + print() + test_no_crossover_no_mutation(multi_objective=True) + print() + + test_no_crossover_no_mutation_int_gene_type(multi_objective=True) + print() + + test_no_crossover_no_mutation_gene_space(multi_objective=True) + print() + + test_no_crossover_no_mutation_gene_space_gene_type(multi_objective=True) + print() + + test_no_crossover_no_mutation_nested_gene_space(multi_objective=True) + print() + + test_no_crossover_no_mutation_nested_gene_type(multi_objective=True) + print() + + test_no_crossover_no_mutation_initial_population(multi_objective=True) + print() + + test_no_crossover_no_mutation_initial_population_nested_gene_type(multi_objective=True) + print() + + test_crossover_no_mutation_zero_crossover_probability(multi_objective=True) + print() + + test_zero_crossover_probability_zero_mutation_probability(multi_objective=True) + print() + + test_random_mutation_manual_call(multi_objective=True) + print() + + test_random_mutation_manual_call2(multi_objective=True) + print() + + test_random_mutation_manual_call3(multi_objective=True) + print() + + test_random_mutation_manual_call4(multi_objective=True) + print() + + + #### Multi-objective NSGA-II Parent Selection + print() + test_no_crossover_no_mutation(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_no_crossover_no_mutation_int_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_no_crossover_no_mutation_gene_space(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_no_crossover_no_mutation_gene_space_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_no_crossover_no_mutation_nested_gene_space(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_no_crossover_no_mutation_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_no_crossover_no_mutation_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_no_crossover_no_mutation_initial_population_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_crossover_no_mutation_zero_crossover_probability(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_zero_crossover_probability_zero_mutation_probability(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_random_mutation_manual_call(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_random_mutation_manual_call2(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_random_mutation_manual_call3(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_random_mutation_manual_call4(multi_objective=True, + parent_selection_type='nsga2') + print() + diff --git a/tests/test_gene_space.py b/tests/test_gene_space.py index c85a4e6..3691a14 100644 --- a/tests/test_gene_space.py +++ b/tests/test_gene_space.py @@ -32,11 +32,22 @@ def number_respect_gene_space(gene_space=None, init_range_high=4, mutation_type="random", mutation_percent_genes="default", - initial_population=None): + mutation_probability=None, + initial_population=None, + parent_selection_type='sss', + multi_objective=False): - def fitness_func(ga, solution, idx): + def fitness_func_no_batch_single(ga, solution, idx): return random.random() + def fitness_func_no_batch_multi(ga, solution, idx): + return [random.random(), random.random()] + + if multi_objective == True: + fitness_func = fitness_func_no_batch_multi + else: + fitness_func = fitness_func_no_batch_single + ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=5, fitness_func=fitness_func, @@ -51,9 +62,11 @@ def fitness_func(ga, solution, idx): random_mutation_max_val=random_mutation_max_val, allow_duplicate_genes=True, mutation_by_replacement=mutation_by_replacement, + parent_selection_type=parent_selection_type, save_solutions=True, mutation_type=mutation_type, mutation_percent_genes=mutation_percent_genes, + mutation_probability=mutation_probability, suppress_warnings=True, random_seed=2) @@ -191,95 +204,141 @@ def fitness_func(ga, solution, idx): print(f"Number of outside range is {num_outside}.") return num_outside, ga_instance -def test_gene_space_range(): - num_outside, _ = number_respect_gene_space(gene_space=range(10)) +def test_gene_space_range(multi_objective=False, + parent_selection_type='sss'): + num_outside, _ = number_respect_gene_space(gene_space=range(10), + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_numpy_arange(): - num_outside, _ = number_respect_gene_space(gene_space=numpy.arange(10)) - +def test_gene_space_numpy_arange(multi_objective=False, + parent_selection_type='sss'): + num_outside, _ = number_respect_gene_space(gene_space=numpy.arange(10), + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) + assert num_outside == 0 -def test_gene_space_list(): - num_outside, _ = number_respect_gene_space(gene_space=list(range(10))) +def test_gene_space_list(multi_objective=False, + parent_selection_type='sss'): + num_outside, _ = number_respect_gene_space(gene_space=list(range(10)), + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_list_None(): - num_outside, _ = number_respect_gene_space(gene_space=[30, None, 40, 50, None, 60, 70, None, None, None]) +def test_gene_space_list_None(multi_objective=False, + parent_selection_type='sss'): + num_outside, _ = number_respect_gene_space(gene_space=[30, None, 40, 50, None, 60, 70, None, None, None], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_numpy(): - num_outside, _ = number_respect_gene_space(gene_space=numpy.array(list(range(10)))) +def test_gene_space_numpy(multi_objective=False, + parent_selection_type='sss'): + num_outside, _ = number_respect_gene_space(gene_space=numpy.array(list(range(10))), + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_dict_without_step(): - num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10}) +def test_gene_space_dict_without_step(multi_objective=False, + parent_selection_type='sss'): + num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10}, + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_gene_space_dict_with_step(): - num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10, "step": 2}) +def test_gene_space_dict_with_step(multi_objective=False, + parent_selection_type='sss'): + num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10, "step": 2}, + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_list_single_value(): - num_outside, ga_instance = number_respect_gene_space(gene_space=[5]) +def test_gene_space_list_single_value(multi_objective=False, + parent_selection_type='sss'): + num_outside, ga_instance = number_respect_gene_space(gene_space=[5], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_gene_space_range_nested_gene_type(): +def test_gene_space_range_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, _ = number_respect_gene_space(gene_space=range(10), - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_numpy_arange_nested_gene_type(): +def test_gene_space_numpy_arange_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, _ = number_respect_gene_space(gene_space=numpy.arange(10), - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_list_nested_gene_type(): +def test_gene_space_list_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, _ = number_respect_gene_space(gene_space=list(range(10)), - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_numpy_nested_gene_type(): +def test_gene_space_numpy_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, _ = number_respect_gene_space(gene_space=numpy.array(list(range(10))), - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_dict_without_step_nested_gene_type(): +def test_gene_space_dict_without_step_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10}, - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_gene_space_dict_with_step_nested_gene_type(): +def test_gene_space_dict_with_step_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10, "step": 2}, - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_gene_space_list_single_value_nested_gene_type(): +def test_gene_space_list_single_value_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[5], - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_range(): +def test_nested_gene_space_range(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[range(0, 10), range(10, 20), range(20, 30), @@ -289,12 +348,15 @@ def test_nested_gene_space_range(): range(60, 70), range(70, 80), range(80, 90), - range(90, 100)]) + range(90, 100)], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_dict_without_step(): +def test_nested_gene_space_dict_without_step(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[{"low": 0, "high": 10}, {"low": 10, "high": 20}, {"low": 20, "high": 30}, @@ -304,12 +366,15 @@ def test_nested_gene_space_dict_without_step(): {"low": 60, "high": 70}, {"low": 70, "high": 80}, {"low": 80, "high": 90}, - {"low": 90, "high": 100}]) + {"low": 90, "high": 100}], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_dict_without_step_float_gene_type(): +def test_nested_gene_space_dict_without_step_float_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[{"low": 0, "high": 10}, {"low": 10, "high": 20}, {"low": 20, "high": 30}, @@ -320,12 +385,15 @@ def test_nested_gene_space_dict_without_step_float_gene_type(): {"low": 70, "high": 80}, {"low": 80, "high": 90}, {"low": 90, "high": 100}], - gene_type=[float, 3]) + gene_type=[float, 3], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_dict_with_step(): +def test_nested_gene_space_dict_with_step(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[{"low": 0, "high": 10, "step": 1}, {"low": 10, "high": 20, "step": 1.5}, {"low": 20, "high": 30, "step": 2}, @@ -335,13 +403,16 @@ def test_nested_gene_space_dict_with_step(): {"low": 60, "high": 70, "step": 4}, {"low": 70, "high": 80, "step": 4.5}, {"low": 80, "high": 90, "step": 5}, - {"low": 90, "high": 100, "step": 5.5}]) + {"low": 90, "high": 100, "step": 5.5}], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_numpy_arange(): +def test_nested_gene_space_numpy_arange(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[numpy.arange(0, 10), numpy.arange(10, 20), numpy.arange(20, 30), @@ -351,12 +422,15 @@ def test_nested_gene_space_numpy_arange(): numpy.arange(60, 70), numpy.arange(70, 80), numpy.arange(80, 90), - numpy.arange(90, 100)]) + numpy.arange(90, 100)], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_list(): +def test_nested_gene_space_list(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [-10, 10, 20, 30, 40, 50, 60, 70, 80, 90], [-11, 11, 22, 33, 44, 55, 66, 77, 88, 99], @@ -366,12 +440,15 @@ def test_nested_gene_space_list(): [-10.5, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9], [-15, 15, 25, 35, 45, 55, 65, 75, 85, 95], [30, 31, 32, 33, 34, 35, 36, 37, 38, 39], - [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]]) + [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_list2(): +def test_nested_gene_space_list2(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1], [1, 2], [2, 3], @@ -381,11 +458,14 @@ def test_nested_gene_space_list2(): [6, 7], [7, 8], [8, 9], - [9, 10]]) + [9, 10]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_nested_gene_space_list3_None(): +def test_nested_gene_space_list3_None(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, None], [1, 2], [2, None], @@ -396,11 +476,14 @@ def test_nested_gene_space_list3_None(): [None, None], [8, 9], None], - mutation_by_replacement=True) + mutation_by_replacement=True, + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_nested_gene_space_list4_None_custom_mutation_range(): +def test_nested_gene_space_list4_None_custom_mutation_range(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, None], [1, 2], [2, None], @@ -413,11 +496,14 @@ def test_nested_gene_space_list4_None_custom_mutation_range(): None], random_mutation_min_val=20, random_mutation_max_val=40, - mutation_by_replacement=True) + mutation_by_replacement=True, + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_nested_gene_space_mix(): +def test_nested_gene_space_mix(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4], numpy.arange(5, 10), range(10, 15), @@ -429,11 +515,14 @@ def test_nested_gene_space_mix(): numpy.arange(40, 45), [45, 46, 47, 48, 49]], gene_type=int, - mutation_by_replacement=True) + mutation_by_replacement=True, + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) assert num_outside == 0 -def test_nested_gene_space_mix_nested_gene_type(): +def test_nested_gene_space_mix_nested_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4], numpy.arange(5, 10), range(10, 15), @@ -444,12 +533,15 @@ def test_nested_gene_space_mix_nested_gene_type(): numpy.arange(35, 40), numpy.arange(40, 45), [45, 46, 47, 48, 49]], - gene_type=[int, float, numpy.float64, [float, 3], int, numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], int, numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_mix_initial_population(): +def test_nested_gene_space_mix_initial_population(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], numpy.arange(0, 10), range(0, 10), @@ -461,12 +553,15 @@ def test_nested_gene_space_mix_initial_population(): {"low": 0, "high": 10}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], - initial_population=initial_population) + initial_population=initial_population, + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_mix_initial_population_single_gene_type(): +def test_nested_gene_space_mix_initial_population_single_gene_type(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], numpy.arange(0, 10), range(0, 10), @@ -477,13 +572,16 @@ def test_nested_gene_space_mix_initial_population_single_gene_type(): numpy.arange(0, 10), {"low": 0, "high": 10}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], - gene_type=[float, 2], - initial_population=initial_population) + gene_type=[float, 4], + initial_population=initial_population, + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_single_gene_type_adaptive_mutation(): +def test_nested_gene_space_single_gene_type_adaptive_mutation(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], numpy.arange(0, 10), range(0, 10), @@ -497,12 +595,37 @@ def test_nested_gene_space_single_gene_type_adaptive_mutation(): # Due to rounding the genes, a gene at index 4 will have a value of 10 (outside the dict range) if [float, 2] is used. gene_type=[float, 4], mutation_percent_genes=[70, 50], - mutation_type="adaptive") + mutation_type="adaptive", + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_nested_gene_type_adaptive_mutation(): +def test_nested_gene_space_single_gene_type_adaptive_mutation_probability(multi_objective=False, + parent_selection_type='sss'): + num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + numpy.arange(0, 10), + range(0, 10), + {"low": 0, "high": 10}, + {"low": 0, "high": 10}, + range(0, 10), + numpy.arange(0, 10), + numpy.arange(0, 10), + {"low": 0, "high": 10}, + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], + # Due to rounding the genes, a gene at index 4 will have a value of 10 (outside the dict range) if [float, 2] is used. + gene_type=[float, 4], + mutation_probability=[0.7, 0.5], + mutation_type="adaptive", + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) + # print(ga_instance.population) + + assert num_outside == 0 + +def test_nested_gene_space_nested_gene_type_adaptive_mutation(multi_objective=False, + parent_selection_type='sss'): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], numpy.arange(0, 10), range(0, 10), @@ -515,12 +638,36 @@ def test_nested_gene_space_nested_gene_type_adaptive_mutation(): [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], mutation_percent_genes=[70, 50], - mutation_type="adaptive") + mutation_type="adaptive", + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) + # print(ga_instance.population) + + assert num_outside == 0 + +def test_nested_gene_space_nested_gene_type_adaptive_mutation_probability(multi_objective=False, + parent_selection_type='sss'): + num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + numpy.arange(0, 10), + range(0, 10), + {"low": 0, "high": 10}, + {"low": 0, "high": 10}, + range(0, 10), + numpy.arange(0, 10), + numpy.arange(0, 10), + {"low": 0, "high": 10}, + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + mutation_probability=[0.7, 0.5], + mutation_type="adaptive", + multi_objective=multi_objective, + parent_selection_type=parent_selection_type) # print(ga_instance.population) assert num_outside == 0 if __name__ == "__main__": + #### Single-objective print() test_gene_space_range() print() @@ -600,6 +747,219 @@ def test_nested_gene_space_nested_gene_type_adaptive_mutation(): test_nested_gene_space_single_gene_type_adaptive_mutation() print() + test_nested_gene_space_single_gene_type_adaptive_mutation_probability() + print() test_nested_gene_space_nested_gene_type_adaptive_mutation() print() + test_nested_gene_space_nested_gene_type_adaptive_mutation_probability() + print() + + #### Multi-objective + print() + test_gene_space_range(multi_objective=True) + print() + test_gene_space_range_nested_gene_type(multi_objective=True) + print() + + test_gene_space_numpy_arange(multi_objective=True) + print() + test_gene_space_numpy_arange_nested_gene_type(multi_objective=True) + print() + + test_gene_space_list(multi_objective=True) + print() + test_gene_space_list_None(multi_objective=True) + print() + test_gene_space_list_nested_gene_type(multi_objective=True) + print() + + test_gene_space_list_single_value(multi_objective=True) + print() + test_gene_space_list_single_value_nested_gene_type(multi_objective=True) + print() + + test_gene_space_numpy(multi_objective=True) + print() + test_gene_space_numpy_nested_gene_type(multi_objective=True) + print() + + test_gene_space_dict_without_step(multi_objective=True) + print() + test_gene_space_dict_without_step_nested_gene_type(multi_objective=True) + print() + + test_gene_space_dict_with_step(multi_objective=True) + print() + test_gene_space_dict_with_step_nested_gene_type(multi_objective=True) + print() + + test_nested_gene_space_range(multi_objective=True) + print() + + test_nested_gene_space_dict_without_step(multi_objective=True) + print() + + test_nested_gene_space_dict_without_step_float_gene_type(multi_objective=True) + print() + + test_nested_gene_space_dict_with_step(multi_objective=True) + print() + + test_nested_gene_space_numpy_arange(multi_objective=True) + print() + + test_nested_gene_space_list(multi_objective=True) + print() + + test_nested_gene_space_list2(multi_objective=True) + print() + + test_nested_gene_space_list3_None(multi_objective=True) + print() + + test_nested_gene_space_list4_None_custom_mutation_range(multi_objective=True) + print() + + test_nested_gene_space_mix(multi_objective=True) + print() + + test_nested_gene_space_mix_nested_gene_type(multi_objective=True) + print() + + test_nested_gene_space_mix_initial_population(multi_objective=True) + print() + + test_nested_gene_space_mix_initial_population_single_gene_type(multi_objective=True) + print() + + test_nested_gene_space_single_gene_type_adaptive_mutation(multi_objective=True) + print() + test_nested_gene_space_single_gene_type_adaptive_mutation_probability(multi_objective=True) + print() + + test_nested_gene_space_nested_gene_type_adaptive_mutation(multi_objective=True) + print() + test_nested_gene_space_nested_gene_type_adaptive_mutation_probability(multi_objective=True) + print() + + + #### Multi-objective NSGA-II Parent Selection + print() + test_gene_space_range(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_range_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_numpy_arange(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_numpy_arange_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_list(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_list_None(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_list_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_list_single_value(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_list_single_value_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_numpy(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_numpy_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_dict_without_step(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_dict_without_step_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_dict_with_step(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_dict_with_step_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_range(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_dict_without_step(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_dict_without_step_float_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_dict_with_step(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_numpy_arange(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_list(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_list2(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_list3_None(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_list4_None_custom_mutation_range(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_mix(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_mix_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_mix_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_mix_initial_population_single_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_single_gene_type_adaptive_mutation(multi_objective=True, + parent_selection_type='nsga2') + print() + test_nested_gene_space_single_gene_type_adaptive_mutation_probability(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_nested_gene_type_adaptive_mutation(multi_objective=True, + parent_selection_type='nsga2') + print() + test_nested_gene_space_nested_gene_type_adaptive_mutation_probability(multi_objective=True, + parent_selection_type='nsga2') + print() diff --git a/tests/test_gene_space_allow_duplicate_genes.py b/tests/test_gene_space_allow_duplicate_genes.py index c2eff96..8b9cb42 100644 --- a/tests/test_gene_space_allow_duplicate_genes.py +++ b/tests/test_gene_space_allow_duplicate_genes.py @@ -30,15 +30,26 @@ def number_respect_gene_space(gene_space=None, random_mutation_max_val=1, init_range_low=-4, init_range_high=4, - initial_population=None): + initial_population=None, + parent_selection_type='sss', + multi_objective=False): - def fitness_func(ga, solution, idx): + def fitness_func_no_batch_single(ga, solution, idx): return random.random() + def fitness_func_no_batch_multi(ga, solution, idx): + return [random.random(), random.random()] + + if multi_objective == True: + fitness_func = fitness_func_no_batch_multi + else: + fitness_func = fitness_func_no_batch_single + ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=5, fitness_func=fitness_func, sol_per_pop=10, + parent_selection_type=parent_selection_type, num_genes=num_genes, gene_space=gene_space, gene_type=gene_type, @@ -124,90 +135,133 @@ def fitness_func(ga, solution, idx): print(f"Number of outside range is {num_outside}.") return num_outside, ga_instance -def test_gene_space_range(): - num_outside, _ = number_respect_gene_space(gene_space=range(10)) +def test_gene_space_range(parent_selection_type='sss', + multi_objective=False): + num_outside, _ = number_respect_gene_space(gene_space=range(10), + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_numpy_arange(): - num_outside, _ = number_respect_gene_space(gene_space=numpy.arange(10)) +def test_gene_space_numpy_arange(parent_selection_type='sss', + multi_objective=False): + num_outside, _ = number_respect_gene_space(gene_space=numpy.arange(10), + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_list(): - num_outside, _ = number_respect_gene_space(gene_space=list(range(10))) +def test_gene_space_list(parent_selection_type='sss', + multi_objective=False): + num_outside, _ = number_respect_gene_space(gene_space=list(range(10)), + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_numpy(): - num_outside, _ = number_respect_gene_space(gene_space=numpy.array(list(range(10)))) +def test_gene_space_numpy(parent_selection_type='sss', + multi_objective=False): + num_outside, _ = number_respect_gene_space(gene_space=numpy.array(list(range(10))), + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_dict_without_step(): - num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10}) +def test_gene_space_dict_without_step(parent_selection_type='sss', + multi_objective=False): + num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10}, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_gene_space_dict_with_step(): - num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10, "step": 2}) +def test_gene_space_dict_with_step(parent_selection_type='sss', + multi_objective=False): + num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10, "step": 2}, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_list_single_value(): - num_outside, ga_instance = number_respect_gene_space(gene_space=[5]) +def test_gene_space_list_single_value(parent_selection_type='sss', + multi_objective=False): + num_outside, ga_instance = number_respect_gene_space(gene_space=[5], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_gene_space_range_nested_gene_type(): +def test_gene_space_range_nested_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, _ = number_respect_gene_space(gene_space=range(10), - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_numpy_arange_nested_gene_type(): +def test_gene_space_numpy_arange_nested_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, _ = number_respect_gene_space(gene_space=numpy.arange(10), - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_list_nested_gene_type(): +def test_gene_space_list_nested_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, _ = number_respect_gene_space(gene_space=list(range(10)), - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_numpy_nested_gene_type(): +def test_gene_space_numpy_nested_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, _ = number_respect_gene_space(gene_space=numpy.array(list(range(10))), - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_dict_without_step_nested_gene_type(): +def test_gene_space_dict_without_step_nested_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10}, - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_gene_space_dict_with_step_nested_gene_type(): +def test_gene_space_dict_with_step_nested_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space={"low": 0, "high": 10, "step": 2}, - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_gene_space_list_single_value_nested_gene_type(): +def test_gene_space_list_single_value_nested_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[5], - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_range(): +def test_nested_gene_space_range(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[range(0, 10), range(10, 20), range(20, 30), @@ -217,12 +271,15 @@ def test_nested_gene_space_range(): range(60, 70), range(70, 80), range(80, 90), - range(90, 100)]) + range(90, 100)], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_dict_without_step(): +def test_nested_gene_space_dict_without_step(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[{"low": 0, "high": 10}, {"low": 10, "high": 20}, {"low": 20, "high": 30}, @@ -232,12 +289,15 @@ def test_nested_gene_space_dict_without_step(): {"low": 60, "high": 70}, {"low": 70, "high": 80}, {"low": 80, "high": 90}, - {"low": 90, "high": 100}]) + {"low": 90, "high": 100}], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_dict_without_step_float_gene_type(): +def test_nested_gene_space_dict_without_step_float_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[{"low": 0, "high": 10}, {"low": 10, "high": 20}, {"low": 20, "high": 30}, @@ -248,12 +308,15 @@ def test_nested_gene_space_dict_without_step_float_gene_type(): {"low": 70, "high": 80}, {"low": 80, "high": 90}, {"low": 90, "high": 100}], - gene_type=[float, 3]) + gene_type=[float, 3], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_dict_with_step(): +def test_nested_gene_space_dict_with_step(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[{"low": 0, "high": 10, "step": 1}, {"low": 10, "high": 20, "step": 1.5}, {"low": 20, "high": 30, "step": 2}, @@ -263,13 +326,16 @@ def test_nested_gene_space_dict_with_step(): {"low": 60, "high": 70, "step": 4}, {"low": 70, "high": 80, "step": 4.5}, {"low": 80, "high": 90, "step": 5}, - {"low": 90, "high": 100, "step": 5.5}]) + {"low": 90, "high": 100, "step": 5.5}], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_numpy_arange(): +def test_nested_gene_space_numpy_arange(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[numpy.arange(0, 10), numpy.arange(10, 20), numpy.arange(20, 30), @@ -279,12 +345,15 @@ def test_nested_gene_space_numpy_arange(): numpy.arange(60, 70), numpy.arange(70, 80), numpy.arange(80, 90), - numpy.arange(90, 100)]) + numpy.arange(90, 100)], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_list(): +def test_nested_gene_space_list(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [-10, 10, 20, 30, 40, 50, 60, 70, 80, 90], [-11, 11, 22, 33, 44, 55, 66, 77, 88, 99], @@ -294,12 +363,15 @@ def test_nested_gene_space_list(): [-10.5, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9], [-15, 15, 25, 35, 45, 55, 65, 75, 85, 95], [30, 31, 32, 33, 34, 35, 36, 37, 38, 39], - [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]]) + [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_list2(): +def test_nested_gene_space_list2(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1], [1, 2], [2, 3], @@ -309,11 +381,14 @@ def test_nested_gene_space_list2(): [6, 7], [7, 8], [8, 9], - [9, 10]]) + [9, 10]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_nested_gene_space_mix(): +def test_nested_gene_space_mix(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4], numpy.arange(5, 10), range(10, 15), @@ -324,11 +399,14 @@ def test_nested_gene_space_mix(): numpy.arange(35, 40), numpy.arange(40, 45), [45, 46, 47, 48, 49]], - gene_type=int) + gene_type=int, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert num_outside == 0 -def test_nested_gene_space_mix_nested_gene_type(): +def test_nested_gene_space_mix_nested_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4], numpy.arange(5, 10), range(10, 15), @@ -339,12 +417,15 @@ def test_nested_gene_space_mix_nested_gene_type(): numpy.arange(35, 40), numpy.arange(40, 45), [45, 46, 47, 48, 49]], - gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]]) + gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_mix_initial_population(): +def test_nested_gene_space_mix_initial_population(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], numpy.arange(0, 10), range(0, 10), @@ -356,12 +437,15 @@ def test_nested_gene_space_mix_initial_population(): {"low": 0, "high": 10}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]], - initial_population=initial_population) + initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 -def test_nested_gene_space_mix_initial_population_single_gene_type(): +def test_nested_gene_space_mix_initial_population_single_gene_type(parent_selection_type='sss', + multi_objective=False): num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], numpy.arange(0, 10), range(0, 10), @@ -372,13 +456,16 @@ def test_nested_gene_space_mix_initial_population_single_gene_type(): numpy.arange(0, 10), {"low": 0, "high": 10}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], - gene_type=[float, 2], - initial_population=initial_population) + gene_type=[float, 4], + initial_population=initial_population, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) # print(ga_instance.population) assert num_outside == 0 if __name__ == "__main__": + #### Single-objective print() test_gene_space_range() print() @@ -446,4 +533,174 @@ def test_nested_gene_space_mix_initial_population_single_gene_type(): print() test_nested_gene_space_mix_initial_population_single_gene_type() - print() \ No newline at end of file + print() + + + + #### Multi-objective + print() + test_gene_space_range(multi_objective=True) + print() + test_gene_space_range_nested_gene_type(multi_objective=True) + print() + + test_gene_space_numpy_arange(multi_objective=True) + print() + test_gene_space_numpy_arange_nested_gene_type(multi_objective=True) + print() + + test_gene_space_list(multi_objective=True) + print() + test_gene_space_list_nested_gene_type(multi_objective=True) + print() + + test_gene_space_list_single_value(multi_objective=True) + print() + test_gene_space_list_single_value_nested_gene_type(multi_objective=True) + print() + + test_gene_space_numpy(multi_objective=True) + print() + test_gene_space_numpy_nested_gene_type(multi_objective=True) + print() + + test_gene_space_dict_without_step(multi_objective=True) + print() + test_gene_space_dict_without_step_nested_gene_type(multi_objective=True) + print() + + test_gene_space_dict_with_step(multi_objective=True) + print() + test_gene_space_dict_with_step_nested_gene_type(multi_objective=True) + print() + + test_nested_gene_space_range(multi_objective=True) + print() + + test_nested_gene_space_dict_without_step(multi_objective=True) + print() + + test_nested_gene_space_dict_without_step_float_gene_type() + print() + + test_nested_gene_space_dict_with_step(multi_objective=True) + print() + + test_nested_gene_space_numpy_arange(multi_objective=True) + print() + + test_nested_gene_space_list(multi_objective=True) + print() + + test_nested_gene_space_list2(multi_objective=True) + print() + + test_nested_gene_space_mix(multi_objective=True) + print() + + test_nested_gene_space_mix_nested_gene_type(multi_objective=True) + print() + + test_nested_gene_space_mix_initial_population(multi_objective=True) + print() + + test_nested_gene_space_mix_initial_population_single_gene_type(multi_objective=True) + print() + + + #### Multi-objective NSGA-II Parent Selection + print() + test_gene_space_range(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_range_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_numpy_arange(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_numpy_arange_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_list(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_list_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_list_single_value(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_list_single_value_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_numpy(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_numpy_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_dict_without_step(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_dict_without_step_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_gene_space_dict_with_step(multi_objective=True, + parent_selection_type='nsga2') + print() + test_gene_space_dict_with_step_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_range(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_dict_without_step(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_dict_without_step_float_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_dict_with_step(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_numpy_arange(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_list(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_list2(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_mix(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_mix_nested_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_mix_initial_population(multi_objective=True, + parent_selection_type='nsga2') + print() + + test_nested_gene_space_mix_initial_population_single_gene_type(multi_objective=True, + parent_selection_type='nsga2') + print() + + diff --git a/tests/test_number_fitness_function_calls.py b/tests/test_number_fitness_function_calls.py index 4d03454..4968db1 100644 --- a/tests/test_number_fitness_function_calls.py +++ b/tests/test_number_fitness_function_calls.py @@ -14,20 +14,33 @@ def number_calls_fitness_function(keep_elitism=1, keep_parents=-1, mutation_type="random", - mutation_percent_genes="default"): + mutation_percent_genes="default", + parent_selection_type='sss', + multi_objective=False): actual_num_fitness_calls = 0 - def fitness_func(ga, solution, idx): + def fitness_func_no_batch_single(ga, solution, idx): nonlocal actual_num_fitness_calls actual_num_fitness_calls = actual_num_fitness_calls + 1 return 1 + def fitness_func_no_batch_multi(ga_instance, solution, solution_idx): + nonlocal actual_num_fitness_calls + actual_num_fitness_calls = actual_num_fitness_calls + 1 + return [1, 1] + + if multi_objective == True: + fitness_func = fitness_func_no_batch_multi + else: + fitness_func = fitness_func_no_batch_single + ga_optimizer = pygad.GA(num_generations=num_generations, sol_per_pop=sol_per_pop, num_genes=6, num_parents_mating=num_parents_mating, fitness_func=fitness_func, mutation_type=mutation_type, + parent_selection_type=parent_selection_type, mutation_percent_genes=mutation_percent_genes, keep_elitism=keep_elitism, keep_parents=keep_parents, @@ -64,46 +77,68 @@ def test_number_calls_fitness_function_default_keep(): actual, expected = number_calls_fitness_function() assert actual == expected -def test_number_calls_fitness_function_no_keep(): +def test_number_calls_fitness_function_no_keep(multi_objective=False, + parent_selection_type='sss'): actual, expected = number_calls_fitness_function(keep_elitism=0, - keep_parents=0) + keep_parents=0, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert actual == expected -def test_number_calls_fitness_function_keep_elitism(): +def test_number_calls_fitness_function_keep_elitism(multi_objective=False, + parent_selection_type='sss'): actual, expected = number_calls_fitness_function(keep_elitism=3, - keep_parents=0) + keep_parents=0, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert actual == expected -def test_number_calls_fitness_function_keep_parents(): +def test_number_calls_fitness_function_keep_parents(multi_objective=False, + parent_selection_type='sss'): actual, expected = number_calls_fitness_function(keep_elitism=0, - keep_parents=4) + keep_parents=4, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert actual == expected -def test_number_calls_fitness_function_both_keep(): +def test_number_calls_fitness_function_both_keep(multi_objective=False, + parent_selection_type='sss'): actual, expected = number_calls_fitness_function(keep_elitism=3, - keep_parents=4) + keep_parents=4, + parent_selection_type=parent_selection_type, + multi_objective=multi_objective) assert actual == expected -def test_number_calls_fitness_function_no_keep_adaptive_mutation(): +def test_number_calls_fitness_function_no_keep_adaptive_mutation(multi_objective=False, + parent_selection_type='sss'): actual, expected = number_calls_fitness_function(keep_elitism=0, keep_parents=0, + parent_selection_type=parent_selection_type, mutation_type="adaptive", - mutation_percent_genes=[10, 5]) + mutation_percent_genes=[10, 5], + multi_objective=multi_objective) assert actual == expected -def test_number_calls_fitness_function_default_adaptive_mutation(): +def test_number_calls_fitness_function_default_adaptive_mutation(multi_objective=False, + parent_selection_type='sss'): actual, expected = number_calls_fitness_function(mutation_type="adaptive", - mutation_percent_genes=[10, 5]) + parent_selection_type=parent_selection_type, + mutation_percent_genes=[10, 5], + multi_objective=multi_objective) assert actual == expected -def test_number_calls_fitness_function_both_keep_adaptive_mutation(): +def test_number_calls_fitness_function_both_keep_adaptive_mutation(multi_objective=False, + parent_selection_type='sss'): actual, expected = number_calls_fitness_function(keep_elitism=3, keep_parents=4, + parent_selection_type=parent_selection_type, mutation_type="adaptive", - mutation_percent_genes=[10, 5]) + mutation_percent_genes=[10, 5], + multi_objective=multi_objective) assert actual == expected if __name__ == "__main__": + #### Single-objective print() test_number_calls_fitness_function_default_keep() print() @@ -121,3 +156,45 @@ def test_number_calls_fitness_function_both_keep_adaptive_mutation(): print() test_number_calls_fitness_function_both_keep_adaptive_mutation() print() + + #### Multi-Objective + print() + test_number_calls_fitness_function_no_keep(multi_objective=True) + print() + test_number_calls_fitness_function_keep_elitism(multi_objective=True) + print() + test_number_calls_fitness_function_keep_parents(multi_objective=True) + print() + test_number_calls_fitness_function_both_keep(multi_objective=True) + print() + test_number_calls_fitness_function_no_keep_adaptive_mutation(multi_objective=True) + print() + test_number_calls_fitness_function_default_adaptive_mutation(multi_objective=True) + print() + test_number_calls_fitness_function_both_keep_adaptive_mutation(multi_objective=True) + print() + + #### Multi-Objective NSGA-II Parent Selection + print() + test_number_calls_fitness_function_no_keep(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_calls_fitness_function_keep_elitism(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_calls_fitness_function_keep_parents(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_calls_fitness_function_both_keep(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_calls_fitness_function_no_keep_adaptive_mutation(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_calls_fitness_function_default_adaptive_mutation(multi_objective=True, + parent_selection_type='nsga2') + print() + test_number_calls_fitness_function_both_keep_adaptive_mutation(multi_objective=True, + parent_selection_type='nsga2') + print() +