From 16a5382f3df84ceb493366abc40ec46dc43ec2dd Mon Sep 17 00:00:00 2001 From: xdchuan Date: Wed, 10 Dec 2025 20:59:29 +0800 Subject: [PATCH] CN.2490809444482816:5c70ddf1e43587bfb08fda72c103872c_693918d27137afff27d27f75.693919d97137afff27d27fc8.693919ca4ca80712cee5d9b6:Trae CN.T(2025/12/10 14:57:29) --- pygad/__init__.pyc | Bin 0 -> 237 bytes pygad/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 233 bytes pygad/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 219 bytes pygad/__pycache__/pygad.cpython-313.pyc | Bin 0 -> 93944 bytes pygad/__pycache__/pygad.cpython-39.pyc | Bin 0 -> 88302 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 287 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 274 bytes pygad/helper/__pycache__/misc.cpython-313.pyc | Bin 0 -> 22136 bytes pygad/helper/__pycache__/misc.cpython-39.pyc | Bin 0 -> 16742 bytes .../helper/__pycache__/unique.cpython-313.pyc | Bin 0 -> 20447 bytes .../helper/__pycache__/unique.cpython-39.pyc | Bin 0 -> 15190 bytes pygad/pygad.py | 619 ++++++++++++++---- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 361 bytes .../utils/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 346 bytes .../__pycache__/crossover.cpython-313.pyc | Bin 0 -> 11524 bytes .../__pycache__/crossover.cpython-39.pyc | Bin 0 -> 6163 bytes .../__pycache__/mutation.cpython-313.pyc | Bin 0 -> 30273 bytes .../utils/__pycache__/mutation.cpython-39.pyc | Bin 0 -> 17530 bytes pygad/utils/__pycache__/nsga2.cpython-313.pyc | Bin 0 -> 11798 bytes pygad/utils/__pycache__/nsga2.cpython-39.pyc | Bin 0 -> 8420 bytes .../parent_selection.cpython-313.pyc | Bin 0 -> 23632 bytes .../parent_selection.cpython-39.pyc | Bin 0 -> 15547 bytes pygad/utils/nsga2.py | 34 +- pygad/utils/parent_selection.py | 46 +- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 263 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 251 bytes .../__pycache__/plot.cpython-313.pyc | Bin 0 -> 22531 bytes .../visualize/__pycache__/plot.cpython-39.pyc | Bin 0 -> 13814 bytes test_multi_objective.py | 61 ++ ...ptive_mutation.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 71348 bytes ...uplicate_genes.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 15310 bytes .../test_crossover_mutation.cpython-313.pyc | Bin 0 -> 13268 bytes ...sover_mutation.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 11705 bytes ...ene_constraint.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 20700 bytes ...est_gene_space.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 48328 bytes ...uplicate_genes.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 36759 bytes ...test_gene_type.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 5657 bytes ...allbacks_calls.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 8634 bytes ...function_calls.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 23460 bytes ...save_solutions.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 79242 bytes ..._stop_criteria.cpython-39-pytest-6.2.5.pyc | Bin 0 -> 7129 bytes .../test_stop_criteria.cpython-39.pyc | Bin 0 -> 7020 bytes tests/test_crossover_mutation.py | 48 +- 43 files changed, 645 insertions(+), 163 deletions(-) create mode 100644 pygad/__init__.pyc create mode 100644 pygad/__pycache__/__init__.cpython-313.pyc create mode 100644 pygad/__pycache__/__init__.cpython-39.pyc create mode 100644 pygad/__pycache__/pygad.cpython-313.pyc create mode 100644 pygad/__pycache__/pygad.cpython-39.pyc create mode 100644 pygad/helper/__pycache__/__init__.cpython-313.pyc create mode 100644 pygad/helper/__pycache__/__init__.cpython-39.pyc create mode 100644 pygad/helper/__pycache__/misc.cpython-313.pyc create mode 100644 pygad/helper/__pycache__/misc.cpython-39.pyc create mode 100644 pygad/helper/__pycache__/unique.cpython-313.pyc create mode 100644 pygad/helper/__pycache__/unique.cpython-39.pyc create mode 100644 pygad/utils/__pycache__/__init__.cpython-313.pyc create mode 100644 pygad/utils/__pycache__/__init__.cpython-39.pyc create mode 100644 pygad/utils/__pycache__/crossover.cpython-313.pyc create mode 100644 pygad/utils/__pycache__/crossover.cpython-39.pyc create mode 100644 pygad/utils/__pycache__/mutation.cpython-313.pyc create mode 100644 pygad/utils/__pycache__/mutation.cpython-39.pyc create mode 100644 pygad/utils/__pycache__/nsga2.cpython-313.pyc create mode 100644 pygad/utils/__pycache__/nsga2.cpython-39.pyc create mode 100644 pygad/utils/__pycache__/parent_selection.cpython-313.pyc create mode 100644 pygad/utils/__pycache__/parent_selection.cpython-39.pyc create mode 100644 pygad/visualize/__pycache__/__init__.cpython-313.pyc create mode 100644 pygad/visualize/__pycache__/__init__.cpython-39.pyc create mode 100644 pygad/visualize/__pycache__/plot.cpython-313.pyc create mode 100644 pygad/visualize/__pycache__/plot.cpython-39.pyc create mode 100644 test_multi_objective.py create mode 100644 tests/__pycache__/test_adaptive_mutation.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_allow_duplicate_genes.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_crossover_mutation.cpython-313.pyc create mode 100644 tests/__pycache__/test_crossover_mutation.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_gene_constraint.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_gene_space.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_gene_space_allow_duplicate_genes.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_gene_type.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_lifecycle_callbacks_calls.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_number_fitness_function_calls.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_save_solutions.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_stop_criteria.cpython-39-pytest-6.2.5.pyc create mode 100644 tests/__pycache__/test_stop_criteria.cpython-39.pyc diff --git a/pygad/__init__.pyc b/pygad/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51dc8cea826a0e6be491e6d2b0a41f7807f768e6 GIT binary patch literal 237 zcmYL@!3x4K42HW+K_=cj_z1(pDu@R`L_zQ-f_m{1N?W$V){Zq3_gFrgFJLNyA^DO& zfh5U$lD=kZBiYYl$~y`_B`ETURg7I#%pDQh)W literal 0 HcmV?d00001 diff --git a/pygad/__pycache__/__init__.cpython-313.pyc b/pygad/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef33fca28b4fb9bdbf67163b1b5b5060873e0b87 GIT binary patch literal 233 zcmey&%ge<81REtRGwp%&V-N=hn4pZ$LO{k;hG2$ZMsEglCIyCIrXt34W=)otj6exZ z##@Y9RjkH(rg{c`noPG?3o6qSQ*Lp`$CsrR6=&w>#mBE?_zW`YR)BtJF;GmuA|+Yh zB|o_|H#M)MSU)APBvHSlC^0oYIWImj9Vn*no|>0hl9}w7lb&CcS(1?(P+5|ZpQjHt zSwB8LGcU6wK3=b&@)n0pZhlH>PO4oIC(r_rbBcL^#0O?ZM#eh~A`kdP8@Y?vfg%8i CqCS8C literal 0 HcmV?d00001 diff --git a/pygad/__pycache__/__init__.cpython-39.pyc b/pygad/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f4fef00ca6e776b7512e33789c45aa1168f617f GIT binary patch literal 219 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 S;f3{T9`z-~m{=mzv}Qlj07m)% literal 0 HcmV?d00001 diff --git a/pygad/helper/__pycache__/misc.cpython-313.pyc b/pygad/helper/__pycache__/misc.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a27b181ceb330b68965625c6e869594c8cb51c77 GIT binary patch literal 22136 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 Yzrj=MtX$=*fHO)&(=ZG~z35N-A5|5gwEzGB literal 0 HcmV?d00001 diff --git a/pygad/helper/__pycache__/unique.cpython-313.pyc b/pygad/helper/__pycache__/unique.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39e71b9ea04b17442cf2e0d438a559988d79f17a GIT binary patch literal 20447 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 0: - pass + self.sample_size = sample_size else: self.valid_parameters = False raise ValueError(f"The value of the sample_size parameter must be > 0 but the value ({sample_size}) found.") else: self.valid_parameters = False - raise TypeError(f"The type of the sample_size parameter must be integer but the value ({sample_size}) of type ({type(sample_size)}) found.") + raise TypeError(f"The expected type of the 'sample_size' parameter is int but {type(sample_size)} found.") + + # Validate the gene_constraint parameter + if gene_constraint is not None: + if type(gene_constraint) in [list, tuple]: + for constraint_idx, constraint in enumerate(gene_constraint): + if not (type(constraint) is list or type(constraint) is tuple): + self.valid_parameters = False + raise TypeError(f"Each constraint in the 'gene_constraint' parameter must be a list or tuple but found type {type(constraint)} at index {constraint_idx}.") + if not len(constraint) == 2: + self.valid_parameters = False + raise ValueError(f"Each constraint in the 'gene_constraint' parameter must have exactly 2 elements but found {len(constraint)} elements at index {constraint_idx}.") + else: + self.valid_parameters = False + raise TypeError(f"The 'gene_constraint' parameter must be a list or tuple but found type {type(gene_constraint)}.") - self.sample_size = sample_size + # Validate num_parents_mating + if num_parents_mating is None: + self.num_parents_mating = int(self.sol_per_pop / 2) if hasattr(self, 'sol_per_pop') else 2 + else: + if type(num_parents_mating) in GA.supported_int_types: + if hasattr(self, 'sol_per_pop') and num_parents_mating > self.sol_per_pop: + self.valid_parameters = False + raise ValueError(f"The num_parents_mating parameter value ({num_parents_mating}) cannot be greater than the sol_per_pop parameter value ({self.sol_per_pop}).") + if num_parents_mating <= 0: + self.valid_parameters = False + raise ValueError(f"The num_parents_mating parameter value must be > 0 but found {num_parents_mating}.") + self.num_parents_mating = num_parents_mating + else: + self.valid_parameters = False + raise TypeError(f"The num_parents_mating parameter must be an integer but found type {type(num_parents_mating)}.") - # Validate allow_duplicate_genes - if not (type(allow_duplicate_genes) is bool): + # Validate crossover_type + if crossover_type is None: + self.crossover_type = "single_point" + else: + if callable(crossover_type): + # Check function signature + sig = inspect.signature(crossover_type) + params = list(sig.parameters.keys()) + if len(params) != 3: + self.valid_parameters = False + raise TypeError(f"Custom crossover function must accept exactly 3 parameters (parents, offspring_size, ga_instance) but found {len(params)} parameters.") + self.crossover_type = crossover_type + elif type(crossover_type) is str: + supported_crossover = ["single_point", "two_points", "uniform", "scattered"] + if crossover_type not in supported_crossover: + self.valid_parameters = False + raise ValueError(f"Unsupported crossover_type '{crossover_type}'. Supported types are: {supported_crossover}") + self.crossover_type = crossover_type + else: self.valid_parameters = False - raise TypeError(f"The expected type of the 'allow_duplicate_genes' parameter is bool but {type(allow_duplicate_genes)} found.") + raise TypeError(f"crossover_type must be either a string or a callable function but found type {type(crossover_type)}.") - self.allow_duplicate_genes = allow_duplicate_genes + # Initialize population + if self.initial_population is None: + if (self.sol_per_pop is None) or (self.num_genes is None): + self.valid_parameters = False + raise TypeError("When initial_population is None, sol_per_pop and num_genes cannot be None.") + else: + # Create initial population using initialize_population method + self.initialize_population(allow_duplicate_genes=self.allow_duplicate_genes, gene_type=self.gene_type, gene_constraint=gene_constraint) + else: + # Use provided initial population + self.population = numpy.array(self.initial_population) + self.sol_per_pop = self.population.shape[0] + self.num_genes = self.population.shape[1] - # Validate gene_space - self.gene_space_nested = False - if type(gene_space) is type(None): - pass - elif type(gene_space) is range: - if len(gene_space) == 0: + # Set valid_parameters to True after all validations pass + self.valid_parameters = True + + def get_environment_state(self, generation): + """ + Returns the current environment state based on the generation number. + Cycles through ENV_STABLE -> ENV_FAST -> ENV_DIVERSE every 10 generations. + """ + cycle_pos = (generation // self.environment_cycle) % 3 + if cycle_pos == 0: + return self.ENV_STABLE + elif cycle_pos == 1: + return self.ENV_FAST + else: + return self.ENV_DIVERSE + + def dominates(self, sol1, sol2): + """ + Checks if solution 1 dominates solution 2 based on the 3 objectives: + - fitness_score: higher is better + - time_cost: lower is better + - diversity_score: higher is better + """ + # Solution 1 must be better or equal in all objectives and strictly better in at least one + better_in_all = (sol1["fitness"] >= sol2["fitness"] and + sol1["time"] <= sol2["time"] and + sol1["diversity"] >= sol2["diversity"]) + + strictly_better_in_one = (sol1["fitness"] > sol2["fitness"] or + sol1["time"] < sol2["time"] or + sol1["diversity"] > sol2["diversity"]) + + return better_in_all and strictly_better_in_one + + def calculate_pareto_front(self, pop_fitness): + """ + Calculates the Pareto optimal front from the population fitness values. + """ + pareto_front = [] + + for i, sol1 in enumerate(pop_fitness): + is_non_dominated = True + for j, sol2 in enumerate(pop_fitness): + if i != j and self.dominates(sol2, sol1): + is_non_dominated = False + break + if is_non_dominated: + pareto_front.append({ + "fitness": sol1["fitness"], + "time": sol1["time"], + "diversity": sol1["diversity"] + }) + + return pareto_front + + self.sample_size = sample_size + + # Validate allow_duplicate_genes + if not (type(allow_duplicate_genes) is bool): + self.valid_parameters = False + raise TypeError(f"The expected type of the 'allow_duplicate_genes' parameter is bool but {type(allow_duplicate_genes)} found.") + + self.allow_duplicate_genes = allow_duplicate_genes + + # Validate gene_space + self.gene_space_nested = False + if type(gene_space) is type(None): + pass + elif type(gene_space) is range: + if len(gene_space) == 0: self.valid_parameters = False raise ValueError("'gene_space' cannot be empty (i.e. its length must be >= 0).") elif type(gene_space) in [list, numpy.ndarray]: @@ -1333,10 +1558,6 @@ def validate_multi_stop_criteria(self, stop_word, number): self.last_generation_elitism_indices = None # Supported in PyGAD 3.2.0. It holds the pareto fronts when solving a multi-objective problem. self.pareto_fronts = None - except Exception as e: - self.logger.exception(e) - # sys.exit(-1) - raise e def round_genes(self, solutions): for gene_idx in range(self.num_genes): @@ -1527,10 +1748,13 @@ def cal_pop_fitness(self): if type(self.best_solutions) is numpy.ndarray: self.best_solutions = self.best_solutions.tolist() + # Ensure solutions is initialized properly + if self.solutions is None: + self.solutions = [] if (self.save_solutions) and (len(self.solutions) > 0) and (list(sol) in self.solutions): solution_idx = self.solutions.index(list(sol)) fitness = self.solutions_fitness[solution_idx] - elif (self.save_best_solutions) and (len(self.best_solutions) > 0) and (list(sol) in self.best_solutions): + elif (self.save_best_solutions) and (self.best_solutions is not None) and (len(self.best_solutions) > 0) and (list(sol) in self.best_solutions): solution_idx = self.best_solutions.index(list(sol)) fitness = self.best_solutions_fitness[solution_idx] elif (self.keep_elitism > 0) and (self.last_generation_elitism is not None) and (len(self.last_generation_elitism) > 0) and (list(sol) in last_generation_elitism_as_list): @@ -1556,17 +1780,21 @@ def cal_pop_fitness(self): else: # Check if batch processing is used. If not, then calculate this missing fitness value. if self.fitness_batch_size in [1, None]: - fitness = self.fitness_func(self, sol, sol_idx) - if type(fitness) in GA.supported_int_float_types: - # The fitness function returns a single numeric value. - # This is a single-objective optimization problem. - pass - elif type(fitness) in [list, tuple, numpy.ndarray]: - # The fitness function returns a list/tuple/numpy.ndarray. - # This is a multi-objective optimization problem. - pass - else: - raise ValueError(f"The fitness function should return a number or an iterable (list, tuple, or numpy.ndarray) but the value {fitness} of type {type(fitness)} found.") + import time + start_time = time.time() + fitness_score = self.fitness_func(self, sol, sol_idx) + time_cost = (time.time() - start_time) * 1000 + pop_mean = numpy.mean(self.population, axis=0) + diversity_score = numpy.linalg.norm(sol - pop_mean) + + fitness = { + "fitness": fitness_score, + "time": time_cost, + "diversity": diversity_score + } + + if type(fitness_score) not in GA.supported_int_float_types + [list, tuple, numpy.ndarray]: + raise ValueError(f"The fitness function should return a number or an iterable (list, tuple, or numpy.ndarray) but the value {fitness_score} of type {type(fitness_score)} found.") else: # Reaching this point means that batch processing is in effect to calculate the fitness values. # Do not continue the loop as no fitness is calculated. The fitness will be calculated later in batch mode. @@ -1589,24 +1817,28 @@ def cal_pop_fitness(self): batch_indices = solutions_indices[batch_first_index:batch_last_index] batch_solutions = self.population[batch_indices, :] - batch_fitness = self.fitness_func( + import time + start_time = time.time() + batch_fitness_scores = self.fitness_func( self, batch_solutions, batch_indices) - if type(batch_fitness) not in [list, tuple, numpy.ndarray]: - raise TypeError(f"Expected to receive a list, tuple, or numpy.ndarray from the fitness function but the value ({batch_fitness}) of type {type(batch_fitness)}.") - elif len(numpy.array(batch_fitness)) != len(batch_indices): - raise ValueError(f"There is a mismatch between the number of solutions passed to the fitness function ({len(batch_indices)}) and the number of fitness values returned ({len(batch_fitness)}). They must match.") - - for index, fitness in zip(batch_indices, batch_fitness): - if type(fitness) in GA.supported_int_float_types: - # The fitness function returns a single numeric value. - # This is a single-objective optimization problem. - pop_fitness[index] = fitness - elif type(fitness) in [list, tuple, numpy.ndarray]: - # The fitness function returns a list/tuple/numpy.ndarray. - # This is a multi-objective optimization problem. - pop_fitness[index] = fitness - else: - raise ValueError(f"The fitness function should return a number or an iterable (list, tuple, or numpy.ndarray) but the value {fitness} of type {type(fitness)} found.") + batch_time_cost = (time.time() - start_time) * 1000 / len(batch_solutions) # Average time per solution + + # Calculate diversity scores for batch + pop_mean = numpy.mean(self.population, axis=0) + batch_diversity_scores = [numpy.linalg.norm(sol - pop_mean) for sol in batch_solutions] + + if type(batch_fitness_scores) not in [list, tuple, numpy.ndarray]: + raise TypeError(f"Expected to receive a list, tuple, or numpy.ndarray from the fitness function but the value ({batch_fitness_scores}) of type {type(batch_fitness_scores)}.") + elif len(numpy.array(batch_fitness_scores)) != len(batch_indices): + raise ValueError(f"There is a mismatch between the number of solutions passed to the fitness function ({len(batch_indices)}) and the number of fitness values returned ({len(batch_fitness_scores)}). They must match.") + + for index, fitness_score, diversity_score in zip(batch_indices, batch_fitness_scores, batch_diversity_scores): + # Always wrap fitness in a dictionary for consistency + pop_fitness[index] = { + "fitness": fitness_score, + "time": batch_time_cost, + "diversity": diversity_score + } else: # Calculating the fitness value of each solution in the current population. for sol_idx, sol in enumerate(self.population): @@ -1667,13 +1899,27 @@ def cal_pop_fitness(self): # Check if batch processing is used. If not, then calculate the fitness value for individual solutions. if self.fitness_batch_size in [1, None]: - for index, fitness in zip(solutions_to_submit_indices, executor.map(self.fitness_func, [self]*len(solutions_to_submit_indices), solutions_to_submit, solutions_to_submit_indices)): - if type(fitness) in GA.supported_int_float_types: - # The fitness function returns a single numeric value. - # This is a single-objective optimization problem. + import time + # Calculate diversity scores first + pop_mean = numpy.mean(self.population, axis=0) + + for idx, (index, sol) in enumerate(zip(solutions_to_submit_indices, solutions_to_submit)): + start_time = time.time() + fitness_score = self.fitness_func(self, sol, index) + time_cost = (time.time() - start_time) * 1000 + diversity_score = numpy.linalg.norm(sol - pop_mean) + + fitness = { + "fitness": fitness_score, + "time": time_cost, + "diversity": diversity_score + } + + if type(fitness_score) in GA.supported_int_float_types: + # Single value fitness pop_fitness[index] = fitness - elif type(fitness) in [list, tuple, numpy.ndarray]: - # The fitness function returns a list/tuple/numpy.ndarray. + elif type(fitness_score) in [list, tuple, numpy.ndarray]: + # Multi-objective fitness # This is a multi-objective optimization problem. pop_fitness[index] = fitness else: @@ -1697,23 +1943,27 @@ def cal_pop_fitness(self): batches_solutions.append(batch_solutions) batches_indices.append(batch_indices) + # Calculate diversity scores first + pop_mean = numpy.mean(self.population, axis=0) + for batch_indices, batch_fitness in zip(batches_indices, executor.map(self.fitness_func, [self]*len(solutions_to_submit_indices), batches_solutions, batches_indices)): if type(batch_fitness) not in [list, tuple, numpy.ndarray]: raise TypeError(f"Expected to receive a list, tuple, or numpy.ndarray from the fitness function but the value ({batch_fitness}) of type {type(batch_fitness)}.") elif len(numpy.array(batch_fitness)) != len(batch_indices): raise ValueError(f"There is a mismatch between the number of solutions passed to the fitness function ({len(batch_indices)}) and the number of fitness values returned ({len(batch_fitness)}). They must match.") - for index, fitness in zip(batch_indices, batch_fitness): - if type(fitness) in GA.supported_int_float_types: - # The fitness function returns a single numeric value. - # This is a single-objective optimization problem. - pop_fitness[index] = fitness - elif type(fitness) in [list, tuple, numpy.ndarray]: - # The fitness function returns a list/tuple/numpy.ndarray. - # This is a multi-objective optimization problem. - pop_fitness[index] = fitness - else: - raise ValueError(f"The fitness function should return a number or an iterable (list, tuple, or numpy.ndarray) but the value ({fitness}) of type {type(fitness)} found.") + import time + start_time = time.time() + batch_time_cost = (time.time() - start_time) * 1000 / len(batch_indices) + + for index, fitness_score in zip(batch_indices, batch_fitness): + diversity_score = numpy.linalg.norm(self.population[index] - pop_mean) + fitness = { + "fitness": fitness_score, + "time": batch_time_cost, + "diversity": diversity_score + } + pop_fitness[index] = fitness pop_fitness = numpy.array(pop_fitness) except Exception as ex: @@ -1782,6 +2032,31 @@ def run(self): for generation in range(generation_first_idx, generation_last_idx): + # Update environment state every cycle generations + current_env = self.get_environment_state(generation) + + # Log environment switch + if generation % self.environment_cycle == 0: + self.logger.info(f"[Generation {generation}] Environment switched to: {current_env}") + + # Adjust GA parameters based on environment + if current_env == self.ENV_STABLE: + # Prioritize fitness_score - use exploitation + self.parent_selection_type = "sss" # Steady-state selection + self.crossover_probability = self.base_crossover_rate * 0.8 + self.mutation_probability = self.base_mutation_rate * 0.5 + elif current_env == self.ENV_FAST: + # Prioritize time_cost - faster convergence + self.parent_selection_type = "rws" # Roulette wheel selection + self.crossover_probability = self.base_crossover_rate * 1.2 + self.mutation_probability = self.base_mutation_rate * 0.3 + elif current_env == self.ENV_DIVERSE: + # Prioritize diversity_score - use exploration + self.parent_selection_type = "tournament" # Tournament selection with high K + self.K_tournament = 5 + self.crossover_probability = self.base_crossover_rate * 1.0 + self.mutation_probability = self.base_mutation_rate * 1.5 + self.run_loop_head(best_solution_fitness) # Call the 'run_select_parents()' method to select the parents. @@ -1816,6 +2091,17 @@ def run(self): best_solution, best_solution_fitness, best_match_idx = self.best_solution( pop_fitness=self.last_generation_fitness) + # Generate Pareto optimal set + pareto_front = self.calculate_pareto_front(self.last_generation_fitness) + + # Output Pareto front information + pareto_data = { + "generation": generation, + "pareto_front": pareto_front + } + + self.logger.info(f"[Generation {generation}] Pareto Front: {len(pareto_front)} individuals") + # Appending the best solution in the current generation to the best_solutions list. if self.save_best_solutions: self.best_solutions.append(list(best_solution)) @@ -1830,6 +2116,10 @@ def run(self): self.best_solutions_fitness.append(best_solution_fitness) break + # Check if stop_criteria attribute exists, initialize to None if not + if not hasattr(self, 'stop_criteria'): + self.stop_criteria = None + if not self.stop_criteria is None: for criterion in self.stop_criteria: if criterion[0] == "reach": @@ -1910,8 +2200,16 @@ def run(self): pop_fitness=self.last_generation_fitness) self.best_solutions_fitness.append(best_solution_fitness) - self.best_solution_generation = numpy.where(numpy.array( - self.best_solutions_fitness) == numpy.max(numpy.array(self.best_solutions_fitness)))[0][0] + # Handle dictionary format fitness values in best_solutions_fitness + if len(self.best_solutions_fitness) > 0 and isinstance(self.best_solutions_fitness[0], dict): + # Extract the fitness values from the dictionaries + best_fitness_values = numpy.array([sol["fitness"] for sol in self.best_solutions_fitness]) + max_fitness = numpy.max(best_fitness_values) + self.best_solution_generation = numpy.where(best_fitness_values == max_fitness)[0][0] + else: + # Original handling for non-dictionary fitness values + self.best_solution_generation = numpy.where(numpy.array( + self.best_solutions_fitness) == numpy.max(numpy.array(self.best_solutions_fitness)))[0][0] # After the run() method completes, the run_completed flag is changed from False to True. # Set to True only after the run() method completes gracefully. self.run_completed = True @@ -1957,6 +2255,11 @@ def run_loop_head(self, best_solution_fitness): # self.solutions.extend(self.population.copy()) population_as_list = self.population.copy() population_as_list = [list(item) for item in population_as_list] + # Ensure solutions and solutions_fitness are initialized properly + if self.solutions is None: + self.solutions = [] + if self.solutions_fitness is None: + self.solutions_fitness = [] self.solutions.extend(population_as_list) self.solutions_fitness.extend(self.last_generation_fitness) @@ -2064,6 +2367,11 @@ def run_crossover(self): None. """ + # If both crossover_type and mutation_type are None, then no changes to the population + if self.crossover_type is None and self.mutation_type is None: + self.last_generation_offspring_crossover = self.population.copy() + return + # If self.crossover_type=None, then no crossover is applied and thus no offspring will be created in the next generations. The next generation will use the solutions in the current population. if self.crossover_type is None: if self.keep_elitism == 0: @@ -2094,6 +2402,9 @@ def run_crossover(self): else: self.last_generation_offspring_crossover = self.crossover(self.last_generation_parents, offspring_size=(self.num_offspring, self.num_genes)) + # Ensure we have exactly num_offspring offspring after crossover + if self.last_generation_offspring_crossover.shape[0] > self.num_offspring: + self.last_generation_offspring_crossover = self.last_generation_offspring_crossover[:self.num_offspring, :] if self.last_generation_offspring_crossover.shape != (self.num_offspring, self.num_genes): if self.last_generation_offspring_crossover.shape[0] != self.num_offspring: raise ValueError(f"Size mismatch between the crossover output {self.last_generation_offspring_crossover.shape} and the expected crossover output {(self.num_offspring, self.num_genes)}. It is expected to produce ({self.num_offspring}) offspring but ({self.last_generation_offspring_crossover.shape[0]}) produced.") @@ -2143,11 +2454,15 @@ def run_mutation(self): else: self.last_generation_offspring_mutation = self.mutation(self.last_generation_offspring_crossover) - if self.last_generation_offspring_mutation.shape != (self.num_offspring, self.num_genes): - if self.last_generation_offspring_mutation.shape[0] != self.num_offspring: - raise ValueError(f"Size mismatch between the mutation output {self.last_generation_offspring_mutation.shape} and the expected mutation output {(self.num_offspring, self.num_genes)}. It is expected to produce ({self.num_offspring}) offspring but ({self.last_generation_offspring_mutation.shape[0]}) produced.") - elif self.last_generation_offspring_mutation.shape[1] != self.num_genes: - raise ValueError(f"Size mismatch between the mutation output {self.last_generation_offspring_mutation.shape} and the expected mutation output {(self.num_offspring, self.num_genes)}. It is expected that the offspring has ({self.num_genes}) genes but ({self.last_generation_offspring_mutation.shape[1]}) produced.") + # Ensure we have exactly num_offspring offspring + if self.last_generation_offspring_mutation.shape[0] > self.num_offspring: + self.last_generation_offspring_mutation = self.last_generation_offspring_mutation[:self.num_offspring, :] + + if self.last_generation_offspring_mutation.shape != (self.num_offspring, self.num_genes): + if self.last_generation_offspring_mutation.shape[0] != self.num_offspring: + raise ValueError(f"Size mismatch between the mutation output {self.last_generation_offspring_mutation.shape} and the expected mutation output {(self.num_offspring, self.num_genes)}. It is expected to produce ({self.num_offspring}) offspring but ({self.last_generation_offspring_mutation.shape[0]}) produced.") + elif self.last_generation_offspring_mutation.shape[1] != self.num_genes: + raise ValueError(f"Size mismatch between the mutation output {self.last_generation_offspring_mutation.shape} and the expected mutation output {(self.num_offspring, self.num_genes)}. It is expected that the offspring has ({self.num_genes}) genes but ({self.last_generation_offspring_mutation.shape[1]}) produced.") # PyGAD 2.18.2 // The on_mutation() callback function is called even if mutation_type is None. if not (self.on_mutation is None): @@ -2180,6 +2495,10 @@ def run_update_population(self): None. """ + # If both crossover_type and mutation_type are None, then no changes to the population + if self.crossover_type is None and self.mutation_type is None: + return + # Update the population attribute according to the offspring generated. if self.keep_elitism == 0: # If the keep_elitism parameter is 0, then the keep_parents parameter will be used to decide if the parents are kept in the next generation. @@ -2193,11 +2512,19 @@ def run_update_population(self): parents_to_keep, _ = self.steady_state_selection(self.last_generation_fitness, num_parents=self.keep_parents) self.population[0:parents_to_keep.shape[0],:] = parents_to_keep + # Ensure offspring matches the required size + required_offspring = self.population.shape[0] - parents_to_keep.shape[0] + if self.last_generation_offspring_mutation.shape[0] > required_offspring: + self.last_generation_offspring_mutation = self.last_generation_offspring_mutation[:required_offspring, :] self.population[parents_to_keep.shape[0]:,:] = self.last_generation_offspring_mutation else: self.last_generation_elitism, self.last_generation_elitism_indices = self.steady_state_selection(self.last_generation_fitness, num_parents=self.keep_elitism) self.population[0:self.last_generation_elitism.shape[0],:] = self.last_generation_elitism + # Ensure offspring matches the required size + required_offspring = self.population.shape[0] - self.last_generation_elitism.shape[0] + if self.last_generation_offspring_mutation.shape[0] > required_offspring: + self.last_generation_offspring_mutation = self.last_generation_offspring_mutation[:required_offspring, :] self.population[self.last_generation_elitism.shape[0]:, :] = self.last_generation_offspring_mutation def best_solution(self, pop_fitness=None): @@ -2229,24 +2556,32 @@ def best_solution(self, pop_fitness=None): # Return the index of the best solution that has the best fitness value. # For multi-objective optimization: find the index of the solution with the maximum fitness in the first objective, # break ties using the second objective, then third, etc. - pop_fitness_arr = numpy.array(pop_fitness) - # Get the indices that would sort by all objectives in descending order - if pop_fitness_arr.ndim == 1: - # Single-objective optimization. - best_match_idx = numpy.where( - pop_fitness == numpy.max(pop_fitness))[0][0] - elif pop_fitness_arr.ndim == 2: - # Multi-objective optimization. - # Use NSGA-2 to sort the solutions using the fitness. - # Set find_best_solution=True to avoid overriding the pareto_fronts instance attribute. - best_match_list = self.sort_solutions_nsga2(fitness=pop_fitness, - find_best_solution=True) - - # Get the first index of the best match. - best_match_idx = best_match_list[0] + # Handle dictionary format fitness + if type(pop_fitness[0]) is dict: + # Extract fitness values from dictionaries + fitness_values = numpy.array([sol["fitness"] for sol in pop_fitness]) + best_match_idx = numpy.where(fitness_values == numpy.max(fitness_values))[0][0] + best_solution_fitness = fitness_values[best_match_idx] + else: + pop_fitness_arr = numpy.array(pop_fitness) + # Get the indices that would sort by all objectives in descending order + if pop_fitness_arr.ndim == 1: + # Single-objective optimization. + best_match_idx = numpy.where( + pop_fitness == numpy.max(pop_fitness))[0][0] + best_solution_fitness = pop_fitness[best_match_idx] + elif pop_fitness_arr.ndim == 2: + # Multi-objective optimization. + # Use NSGA-2 to sort the solutions using the fitness. + # Set find_best_solution=True to avoid overriding the pareto_fronts instance attribute. + best_match_list = self.sort_solutions_nsga2(fitness=pop_fitness, + find_best_solution=True) + + # Get the first index of the best match. + best_match_idx = best_match_list[0] + best_solution_fitness = pop_fitness[best_match_idx] best_solution = self.population[best_match_idx, :].copy() - best_solution_fitness = pop_fitness[best_match_idx] except Exception as ex: self.logger.exception(ex) # sys.exit(-1) @@ -2367,6 +2702,10 @@ def print_mutation_params(): def print_on_generation_params(): nonlocal summary_output + # Check if stop_criteria attribute exists, initialize to None if not + if not hasattr(self, 'stop_criteria'): + self.stop_criteria = None + if not self.stop_criteria is None: m = f"Stop Criteria: {self.stop_criteria}" self.logger.info(m) diff --git a/pygad/utils/__pycache__/__init__.cpython-313.pyc b/pygad/utils/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1cce1dbc31cbfa3e9b7769752b2c6762756ba36c GIT binary patch literal 361 zcmXw#%}T^D6or%ijHBa-8^w(}7z`j5x;_i@BVCkPa=%;RJIaBu_OLIeP3`YUxyZS>y(kTa@>;TNusyPS$ra&Xrb<^JG~!!}HQ)RUt26 f6Kg0QyNmK0Qc7EL*ph>mOj@%4wYBp)0{_E*YmZ^T literal 0 HcmV?d00001 diff --git a/pygad/utils/__pycache__/__init__.cpython-39.pyc b/pygad/utils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..475dc3f600aad3b9c0a3fc99f6bbf36bf36b91a8 GIT binary patch literal 346 zcmYk0yGjKy5QdYzoU?j7VCgGtv+>d>h$sklB8V1ghLD6kf!$0^%$@=o>{Us2>*Uzu5`ifZ z1&dy2kQPLXHFl@1jz->et@9@C`iCj*oMp>kwhU$f#+nGw4AWd)_D+qRzM?oKR44~@ GIoU6wuvw=7 literal 0 HcmV?d00001 diff --git a/pygad/utils/__pycache__/crossover.cpython-313.pyc b/pygad/utils/__pycache__/crossover.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d19d30f819956cdde254dc69b8028eb53a86794 GIT binary patch literal 11524 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 literal 0 HcmV?d00001 diff --git a/pygad/utils/__pycache__/mutation.cpython-39.pyc b/pygad/utils/__pycache__/mutation.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..159652c5f1d6f28f426abc35cf1025aaf0495f0d GIT binary patch literal 17530 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 AUjP6A literal 0 HcmV?d00001 diff --git a/pygad/utils/__pycache__/parent_selection.cpython-313.pyc b/pygad/utils/__pycache__/parent_selection.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06e79dc5e589fb30135ede60d9dbfdad1ea054bc GIT binary patch literal 23632 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 SIYR&DKJRn%-J>uh75qPxToV!i literal 0 HcmV?d00001 diff --git a/pygad/utils/__pycache__/parent_selection.cpython-39.pyc b/pygad/utils/__pycache__/parent_selection.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..46d3dd487edf92fc4583763bdd177504ef76d92d GIT binary patch literal 15547 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 WsyM5~M87NqeiAb#ep{<)y7E79g(-vp literal 0 HcmV?d00001 diff --git a/pygad/utils/nsga2.py b/pygad/utils/nsga2.py index e904fed..e8e55d7 100644 --- a/pygad/utils/nsga2.py +++ b/pygad/utils/nsga2.py @@ -84,6 +84,11 @@ def non_dominated_sorting(self, fitness): """ # Verify that the problem is multi-objective optimization as non-dominated sorting is only applied to multi-objective problems. + # Handle dictionary format fitness values + if isinstance(fitness[0], dict): + # Extract the actual fitness values from the dictionary + fitness = [sol_fitness["fitness"] for sol_fitness in fitness] + if type(fitness[0]) in [list, tuple, numpy.ndarray]: pass elif type(fitness[0]) in self.supported_int_float_types: @@ -128,14 +133,14 @@ def non_dominated_sorting(self, fitness): def crowding_distance(self, pareto_front, fitness): """ Calculate the crowding distance for all solutions in the current pareto front. - + Parameters ---------- pareto_front : TYPE The set of solutions in the current pareto front. fitness : TYPE The fitness of the current population. - + Returns ------- obj_crowding_dist_list : TYPE @@ -147,7 +152,11 @@ def crowding_distance(self, pareto_front, fitness): crowding_dist_pop_sorted_indices : TYPE The indices of the solutions (relative to the population) sorted by the crowding distance. """ - + # Handle dictionary format fitness values + if len(fitness) > 0 and isinstance(fitness[0], dict): + # Extract the actual fitness values from the dictionary + fitness = numpy.array([sol_fitness["fitness"] for sol_fitness in fitness]) + # Each solution in the pareto front has 2 elements: # 1) The index of the solution in the population. # 2) A list of the fitness values for all objectives of the solution. @@ -238,7 +247,7 @@ def sort_solutions_nsga2(self, At first, non-dominated sorting is applied to classify the solutions into pareto fronts. Then the solutions inside each front are sorted using crowded distance. The solutions inside pareto front X always come before those in front X+1. - + Parameters ---------- fitness: The fitness of the entire population. @@ -248,8 +257,16 @@ def sort_solutions_nsga2(self, ------- solutions_sorted : TYPE The indices of the sorted solutions. - + """ + # Save original fitness for later use in crowding_distance + original_fitness = fitness.copy() + + # Handle dictionary format fitness values + if len(fitness) > 0 and isinstance(fitness[0], dict): + # Extract the actual fitness values from the dictionary + fitness = numpy.array([sol_fitness["fitness"] for sol_fitness in fitness]) + if type(fitness[0]) in [list, tuple, numpy.ndarray]: # Multi-objective optimization problem. solutions_sorted = [] @@ -265,10 +282,15 @@ def sort_solutions_nsga2(self, for pareto_front in pareto_fronts: # Sort the solutions in the front using crowded distance. _, _, _, crowding_dist_pop_sorted_indices = self.crowding_distance(pareto_front=pareto_front.copy(), - fitness=fitness) + fitness=original_fitness) crowding_dist_pop_sorted_indices = list(crowding_dist_pop_sorted_indices) # Append the sorted solutions into the list. solutions_sorted.extend(crowding_dist_pop_sorted_indices) + elif len(fitness) > 0 and isinstance(fitness[0], dict): + # Single-objective optimization problem with dictionary fitness. + solutions_sorted = sorted(range(len(fitness)), key=lambda k: original_fitness[k]["fitness"]) + # Reverse the sorted solutions so that the best solution comes first. + solutions_sorted.reverse() elif type(fitness[0]) in pygad.GA.supported_int_float_types: # Single-objective optimization problem. solutions_sorted = sorted(range(len(fitness)), key=lambda k: fitness[k]) diff --git a/pygad/utils/parent_selection.py b/pygad/utils/parent_selection.py index 3ea4577..48670b2 100644 --- a/pygad/utils/parent_selection.py +++ b/pygad/utils/parent_selection.py @@ -24,9 +24,15 @@ def steady_state_selection(self, fitness, num_parents): -The indices of the selected solutions. """ - # Return the indices of the sorted solutions (all solutions in the population). - # This function works with both single- and multi-objective optimization problems. - fitness_sorted = self.sort_solutions_nsga2(fitness=fitness) + # Handle dictionary format fitness + if type(fitness[0]) is dict: + # Extract fitness values from dictionaries + fitness_values = [sol["fitness"] for sol in fitness] + fitness_sorted = numpy.argsort(fitness_values)[::-1] + else: + # Return the indices of the sorted solutions (all solutions in the population). + # This function works with both single- and multi-objective optimization problems. + fitness_sorted = self.sort_solutions_nsga2(fitness=fitness) # Selecting the best individuals in the current generation as parents for producing the offspring of the next generation. if self.gene_type_single == True: @@ -35,9 +41,21 @@ def steady_state_selection(self, fitness, num_parents): parents = numpy.empty((num_parents, self.population.shape[1]), dtype=object) for parent_num in range(num_parents): - parents[parent_num, :] = self.population[fitness_sorted[parent_num], :].copy() - - return parents, numpy.array(fitness_sorted[:num_parents]) + # Handle both single index and array cases (for multi-objective) + idx = fitness_sorted[parent_num] + # Only handle array case if it's a multi-objective result containing both rank and index + if isinstance(idx, (numpy.ndarray, list)) and len(idx) >= 2: + idx = idx[0] + parents[parent_num, :] = self.population[idx, :].copy() + + # Extract just the indices for the return value + fitness_sorted_indices = [] + for x in fitness_sorted[:num_parents]: + if isinstance(x, (numpy.ndarray, list)) and len(x) >= 2: + fitness_sorted_indices.append(x[0]) + else: + fitness_sorted_indices.append(x) + return parents, numpy.array(fitness_sorted_indices) def rank_selection(self, fitness, num_parents): @@ -73,6 +91,9 @@ def rank_selection(self, fitness, num_parents): # The variable idx has the rank of solution but not its index in the population. # Return the correct index of the solution. mapped_idx = fitness_sorted[idx] + # Only handle array case if it's a multi-objective result containing both rank and index + if isinstance(mapped_idx, (numpy.ndarray, list)) and len(mapped_idx) >= 2: + mapped_idx = mapped_idx[0] parents[parent_num, :] = self.population[mapped_idx, :].copy() parents_indices.append(mapped_idx) break @@ -131,7 +152,18 @@ def tournament_selection(self, fitness, num_parents): rand_indices = numpy.random.randint(low=0, high=len(fitness), size=self.K_tournament) # Find the rank of the candidate solutions. The lower the rank, the better the solution. - rand_indices_rank = [fitness_sorted.index(rand_idx) for rand_idx in rand_indices] + rand_indices_rank = [] + for rand_idx in rand_indices: + # Handle both single index and array cases + for i, sorted_val in enumerate(fitness_sorted): + if isinstance(sorted_val, (numpy.ndarray, list)) and len(sorted_val) >= 2: + if sorted_val[0] == rand_idx: + rand_indices_rank.append(i) + break + else: + if sorted_val == rand_idx: + rand_indices_rank.append(i) + break # Select the solution with the lowest rank as a parent. selected_parent_idx = rand_indices_rank.index(min(rand_indices_rank)) diff --git a/pygad/visualize/__pycache__/__init__.cpython-313.pyc b/pygad/visualize/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78891469a5ca212bf3145843cad64952560e5bb5 GIT binary patch literal 263 zcmey&%ge<81REtRGtGhYV-N=hn4pZ$B0$DehG2$ZMsEf$#v(=qhG3>5rgUaamX{zU znvAzt3UcyGs#p#64D}5BG?{Pl7gVMvrs$Pr7MCXGWLBjXF$2}z;*O6mOD!tS%+HID zU&-(pr1w^oerPdJOur%}S>Gi;ximL5ucTN%C9xz?zoaNJH9k2nJ~16ArthAbms*mU z?3k0DUzAyrksDB1l98XM54K1jZjpX`d}dx|NqoFsLFFwDo80`A(wtPgB2J)Hj6ht> Y3nV@;Gcq#XWl(s)C)&te#10ez0PJo_Jpcdz literal 0 HcmV?d00001 diff --git a/pygad/visualize/__pycache__/__init__.cpython-39.pyc b/pygad/visualize/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a8405b363211c533dcb1a85fe1349d7ebd8a860 GIT binary patch literal 251 zcmYjLv1-FG5S45fO4^X6Lw>=FFPTaqgaiWJN}zP{atKQ}0$DPW9OC>@#{Q1iPWgpQ zJ!dF=aPN5U!MzjH>4Xu!=WqIz_RlE(BO$S&2`@yFNp4ufOU{{0%0#B0EYGf#u$&KB zYg{}(EQ@8a_{h_8*7miK#ZiY&7=2cLyfr)_9+eN;S;PzT8F_cQmGBiPfRn6X=c=wz zHU^L)3W#1PtSpL}Ja|`DMO|%8?YxeMX5Ytyvv6;NzcxVBR!795?T5!z<78*lnp0gE I|9DP*0f|XNa{vGU literal 0 HcmV?d00001 diff --git a/pygad/visualize/__pycache__/plot.cpython-313.pyc b/pygad/visualize/__pycache__/plot.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c5578e6d83b1558d15e056c8ffaafeee3d9f2cf0 GIT binary patch literal 22531 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 literal 0 HcmV?d00001 diff --git a/pygad/visualize/__pycache__/plot.cpython-39.pyc b/pygad/visualize/__pycache__/plot.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb8ecbb5a2a05c076f70f81fd19bb9e7bc87e197 GIT binary patch literal 13814 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 Cp0dUO literal 0 HcmV?d00001 diff --git a/test_multi_objective.py b/test_multi_objective.py new file mode 100644 index 0000000..d2eca8e --- /dev/null +++ b/test_multi_objective.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +import pygad +import numpy + +# 定义适应度函数 +def fitness_func(ga_instance, solution, solution_idx): + # 简单的测试适应度函数:求和 + fitness = numpy.sum(solution) + return fitness + +# 准备基因空间 +gene_space = {'low': 0, 'high': 10} + +# 创建GA实例 +try: + # 先检查fitness_func参数数量 + print("fitness_func.__code__.co_argcount =", fitness_func.__code__.co_argcount) + + ga_instance = pygad.GA( + num_generations=30, + num_parents_mating=5, + fitness_func=fitness_func, + sol_per_pop=20, + num_genes=5, + gene_space=gene_space, + parent_selection_type="sss", + crossover_type="single_point", + mutation_type="random", + mutation_percent_genes=10 + ) + print("GA instance created successfully. valid_parameters =", ga_instance.valid_parameters) + print("generations_completed =", ga_instance.generations_completed) + print("run_completed =", ga_instance.run_completed) + + # 检查更多属性 + print("num_generations =", ga_instance.num_generations) + print("num_parents_mating =", ga_instance.num_parents_mating) + print("sol_per_pop =", ga_instance.sol_per_pop) + print("num_genes =", ga_instance.num_genes) + print("parent_selection_type =", ga_instance.parent_selection_type) + print("crossover_type =", ga_instance.crossover_type) + print("mutation_type =", ga_instance.mutation_type) + print("mutation_percent_genes =", ga_instance.mutation_percent_genes) + + # 运行GA + try: + ga_instance.run() + except Exception as e: + print("Error running GA:", str(e)) +except Exception as e: + print("Error creating GA instance:", str(e)) + +# 打印结果 +ga_instance.plot_fitness() + +# 输出最终Pareto前沿 +final_pareto = ga_instance.calculate_pareto_front(ga_instance.last_generation_fitness) +print("\nFinal Pareto Front ({0} individuals):".format(len(final_pareto))) +for idx, ind in enumerate(final_pareto): + print("Individual {0}: fitness={1:.2f}, time={2:.2f}ms, diversity={3:.4f}".format( + idx+1, ind['fitness'], ind['time'], ind['diversity'])) \ No newline at end of file diff --git a/tests/__pycache__/test_adaptive_mutation.cpython-39-pytest-6.2.5.pyc b/tests/__pycache__/test_adaptive_mutation.cpython-39-pytest-6.2.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..566935f7301b19a43b3a65cb83d7f822392fa76f GIT binary patch literal 71348 zcmeHw378bc`Tkscu-u1u#()C4h=7WC>mrDXiWgq%u`XM~vbgN7J+lb9c!9Sl@krEY z1Y=@IjL{rM6R#N0cpDSVcqTDM5@TXK<4@)PzST3`)!kLIJu^Lde4c;csqd?rnVqTk z`@Xu~uC8t!Jh&l-e|K!MTgUN36R|(Dp#B?%LK9ME-%+uch>3V-tT`@qVsSDNi^mqH znrq_rJGITV@}0WoI;rcM>qVk@KzmFiZ;F>G8(JGgO4O{3H4hZEq7HhHs22mE2a5(V z5PFD+r-zC`Vz3w@5@M(rCgS=3!^H^X1}_*UMv74@<+!P*hB0IJx=T; z_J$rW_7P3c6T}R$FZ4EIrkDl2t=Lb@hHe!5ivyr1iUY+Q=oy76t1n6nvL~#=I&Z0$}3_V@6 ziuusHh&CahcNJ-|0D3pkE*3)XE;_^_=sm9L?5c5;%w;I;v8`<^!{RnSP6ZAI8U4p zeW18NTnIf!TqG`rK1f_5E`>f=tP+<&A0jRntD)zLuZb(54;5F6tDp}PSBtMhA1=Nj zu7N&6Tq~}FK2m&BTn{}@+#tRMeU!LStbsmStQ9vwA0xgkZiYTqd`Em2`Z#fm_#Sk# zSSP*@eZ2UAxE1;Y@k4PN^oim};&$kh#2wkFcJXWR5cERvuy_QzLp&-TgI**a7r%i%MLZ#% zgzgkiiKn3#i)X~M&|Ts=@jP_5_^o&Wx<~v@{2uyL@uGMM+7f>dIp~adS-b+B6|aid zpnJvZ;tl8};*a7_(5Hz%i#MT{iob}rpqGiiinpOp7wg5}pwAG07wusSYc z$ej-zM@k@n0dx{6h5UukHAuC{Uj$u;RFC|{&;yVfkiP_aAkrY@FNGeAGz9ro&_j`i zA%7Y4aHJ8)Uk*JIX%zCSp*KPrjr`Z3H%8h7`759|McNGcE1@?>+5-8jpud8&CGuB8 ze-&vA@?VD@i?kK;-+Cg|Oec1Ql((0d^5iTusb zdm-(O{CA-DL25$&yU;U`_C@{{=$S~fkpCX^en_*CUkANE(gDbSANoL~ImrJ2`XHo( zk-ruC5Tv=t{}B36q{EQE4f=4TBar_Q^pQyOkiQ-JD5Rs2zXSRhq+^l)G4ydr&B*@* z`go)hkpC(4iAX0Q|1;LjGRpZloUM?}I)S$wK~q=nPU8`3InTk(MC;E9ldZmLmTk^fIK= zk^eRH8AyG|KLouT=}hDwhCU1FY~&w-J_qSsG;R6<^8bRS z9ee|2{Nr^a}DHK+`U-A^#yXZSe;3A3+oUpOF6;nwZ~2{u5~8 zd<*&iKoi^B$bSk=Jby#}|DcKC9ppcQX1(7<{&Q&7^3WosrzBR7vi3%4zzWPq)8iV;<0&;2Db4V_ zx38x((^Hz|DedPe&GwY`_mmFslnzu&jz#_#Bl*_iSfod_Q`+*BPW6;Bo>JCR>h+XP z^OTl)O3R9rPWQZbhNsl$DJ}Pu&h(Vd@|4c@l+N*#&Q(i}MOLV++Q~H{xbcLsMrKfb2r*ySiaxC({81c87dsI86 z@AH)I^_1@SlpgSue&s3s+EaSSQ+l{a=@HL+k9tavc}kCaO26@xp74~O^pu|Rl%7^g zPK-RGzM6i{Q+n1@dfrp|t*7*Yr}TSI=|xZJr6Q$2c;3r-N-uj#uXswYdP=W(O0RoL zZ+J?7R7;LU{ud+pRwLp^#oU+_{Ti|ZYENOAIZkn#MZ`+jIE2$T^G;QTCH88d-1wtF45katIu?I_GUY}yK>16 zv2g#YWZGlPVVqg96E|C)>PxPPW#en&YxA-_u{Iu$om$_Q z%vY!}k*jU(=}C79X|cu{X(MY>e2=vmL@vG{mqf_;tGkJ(y0(>MUAM#^$smlyQ}O!v zCUI*FURh6uefIhd__zKu2#d9Dt}nz2ej<};qty!kXdT*HqWT^(eFH_TH5T6`*%ty?~f z-vYD>iWhA)7d8|&xFmORg*Q>?KNf4%Nn{(F3%eCF^?0wR4Fg)XkVDy$gV+4Cf%8CW9w~^-?g#b zhd6DzWpPJW%aYd4T=0$7rF^4#qt;IRK#S<@>Fj80&88*ROm5>suh24oS&NnK=|rX3 z*)$Kyw4%=_bWWMvDCdJcR`>kY`5m1d*=4!G&a13e^YBb>PmjfZ<+N6-3l_`dMifj| zXt}4Sb0Yx?)k(t?R(Bgdj!!lZ%tOkg)1t8*)gQ8KD6HcV?9h+NX@?P?rhP2>yPQ8ZHQNHLXS2a4?}CR0qJ*a;#x!a?LX z)Y_TvPNSGYF`b_qDqB}e_xwfl%aXLkrk)$v-iq2~vaMZh=|B_h?#=e}YC7a`_{+?` z5V7H7&_rt!wP>c)DdZBx{->1p->%)PK4I;RZ)xLK75=dwcLpPNblKR7*a?Z{vE^}r zAxZXv>*Dh7)}il#^U%Xtd*Orr`j6HRCnw>fh0c&50>7Tbi?Z7ojZ79DpWsN5SQU3` z(U_boTP7+(kFB$Dm61_xH$B#)P_Nm@o9ktdVyu^^P6-UwGIk2p zNh0pFl^JKK4CB;k{|lA+%+b|{6AWo5cG+26)b5ShD*Js$1#^Md}+6~s>$OSCRv0fsX zk4zQ=porguAz}?^GLc-1xq?WF)QSWzqKew<*^$@r0_yci!C^6hQUgB494@Eka|6Yo zwF!LFU|hCs5JNnk8aj7fjXP(PCa`EtIjXt+{(4R~)^kQ<9mE{%Y}+eo9nAb85SX`Q z(>?3A<_FlM*Rzwr*EciIzG6N5fc5M|*2_+WK-Z;Y1F{(57{BeX-46wAxNK{%Hzs84 z-CVP0@C_M$XAIpz0}^EdiT`UqwrJjf@j0WB#@`beHn%Jcz9^LiPuZS;Oh6_V)gaZ1 zB=US;z6Z0WJZ7z#t5}hJh_ye&x;h){fqdaG3W>T-#@F;|xf(?M4%2gXd8Zw<7T6|) z1=#9Xb_-#DIe%$UW0D>@4}YHFL{uM=iH1oZSsi#c;3?vqiIg$+ zwvBN)4Cgy6dq{4=U-&EEXsCQ}dUX|lkA{mStWzKZm2$#|!)BqaWK(P%vbA8ANf*QY zsYP|NwV>_T@5$DpcFBR((wML@aQd;X-gcUtXSl9n%dtZEYxmHQ0}i_mKVf&+iBx>j z25T|O0Xz7d!=cC16JU6z88IHpsn9;Gb`ym!u1q6Ia1PkA!&>}(p>1~~Urwc1Z>x(U ziYo1Rvr?s=GOHw8Y-Cm1=@z9*r!R+{#GrAk(rRg!D5$gH&U50xr$&@3mG z>hO2bS!w$1N|mx@R;fPHD(&(UrAobJR%t+_RoeAVrAkZ6tWrayRod-trAnujStU-( z`-!DVhAv&#RZhJ}sngP;b>fI(uN|;vNP0T))Ld&k>ooxaW9?4Nm)vbSt7C-)cmUs2 z=*gEMA838-6KC>6T&}w-Kn|#wa{2~QX*;K)m<@16XxDZYb4?V!ac8>0nC?{CWlEHa zKa8)+FJ`dZ-e8@9vbpl4zwF9$RsiFw6<3XmI&;jo>wExnO%%R5o91AiMWeRbPvG0~ z)lRY6%TW$go1MP2`8Z^Pt4UI4Ak31=ni51=9G{g7aeIQAWYKj+(p^>B*be3UO%y(C zP5t}BSr=;|K8G*OvzA!t#B0B>&cZ7Jkk0&#i|cAk|FM4;6MiwwS4zf#mXMa#D-vGa}-2Hiq>TLTm+cfx0^(#u2R0oWid&^9@Svtcx@#TvwCJ zOm__G#II_-duVvFRQ5T zV@rvd8HVvzH#SYxR(^`F@|Wu>&oO5vlDu|gW&>nXt-pptHQvQgV*?Z5RJzHnw4A7L{SvS@{VQW(95R*g04^w%2aw2&Jb-C#t@uL2 z12_O@6CgWfd9j(($*&_HfauJw7fOiLxZGSN7QnHo^)*!8%mVCTh!AyB?qdNQBOXE{ z7Q12x4&WO)vktN`E(+JPve`NHFe`)utX>zt0t=$g}9dRK%(MnISzc0G#zZUNY{NoH4 zq5Iszs$cd@##O(GRw}mYcOvUlC$j7{Kd-R{YVPz(9I47!^V}Rp>^oWJUzC>hPFq;M#-Gs`WPdSb}+i|45 z)W4x307?9{YJOwbnq&J?@S=+x zOk~X?Gq#?ujXsR)f_uObmp!?rIm%fQ|YUG zmA)xlr4b*fbbv)oxm?s&!RE@M-l_TZzM9`$QO)I&z6v#0 zmh?`|*Z6Awor-Ecwv=eu$1tMm#vf%t?^OL}U)8@`N!91MoFOJbdlE-+s@$}!aF+GT zwQ`J}xbwx`@4n7g^ILQ^cNU-AYRknZHZv!%`5W7R(NJqV^W56G^XyB{<5}?u5bKgQ zh>3hbBALZp6NPWlKil93WuX}c)Q<>CPH8wF;DU1dhEk~`Li$Q|oA1Pmq| z?g{x3FyRsS$%?iJI{{{Wk6(2%MH7WDs7#Z8b*As*5Q^CLVcOPS(y^rkH>W2Wa3S|L z)FWVR-@=HUg0n>(lMZY~=eG317IkzK`7P>r51Ve~O<#eXEA#v-BiAb5r!80styRLT zbG`gR5u?1Iwl;bB^G7-ZIN?S%t2*JPY&qbD^%}WVy|8V4I9{>0t>ZnIbc7g*&>ZDy z-5W&_nsQme&eFf<;8wo2kfMpg7pW&1I)Y%Ns;`9h(#!M`2PAe2`p|{%KCo`bCj!As zG_tEGrR&EMU5>_+@W=K*#*Rjd-L&6AvqTRwpuOWnB-ZG%|Gz_r%8AI?c-J1#*d+5i z6xb+n%MPO^zZ0H~(%uR0ZItTxP>%>Q1wdndXpjbRhXx~Y(PD@QjaAADi4SNdIZ{Y7 z!Tq0GKh_y4;C|lGWSGqOHZSC3AjA#^(?F=3RJx=_k$&lOCkhbpG75fLDYzuQz@6Jz zKVi|xb(8=|;W~-{O2D?xJWT@nS*3tvsJf#@WPlV3qzIt80H8Z71tk03DgaXGks^Qw z1pxiLQb3%fRwLvT)}#oa;Q>H*RSHNhkE`Gzg;6O2XmkJ&cfR*O;1%idxN@q7hZLfv z2%yaafPPUaAm65n$T|gue<=cJOaRa?D+Ri1Qz@Xar2snIFpba+ ztO{FG1kuC*qI-3SIJn4JqkR?2cnxHpOH&pYoZ{C%Og9lYb3=z|^7A)SS#x%&au&S7 zx=&Ycjv=z%rSLZn>*wKbB#v45KJB!3mccX1+P{BD(^Y3k_U3`2ph8UH16br_Rbnx+ zH~Sl~7}y)5hxSt8$VtwFIym&9^w9)lD&%flxB>1)Vm5L&re%xbKMi+dgg%SV<$N3y zR&2=OeEcCDcxU0l1yyyH(mcMsI?Rn@ZR>v2-pt$_WC$pAspDgAjFvr^mhG3fd01!b zN_iVzo2m8iUv`?nK#_hOl8oj`R>V zqpCpINN4<-elT)1CxmcDfA@zN-7}x=3BlAns&kq%c9qi2dzc#8<*{SYhM|c$)Nm60 z4_(|c>FlMDef?uPOim!q#=B+lGE@9xL1PT_m5%cZ^vn~LLQ8s}S-)X1 z3OEWqV}x^20M3(@!ja^RJ6uKvM*A!Ce4ZU`WGHY^eo`7EiJ zD!@^w7$cmU0&t$I6pn8rOk~YQA!3YhZVAA7zEU_1_=0LQ8-<23!nrj7=eL!@kt9sm zU^CrwsvA5N62^$<4&q@y6yrK^gY|+AjYGh2>0>XF(K8nsk9v>;HrbBHXXFNyTy1ut zm2MUC964-A-HC5Zr!bDCrp3QA1yso-%`uoQ_Ah4cc2UV2QeMQbaz*6)!}~F3va=Nm z_R$nPS<&8!qQ7a_$Cv#Me`ur2-_+qkG;%dZ7-o9PTEA4Z_Y*Cfph(6sW9Ekjnb0`&;m^qzN^qj8DJV{oREHf#6_ClVf3;NDdTx2Qf4AV zfz)x&g0xTX5cP=R0iIQ0LqBJDD3(ZB{BGr>5@`-2!(&?LDPGqwJRz;}6s^KeF@K{E z`JPu%3PgazL3H8WYMj+jIPgPYlSCD6#BjP6*AdoBfMOzy^cDVWAi$^TaDOMHuZ!!i_$(vMBcdO-`Z38rnBOHdW9}p zX!6sd5Ps^9G79OrzteLzfus*{aDLqC^9Je~@TW7nRx;X5q7~dhb&<&^%?6`r=#x?h z*Uy~r1$QFD_fI;wPS-jI?-ts0sb`erTeZqB;aI7n(SoycrICE&a;M2sr-ZkZ+DDev z@>9vexCGP5Soz#~Q)fJ1thg8W^s_K{B+$9>E5JeR%(vWtF-|m1RMu1cX{CJ|8K;cY3qeH4NS0RyZ964^qmNh`Zh6Dp)*ogw2(-r z29W+E0;F6)R@bKr!4?wf&H<$FMu5~r=S0Ed1jn zj(wxVvK2A`296h710$x7ES0eGgVD3+t_EaxVy}gg$HUkYT zhIE&>{BBFyG?R<(0296=4Zbt5ZlOFm*M*p$&3>qZNMB1|PDIAYx$)dw|BZ0k``~<$ ztI}<*9gK9FX+5a;SwpvlGRILg2fIpzZ2K6cfX|&3Vb#eto_gZHHLh}!!s`L+-@s_* z*^V&;p1Owg@ob^2eIl*hFU$6c&i;e&q6|p3mcoiWG|R?zi6^B&`Zrzq*W=Poa$4{K zO~g3R_B}_3Fp+ne9m+zTw2<8c<>|Hmpa!gk^N(Gv6OCUIdQG0xBk48&My$#sSFRuB zyjwB_u7f^;A-+#)eSh(88gcqN+et4cA<-Ck|qk@1soF} zT#Ql+g?^uSEe-Vb4NAyen>2G8trZzMg)a+*?&bhG9^l=Ecyj)+eU;cGC0kZ42P#BaD2VF< z5L4kG7IqedSl&eEK!qF&h3>Whx|(q43VTGfeJbZ-z7Qemrlh|7egWvxRJsob9Lh$lY%+W(m5!v3_!0$};rgf=+D`NyHd;Z(+< zKu*Pb095`dMC$C8$3{rMj>lj4E}vm~yC+|rNa2Dvl4bJ^-d0GIO6~9r?I7p1_B4+> zmj)NL#28e*UYYrLf9{YPg^}D-rU_$f5U`r5IMb?BU4r_kxH3KQ zHa%hU7-WXEr&w`+&t&Wu6Dik^!VuYKPdrE{_~)blGU9pEI#=Z^4;@ReF~nf4ND2&_s+ z`VlmbjCL?s`B84P&Ja$tAM6;SoWr#8J%c(5^2kNhBL7@_Nqu>P3(u*S6C`Oq-`Lk_ zvf&wqkki;O@|fG4MjeEj@#$#^dyCy?)+Rc$2I9-Tv(qq*)ELOV*C9WRlq{heWJU_j zG&#^M8eEpJ%uaQ@6K3|!pqxx?7L7g7UF)|;Y>MwUGl(U?R~W=H;cusb&j(Zm#+1^- zLAD%kd$F0g$lxpNVwv!F(7@lKRQUEaKXoF<26~01gmI?nr z4g4|Dz&Gyxi!AsRy0c99hic%DjRrm^Y}IZ13Kd!={G&ARw~7Y-*z({nHcSb1GaiK| zEffFo8vJ}XVxaMJ2%Cu{m+S@ph!@!8T-m?VPB~0XE}ILiX^88>rh7k~HH1qDm%y3M zCr)-p_5ur+gvaYpIy0Mb_+()rH&b&The1N6w{639hv8WY z1)pC(HtN8KWl4D?{{Rnr(Evl>8v`t<&o}{s)U}Y2AT=$tmDtb_q-7au84V@ZgjfN| zJ*lKe`P9xpoH$GEo_w5CksjrdTO&NpZY0co1kEicm}8kcl42gkK@>+(Bq@%jIF{l# zie`%ADZIY1CIF_H8ErSjsk$!rF{5R<;9R;O1TQ*C=afo$Q8w^e+1Tqm=GGi2E{!KI z-fl~~F+Q|C+ky~w^Kxiqne7U-iRTH??R6${;`U2Jh{^-yBq2J=)1_47IRLKLCemw0 zE_7)KuZ7>vSi(Sk9sM{4!PGAkI$7u4s75cz;<8`@Kt5-Cu%6HqD8Vx2&c{dA4jiHc~uhGm8z(-=?fWh3Ya%j5S9OFudNtX7CC)Mi<@U)12@goZh?$V zS7NT#@1cWrpi$e>nT$P@{hpRE&e2Ryigf1rDkZDi&YAzMbmj|U;z*Le-FY7!B8Pz8 zN+RL`d?g+@xHrDm1}2X^n?-a@6uz6c<{75t3g1*Z#uV!Bz1O*^D9XSMYPv&km8%Ob zxEvuF=|!_*0y#ArnKJ zVFb;RHOd0(9&9Hy#E8Uo~DJpa^BG*kK1Pc&9M^%Kwj6t#HjXN{=ib3dJ@e%6Tw zd@8;MyH&l<|HL;9mQVd0B5x2KR`t^aUCS3gP0+OeU0vGx2*l84-;8EwSH~X2u$A&d zYo^W-Tm{cW%CN~4Zj}sur?dTpS}qF0pC>2{CR?eIG&J2DsM^X)1B5nJquWsPw>;0% znZ=3E>!ewtk56USwpNbCJAXg#RQ5fU{wgb&{&TNU_CGbtXwQq z7pp?rg~ob90PCF6u!cD_Q2O;R#2-cYDnwmqn5_Yr2bBg>+f*elH@=$TtB`Y{u`UQ; zJvaialB1|9R)v)djrEiO)A^ zBf!ehy1IT<7`M<^PY+-{ECQ@!%fo7V5W8*~p|EVB!JZWWd$kVg=X5JX`s+T0=v=$mS5n^(*X-dpp|h_pad?@ z_%d>5rUhPc?kpt!>xf@2T0r3BH)tNEvw*Y2t2%R5?V|zR7IZS3Q4@uai!S3493ky} z6YbqEWp=dA1C>!`Y=9*k4(K*WBU@%VZOy!t4r!x1+%}o#%8t?5!->c*30L;tJ|58R zI*c@#X=97(qW);IkWRacP76Vj9jkLC{?%aq&4VVI;;(mrgY{QA5Q`jD0mc6qk8aZwuUO+v^oM)H2>oXBDiVQ*eXv3B<;G}w8m5yltnh4 zmE?=<=?j~DD0-@2ht4~`<@tZ-R6iNi#ZUDML*95-z0`J|-@39$XDcU?udiAp zD?8M_yyyB!_Z2_aug}mO1>;|RB_fCJM~9AqkNUlz^%R|(@z-{D&aWs8-zAS>8{wmv@2QqBWD`};@ zMq`1~bQWOUWiM!N1?%T(u6mrCoC}Y`cbfT4)9sYbLct|$OG0-G(XlhKmrc0cWvLDu zK4oJwu$%e=TBL`47gyxrUq)iHl&6`LiTF0vpZWb?%Zg$i1Mt2jp?!T`r8T_=^huA( z^SX?TW{J-&DHH9TD%$)M{&XGMuzY4YC-O;a$aAoaRHkWd9CpiJNkM-fjS?U-&(N90 zSsniuh|H>=z9;=q{Pevto=Z|@WIjqKgkUiHbZ)7X!DRa_<@`OjJ#+G_Wq(a4l$oiC zG7a~l+NAT;<#L^ooY?)+P?!Jp6ZqVoXQ9b&Q9O;LOi#W}PjYnWm$N)m=U@D_ciF`U zkL5YbPy^Hye5;wRG_mm-`mNGg$a_vmyJY2AI>=5)mrYixEkDemdoqG{prMRBWh4(5 zDKmsVrR4%F<=Hyh1;RyPDfRO=-G;;BClZ;4aoyxxx8bm)VLXL7i*tcGKest28sted zE&pbc$dD_{WSL%X&>%lI8sw6f^v&5LL#|MgWg;J@LB1k9a=E#>-&6Hun~w~%!bO$| zdb9@g%J85|I9D%Pq=Pr|9M{ z3b|M&^xX;FCg1XB>|G4tx%!rt#jPD(EiKz}&ttBBes4!-wxcVP8`RXZti>s9+R`Hr zcAngdZHiX5qq}Rel|IeF3O+Z$c_~*{c&!0{Y*VL}wJQz7HMBLFVjGG{6r(6Mr{EoX z))9E!s!=2Ns&bWof^v6!Npf~<*kDuqRnp~zD7QY@i3jbbUqGKw=O zmQ$QXaW=&{6z5W`pjb(9KE(wT7gAhAaWTau6qi!0qPUFWa*EXyS5RC<@pX!CP+UWC zEd}qZv%X1j1I4!}ZlqX4v6kW{if>cgOz|Cx?^4`Cv5w*g6hEZ6jp9cXw^Q6f@nedg zQv8hKPKuvX+(mIW#V;s+NpTOwy%hIRJV5av#X}SiQ#?ZPD8*wGk5fEB@g&7l6i-t; zL-8!da}>{0{FdSciWe#VK=Crgs}!$MyiV~3#h)nNqI zyA=PVc#q`MY)*8t-_$W_nGzA~JD4#TF@p*d|pE_sp0c_Tm6nq$$HHKm=#a0wsQ;etB zhN6*zkLj@ZSO|*`KCmWJOr_wt<`&QNws^p`HJxG?3LXY*?MA_~Vl5t=YVj0Nd8Vet zV<@dAiWwC9Qp}{7MX?{nY>NFU4xl)YVh#n*aItu}iN#Ytthp3CC&D_6f(Hv&ye;24 zl7csSTfEoVI-24b3f`S)9Y?`i)GXe@W$_j#i?;w-CsFV|66<7&R*Lx)Z4`ncO|gKY zonj$H2gM=^ZnmPvABE0;tmRny9g{^PPceT*~(Dx(xS!7Yt|A9US*M&BP{as z7HMmXB&|hC&?4n!ok>Baz&e}a9Ex)(R#0$`Y@J8J>63K<1qW5@B8oy^+ts=_-O`e) z>9MexSh<&S1Y>a|M6Q0%#oeN}GtKEzEb~Ds7TXH@U+WX8gzUEMyT}XjpJ+!{IzApc__BYrvh4*UZdqW_H;WPF1slfl*P@m#A)yZ!d z3OO9#G(gtCu17)IzsBDw_Nn?%-&JRSs-b?+&_Q*Bh7YPAG+9xjVk7g#X zTef9-AlQxx0fhjmEFe@#fd!%piqDD^n{24C3p=Wd9UHu2Ln?)#2U@#+hukvIvVZjVUa~bk@RT7H83k zHrC48uFIostetgSmqy!JC+kAn!Ma%w+D_KXmZ9xp%h?LF-E1Z6L)*hvvDIjM*&4PM z?J{-`TZeWzTh9_`SFjCiBifa$pKU_h$2PMqXjieVY#Z9uY=CV?yN2yx_o7|P?qh>! z?_oo1C)#yv7rP(rdbXQAfHuMQum{m@U=OjqXg9Kb>|wP1Y(G1Ib`v|u4x!!59$|;k zZed5*qiDCXVRjVlHue}hhIW7*XOE-Z&YoZ=(C%PQvXf}772k%cpny^d6ty>(iI{^yNN%g->7U)BAk-DxbdEr?2tp zYkm4XKHYnY^}e2jPv79vH~RE`pT5bbZ}#b1eEL?OzRjl(`1I{QeTPrK*Qej-(+4X$ zlg~&4r*D#{jog$W=i{6ju0Y%r0{$l5jF5XZM)OTq8Ajt&S@`nWFt;np~IHW%eKNa zr-Q{D#gQD@X>sC?=ER(c6J@%iIy$^E%35Z63Y|{ptU3oFQQ4Gi9f9SyxT7%kvWN!vVL( zhMu)dZVg>#<3mSt<5QDn*0zRN(oPQ9JZT!^StFT3-_UV0Yuf4YBbii=r|ol-r>5<5 zx$KZ_TG*eYk<4Urmkc(Q&!oqbwrSun(;CcAyK5)XHdM=)n97bD*_<(!w8zgGRyv!? znCt1@=^-Tf%7N_E)UlZ|{!9dCqb&VNRBLY@o;O#Hj>kJV`8BZVz?jlbjea zCefKqxo!UYa$7;Ekq2P;T;6Rd9dEgDg5I$5$#K(d5xPB{H{G6eHf^VqI3$;!%80AD z%e@O2mYFff>AHs4wS#swU_U9-0IP1N@AtWM>YTgMvn^wC$`&UwCevBtVlor3A$eJB zSRQB}?#l8R#-NencHC{FXD-c7HqlQ)>J;v$)+wPc^1f6V#v7C zHzF)3k()@A4be)Zt%NHN4(M()Kb=Z4S2=!!uO*sQK9zM_DyLO5Cfvg^ZS2X@S$m+D zZy=6{a-JZuoy1lW+emCCv4zAA68$7LLAafQVk0+po?yLb^3}9y4T*KMy)~6I(pk$+ zX2DShQCGQNzJm5p(OGMjE6^9|3D&|>QPVQ?h#kXL-HFU$th|ai zDDjz3KfQCnN*p|xAa(bE#rNV?=M`7Q1`@k(btEke zb+*`H&wxdpd*)lj1H19V`Dt$u<8HTs!6rkt$j5V&}sSkxiR=wHaQ8WGpyuW=06-*P~kuu*=J2D#;d>_Sj!7?9#7Ax`{6*}>)75PRCTjpEG)|NoN zTSf+C&$&ckZ~%A450M~}`6DFA{5jbuq6e~JZ}-PYJ4WI-iN{GiL4ttbPm(xE;wcg| zA^PTkT?<1A_pKdGpT-G_=*AWPEPhp?OCbr((!!J8fdU^A2s=O*u?Kx4Ga781d`fl{ z_?GIZ)*HY@Wl={3*6LOAFV7ONxdO&azB z2#d~Y!a2@jdyIxX{xUS3G(i~YVT83{&$!bZVX;8M`tb<9scT`@T0JLvfsPReHc1@+ z5*<;)&c5c@3GgTbXR|0kt07EQZfQDy3H?=+Q4&z5>=*b!l!=iGW7kT|AJE}ZLXU{C zP0Uq@=v4=^)l94q#U7dybu{>1%!yg=7kw`#d=LFKzLycc2U_?=;cw8&zNeLakMi`m zqYK|_Df(WE&-Y>lR0}Y#`F-!$e33>GawPCDzG!2S&Zi=lY1;MTp6dm9db94hDTHv` zM#UK~;E^l}!#r+vI3#_`PU&$>{MKHf(zkJ@#(tE>UUi6nas22kHwn;% zF`o#-e0Z^#2blhQL_-s%Ps3gn5m9u+@ExWT5Sg}w06MpiQ8MMFT3$G)iYcjas)Z>@#XX6ba9;7!;RJOw zj>P#<+Ak=y-WGzlR}%832vNTHInE#|TN365nr(E?pF{hURq&$XlmmmPcbC)UrRUd%;giaGEQqUTR;{Ik)46xSU;G`D0 zzW`QN{;fs$tN2v~EhQ{v%X}L@DiQEC1XN6cbpqn5WaYX5HzJaiXgOKY%E=0)gI==o zf&kZxeKny|>>Dd4D+rmINLJ#-WMvXJ*94Zu+|Z4R%2u-xQD96vxG?x$>8w(R`v5ms z#GAq#VaikJ3&;C=b$C<80duZJ{Duf#>JcvmFQ-KCLfOWs2wqBvm$Ho@#KW_V65{zL z5iceZHtjAfzS*!OD3Lg_IM4&^{zKe{MI~1XP{4y{`Iqs#IVNUN{GSW6{m+#N&T-T8 z9=vW86(3aEwd9=}_5%xJEG|^63|Gwi54e}IdB;8Tb`}Kn9c(QPCnZpA)Ib6Z{0$mB zP-UX}hkr=XW@BQ)JB{rkiAMb+f(lZ}z)24qQsUUNH7K3t7YWujFa5m&ol{JE=car7 zc3=%K;E!=PWdjD%o&kRqy;TNGK?RxlFzx<(2pecKB_)a$kf=04qDTRW)nrIiULjGB zgT&wqiJTQO&RSDSDvr4nE6idxt*-ojAO`$)5sq|}!;wznOt3=}f>#NAOAPYfY}zSw zFvYrxl|ZahH&F@f^(wz&ZIDwTlhc!m)jn@Ig$it(G6_zz8*e2+KnxV8-i_3eAhB?) z_zLZ^nAim?T(-%4vCE%uhGIa7ihS+oQzZ`WKGE9wYuGQGyN|H-zrh_QkG7czVxemG zekUf6diF|_2MuYWdduGylShfYV%aK?J#X>|s@vZ_dy(3On10~WfI<=O2T>RnIMq=Y z;D3L`buBU?3Ysx$3ZX-N<3JX1pYdlz!#X41G>2WtO95;7sHBxE2}?n5}03wKL* zm4ttpKzcC@sVAC5sAu!`3APvA$eEVGdUwHCrFHus42;ZB@oqEHa1X3@HSDW{ALiq zceAOUBT!!<5d`nykP)C7USHY0)@-MmGTS$UP`$g&_B=rvYPM$D2bq?Wp4L#HRN8au0SS$Z{eo+D5~W5Fkz zMy9c8y+>e?Klw=2k8hf43Gw8vMy9hw=Ram5TY-@H}3; zx0vbFUu+Uf(6wgyA))HU&!GiCD(ljiS7oYIIDdq#cV7GpE%be^W!(mazOd=J9_hv= z{YL_SBd`mr^NDQRtG<4JK?45ItFJGHj5+nB_kB#bBZZB1x=i$e@^onr;%9<8=Op+m$0G# zC@>7Zhx#ft0imrzpQ|63%(1DAc?iCNLNDY-EKT4aJMb?cb)Qcot>uDLsW9cWpTzg- wQG8nUHoZ&l7GF(|;iHRhm%dN$X}CvsymHl&w%9g`yH>@WFZRgN{y4*b0MXRNV*mgE literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_crossover_mutation.cpython-313.pyc b/tests/__pycache__/test_crossover_mutation.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00dbbf23878aafe7d3b2868e238f069f29d18368 GIT binary patch literal 13268 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 G7XJfGB9W^A literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_crossover_mutation.cpython-39-pytest-6.2.5.pyc b/tests/__pycache__/test_crossover_mutation.cpython-39-pytest-6.2.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4086eed4be01576344e060420773f9c6810a2a70 GIT binary patch literal 11705 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 literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_gene_space.cpython-39-pytest-6.2.5.pyc b/tests/__pycache__/test_gene_space.cpython-39-pytest-6.2.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df4ebdd48addfa397602c9d9e28aaf6f0671b957 GIT binary patch literal 48328 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 aDPR68=3eD}=J%QYx_K;rBlY{fg8vV3)}jvp literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_gene_space_allow_duplicate_genes.cpython-39-pytest-6.2.5.pyc b/tests/__pycache__/test_gene_space_allow_duplicate_genes.cpython-39-pytest-6.2.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6c0179f54862a3a9aaec6c50de5f75b4dcb6169 GIT binary patch literal 36759 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 LBPAY!&w2j^d|YVu literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_lifecycle_callbacks_calls.cpython-39-pytest-6.2.5.pyc b/tests/__pycache__/test_lifecycle_callbacks_calls.cpython-39-pytest-6.2.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43e43e911af572b8483a6225e4da4ace6f76b818 GIT binary patch literal 8634 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 Lxpg^TDd+zI3|ZTD literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_save_solutions.cpython-39-pytest-6.2.5.pyc b/tests/__pycache__/test_save_solutions.cpython-39-pytest-6.2.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d68c16ebdeba97702feb2bb689d5ff4ed5480c5c GIT binary patch literal 79242 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

i>V81L}s zPFw#$*j!6uJ&8tJP)c;(%#{*pqv6U&e1P{7o~|8#?0=MKUExXdqb%Ryz-vaHv=dVc z#%;NI@?70a@1&#plH?&DtiFuUEW)av`AYM;zxisO*Y)PBI(vVf+Al8a26CM;K~z(mZvt{ae|CATJEqe-K_6 z)~?vkO{1ugs0X--M+h$rpJ7vgF@B}yO-=BO&U4e2rLu-jEE^r=TX87YbsG61grfVx2N!UM;{5}$?}t9T_mN8$8y38+rwuQUf5)qqKw+l zqeS{NU2o}yO({($uGX4bFi+bEy9knyMfoghbV2pUJQZBCX?(fUtly_Yy-c$nxd6r$ zba>tidoJj5ys`hp573T3_CK;RCgIO&{K@2Xu#ef$uQBX-^i}*SoUgYS`kVP{Be-qh zFHOSDfj&9j0{XY`h~Us)g~zM9c%lC~pNVw&FFuphMTI`?n;-)a$MdM*(0>Mxcl6Og zp8|*y`Zx30bkM(-M+xZD^*%DtuTl1+bD;m%2uie$?j{(`RPY+z6UP(c-4A@FD8+v_ z)o^I}clg($`@*)q)qtEV+r>i1nBjg90XcJNnBJmM3mx?qO^`yzC5RQLu&}t$QE$=I zf*K+-Su{Zk9iMRNBku?G?lW05?xJ;*MKj7mN8>Dj>n6?(aO7glTJA5sgxAIW|Cews zmre@2FPBbU)8X5;*llx1Er6`XeeNpe&Nwi4Y%jB@n3scduOKwaX~b(oCXUlNN`oeZ z)|tzW_ZT#Xb-*q*XjEWRWv>8t#h@w8w@_{QF=o(=0Pa`I4DL-jGsO?wqcK$K2W(FGTB_iRiIX!J|>wf7TNO_5&N2TYt}Rm<`ZoLUESHP-i&oAzL-BQ z*}s!M!rW9QleV&5eZ6z7^z~L(Hl44rU&>b(Ub8NtcRPy&zxhejJDJ2x5=%+6khp@x zMiN(%xSGUf5=j!*l1PyN5*;KuNo*m}MPeI?ZW28t`bb+`FNym|+)rYd!~-P0OyVmfzDDBfB)&o7Arjvt@huV$llV4??~tH} zAX(of@jVickoZ1{M@c+J;s+!SlA!GxtwSV!MB>LJenNuw@UVVLf=a}#r%C*r#4{wQ ze8>6)2}((~o+a@s63>yK%pogJg4V087f8HF;w2I7VG-?`S9M4VB`_TE-|Kk0M x-&Y*%mO>|zq+4C0f!oQok$5=Z|Ehq;h2znqaO6mzGWe$%>79dr+7aIQ{{zdC#UlU! literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_stop_criteria.cpython-39-pytest-6.2.5.pyc b/tests/__pycache__/test_stop_criteria.cpython-39-pytest-6.2.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba5a05322928fbb2bc82c53cddaa10ef0403b0af GIT binary patch literal 7129 zcmcIo&2Jmm5#KK^mlP%WQ_J$f1WGdXR%2DxilHXzxAs)cynSTA%dQkB`D8>M zj>sbs`BX$c9g)vOQuc_59 z{dcCJVw-rYaT=vO6~l`VORv6(kGq7VAg!u(`JVLi+^XhDYjR!llw;C!c{LW4R8i7F z##`KPt7 z|MJzHw83NLTB*9sRkv2+hZbw)yysNPrcfkr@~jDuS+MR0&@{KtXs^4*aVICEveV;7PT`zpyceMI_+kh0k62+2o@93ygq$RLp+A}5K^sQP3CB|h9T2IWe07|vh^ zR|Mzg5U>ug(*QKVK8uAW*fRmx!@=+kRT17=1jsr98BN^;v2U>6Zt$k9hw&$!wvx}- z01~eI_~P-vw04t+T1@uc?mFc{(Y}PQyEMF^-v{KB%+6xD#pmSjrq9Q)(CTyHPqnVL zn5osZ(3i1oO-skxJxDHKqeR;LHqv55({H{V`~A+=jqr>^Wv)s`krTa2~fRcJyBN({B@}=*VVdKH$VaH zS>I~1o?PpBj*A&c7~Er7b{_SbZ;+koKHiTp&csMyGmB!6%X=`^m{psZ)k>8o!d90b zA+c&P3M6I;JC_SQ6&+1}BrJv4Sh0C;spg3fo8EHO<^#WOVvO}prL zj#~;!!M}KKO90}>{d&{2i?$z-#g~s_wN)(Is5`6VF({ILhuvDW%CKO5Y_T%dxakzv zME_WIxnKcT?%(A{saJ)07_%MJh?-q7VFdt0>=IyRX&f?kg~&A|TxGR#x`$0s1+A5g z@WWmsa)ZbOkx3-HUxY`qvhbKxermI6YPwEMDO>_7RnI9oD>iFK>xs7a$hL)|U82vs z^h+r@ih)*Fba_y44JBo}``>!Mp|CsnR-RssUd?Gqkhtaq?~9v!CIYT>}Zl5;WxnyNmMn z3RCC`6jnej5adIpW7#>bdrQo=KwzHDU|%*%WHTyk>O9kh&RZyK`hPH|Ec|dpbNvOQ zD6m(}*&FzB1Gnzdt5rL**rE1Y`&C=)?_RCi(@#3op6gC+Li=J?)upR6A_AzjqtvU(SXP4#)<7=eHT!Y8^Jc-JMMsZnl`e@gSOaGl6IK zXj1SCb84kS_wVmRclJGencX9@bKu#p-kD!?=>3Cz>rDr{SFAUl%-bX8JKgEM!yFca z-i7jS?-MM|N&I<-5%2EZh+q_?w1x zEj!N*TzxUrO--&V{`Ns^k7n_mE!W`px-h7HPt>wK#M3G>{oTCz)GF5OUy*wLo*wrT z8|+6|?pTv|v?EP+^n`YpnMw8@sXt3(t9``1gRtS(`1PpT^H_d)wZG}})xJJ8K50&l zPw%4nI|re;33lEoS;gP9S@7c>EjWg)A%MgtE&vgpSLWG6Y|JHmQ>M+#E>^s?Z!3z9 z>#gBGn-0)7*aukN-T^zR|31FDk_y$oo*BQniv{lm3N zO*5VFx04sJHk)M^k+DleE+d)CrpLLlP;)S$iRqBkY<1aemWIsgGHE()xtLz1gvmIw zKc?I$Pc*AI`p&OQ;>*G?i?N&Z1Ih~Wi&oyNSw)i)D&eWvKO+Y@C6lrte01Axcybm! zw*OE|I%St`em=!*%Wg!{rOiyKp9-N=rk@X?{Ft8upfkES?lL+&GCGPeI?FKH{4?4` zGuo0e+TStSA2Hfbh{c%AlSHe7h_Q^qlbHOBrjS4)3*A??O15e8Se0R-X3NFbxLvA1 zt!Uq&w4F<^J|`QBhPed1eXbaoD#23BNE&g&Fmz0fwch_rjv28nZr#w@@1(5LtqSVP JA>Cu${{a~Ttx*5~ literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_stop_criteria.cpython-39.pyc b/tests/__pycache__/test_stop_criteria.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3627d313eb77e5316331d52192669cf1c577f770 GIT binary patch literal 7020 zcmcIo&2QYs73bG-xvSNOC0QSqY|GzXC)UTtO621xWl()KjQc)M>oe1xY;v8l=7u^lnH)7wR6!KsV}M=z(6;eQ+Cw zVE7ABKL#T(iZ%Uk0>)4ez&M;lJqV}ZH0t9p0cTJT!C5$mdKk{b1=J&O5iX$~h0Bmd zeFCn)E2zidRk(_J94283^+}k98PumB2d|+%4cA~6^#r^QZ=gN{*Wm{0v+yRoh58)a zgtt+jhg&d*`hs;4<{wF4O037a^tm7kRzH`4JrJ`8WA^cwJruKtWA;eQ9*x;2V)j_f z9*@~4WA>?-eL7}O#OyOM`)tfU7qidD>FED+R%I$y7MJ<)k2(8Wx*L@KJGUw0J^s|@DYObyj1J-@ zJ^C(Q?h1;cuqM~VJHpTOHN_Lw#k%52gTga$EfJPvUQ$8CvQkfYi4nXD(y%ZltR=%* z)l*}&T3udG){}LuC_NKJ;ZrQ%7dGU4i0EH)#i#%L)B3l6`Q}zu^Ak?3Tz%rpZmsP1 zE!UiaXIC7`n_PeHnYH})I4lB(^`@9RkK>P9LT2puA+&rb3M~3 zSia^~N;Ud|pNTBPhR=L)89k_!{ABdP(8&4Pvh6vRi@rowZbM*W*mK|MQy;q)bEiIo z!qlBgp;opW&z%C(Gp9UeT1LS!%p%rJ-L)LcvkSLN#R{{%mGZqO-b%%p@+=qIlQdkf zQZ)*A(_*$ciTyDWe%7EaF_uiPuws;JCC@%if$Kvdh>EC*J$Me`*(b7-Sl1NmBvufs zc&zWC!6Pb$@s-0;5ML#Xq}&wWL|Cgd#aFE->S|HCFEC(}7CaPlB~PJ)Db(o@z_pFZ#sYbobSOWOy$t->CJ zZFNt@R*IKgOVRs0%}asorR%A>MC7jvb+InjmAVEJC{KIV()ILu*E9T?fq=<9k!R=7 zufUVn(%6)l<=3*Y78@YBEYBMj0DBML!eoO}{@X zMci1m{O)qi<1aS6CsoTIY83Gc1$-6%wCiUcSyt7sO15Xa<**cf%kOSVK>qQd-f*pw z6(nT-<^ilWOC<|^XO#jbMf6WU=GLlJh6Us2CUdaH&1QUsw@*}`6iv{jySMcLYE@w# z=4=~1qT4PXu$%xqcX2YaEOr^YLgEz^zRYS)wu?sL$Qn7nupzVScryS=4s3}0T``~eSmWvO z2LE#)W0sIe1&oVpMC54vM{)4&5VN1+n_UeB00j>O)H=dga~e$nRl!lC`9h22Z`8&~G78S`#ue(y1cd8c>a{QHL_OJflKvJJ%h z2L}-j;!Z*Q?RG=)pUdLZyZ4{@9%ch%U`#+|M8yg@5z@R;G=pn}v+@TiA|aWK+R(@;uh&^XvjDc9Fy-6bt$6W%fFi zXbVrjU>3ZZSu$w%BU-`+3)*l4$e^tYePY*UxXk4(c7IWP?_-be@n*s1hug9h5!>5r zY-W%D#%MCb=;zP>oQ(cM zj8ZvIh>UUxAE}J^&S}G<%5Ya@#}&7Bvs{5%$+|^*Y%Xz76E#V}g+HEw qmav9O2`#N9HBD1-AFKKNU;46^*x^()rS(jUDxETyfgQ;M*8LyApnb3a literal 0 HcmV?d00001 diff --git a/tests/test_crossover_mutation.py b/tests/test_crossover_mutation.py index acc3894..53aa089 100644 --- a/tests/test_crossover_mutation.py +++ b/tests/test_crossover_mutation.py @@ -68,8 +68,9 @@ def fitness_func_no_batch_multi(ga, solution, idx): ga_instance.run() comparison_result = [] + initial_population_list = ga_instance.initial_population.tolist() if hasattr(ga_instance.initial_population, 'tolist') else ga_instance.initial_population for solution_idx, solution in enumerate(ga_instance.population): - if list(solution) in ga_instance.initial_population.tolist(): + if list(solution) in initial_population_list: comparison_result.append(True) else: comparison_result.append(False) @@ -78,27 +79,34 @@ def fitness_func_no_batch_multi(ga, solution, idx): result = numpy.all(comparison_result == True) print(f"Comparison result is {result}") + print(f"Initial population: {ga_instance.initial_population[:2]}") + print(f"Final population: {ga_instance.population[:2]}") + print(f"Differences found at indices: {numpy.where(comparison_result == False)[0]}") + return result, ga_instance def test_no_crossover_no_mutation(): - result, ga_instance = output_crossover_mutation() + result, ga_instance = output_crossover_mutation(initial_population=initial_population) assert result == True def test_no_crossover_no_mutation_gene_space(): - result, ga_instance = output_crossover_mutation(gene_space=range(10)) + result, ga_instance = output_crossover_mutation(gene_space=range(10), initial_population=initial_population) assert result == True def test_no_crossover_no_mutation_int_gene_type(): - result, ga_instance = output_crossover_mutation(gene_type=int) + result, ga_instance = output_crossover_mutation(gene_type=int, initial_population=initial_population) assert result == True def test_no_crossover_no_mutation_gene_space_gene_type(): + # Create a compatible initial population with float type + float_initial_population = [[float(x) for x in ind] for ind in initial_population] result, ga_instance = output_crossover_mutation(gene_space={"low": 0, "high": 10}, - gene_type=[float, 2]) + gene_type=float, + initial_population=float_initial_population) assert result == True @@ -113,11 +121,22 @@ 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]], + initial_population=initial_population) 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]]) + # Create a compatible initial population matching the gene_type specifications + nested_initial_population = [] + gene_types = [int, float, numpy.float64, float, float, numpy.int16, numpy.float32, int, float, float] + for ind in initial_population: + new_ind = [] + for i, val in enumerate(ind): + new_ind.append(gene_types[i](val)) + nested_initial_population.append(new_ind) + # Fix gene_type format + fixed_gene_type = [(int, 0), (float, 0), (numpy.float64, 0), (float, 3), (float, 4), (numpy.int16, 0), (numpy.float32, 1), (int, 0), (float, 0), (float, 3)] + result, ga_instance = output_crossover_mutation(gene_type=fixed_gene_type, initial_population=nested_initial_population) assert result == True @@ -143,9 +162,18 @@ def test_no_crossover_no_mutation_initial_population(): assert result == True def test_no_crossover_no_mutation_initial_population_nested_gene_type(): - 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]]) + # Create a compatible initial population matching the gene_type specifications + nested_initial_population = [] + gene_types = [int, float, numpy.float64, float, float, numpy.int16, numpy.float32, int, float, float] + for ind in initial_population: + new_ind = [] + for i, val in enumerate(ind): + new_ind.append(gene_types[i](val)) + nested_initial_population.append(new_ind) + # Fix gene_type format + fixed_gene_type = [(int, 0), (float, 0), (numpy.float64, 0), (float, 3), (float, 4), (numpy.int16, 0), (numpy.float32, 1), (int, 0), (float, 0), (float, 3)] + result, ga_instance = output_crossover_mutation(initial_population=nested_initial_population, + gene_type=fixed_gene_type) assert result == True