def genetic_algorithm(instance, config, fitness_function, *, best_fitness=None, perf_counter=None, process_time=None, all_fitness=None): population_size = config.population_size population = np.random.randint(2, size=(population_size, instance.num_materials), dtype=bool) # selection_quant = 2 # if (config.crossover_method == Crossover.THREE_PARENT_CROSSOVER): # selection_quant = 3 timer = Timer( ) ######################################################################################################## start_perf_counter = time.perf_counter() start_process_time = time.process_time() for iteration in range(config.num_iterations): timer.add_time( ) ######################################################################################################## # print('==========================' + str(iteration)) survival_values = np.apply_along_axis(fitness_function, 1, population, instance, timer, data=all_fitness) sorted_indices = np.argsort(survival_values) population = population[sorted_indices] survival_values = survival_values[sorted_indices] if best_fitness is not None: best_fitness[iteration] = survival_values[0] # best_fitness[iteration] = np.mean(survival_values) # best_fitness[iteration] = survival_values[-1] if perf_counter is not None: perf_counter[iteration] = time.perf_counter() - start_perf_counter if process_time is not None: process_time[iteration] = time.process_time() - start_process_time new_population = copying_gene(population, config.copying_method, config) if config.use_local_search: new_population = local_search_gene(new_population, fitness_function, config.local_search_method, config) remaining_spots = np.random.randint( 2, size=(population_size - new_population.shape[0], instance.num_materials), dtype=bool) remaining_spots = population_size - len(new_population) selection_spots = remaining_spots if (config.crossover_method == Crossover.THREE_PARENT_CROSSOVER): selection_spots = int(3 * math.ceil(remaining_spots / 3.)) * 3 elif (config.crossover_method == Crossover.UNIFORM_CROSSOVER): selection_spots = int(2 * math.ceil(remaining_spots / 2.)) * 2 else: selection_spots = int(2 * math.ceil(remaining_spots / 2.)) parents = selection_gene(population, survival_values, selection_spots, config.selection_method, config) # children = crossover_gene(parents, remaining_spots, config.crossover_method, config) children = crossover_gene(parents, config.crossover_method, config) assert parents.shape[0] == remaining_spots mutated = mutation_gene(children, config.mutation_method, config) np.append(new_population, mutated, axis=0) return (0, 0)
def particle_swarm_optmization(instance, config, fitness_function, out_info=None): num_particles = config.num_particles if config.evaluator == Evaluator.FIXED_EVALUATOR: evaluate_function = evaluate_population_fixed else: evaluate_function = evaluate_population_random def counter_fitness(individual, instance, student, timer, print_results=False, data=None): nonlocal cost_counter cost_counter += 1 return fitness_function(individual, instance, student, timer, print_results, data=data) if out_info is not None: out_info['best_fitness'] = [] out_info['partial_fitness'] = [] out_info['perf_counter'] = [] out_info['process_time'] = [] out_info['cost_value'] = [] results = [] for student in range(instance.num_learners): cost_counter = 0 iteration_counter = 0 stagnation_counter = 0 if out_info is not None: out_info['best_fitness'].append([]) out_info['partial_fitness'].append([]) out_info['perf_counter'].append([]) out_info['process_time'].append([]) out_info['cost_value'].append([]) timer = Timer() timer.add_time() particle_velocity = np.random.rand(num_particles, instance.num_materials) * (2 * config.max_velocity) - config.max_velocity particle_position = evaluate_function(particle_velocity) local_best_position = np.copy(particle_position) local_best_fitness = np.apply_along_axis(counter_fitness, 1, local_best_position, instance, student, timer) global_best_index = np.argmin(local_best_fitness, axis=0) global_best_position = np.copy(local_best_position[global_best_index]) global_best_fitness = local_best_fitness[global_best_index] timer.add_time("initialization") start_perf_counter = time.perf_counter() start_process_time = time.process_time() while ((not config.cost_budget or cost_counter < config.cost_budget) and (not config.num_iterations or iteration_counter < config.num_iterations) and (not config.max_stagnation or stagnation_counter < config.max_stagnation)): old_global_best_fitness = global_best_fitness if out_info is not None: out_info["best_fitness"][-1].append(global_best_fitness) fitness_function(global_best_position, instance, student, timer, data=out_info["partial_fitness"][-1]) out_info["perf_counter"][-1].append(time.perf_counter() - start_perf_counter) out_info["process_time"][-1].append(time.process_time() - start_process_time) out_info["cost_value"][-1].append(cost_counter) timer.add_time() local_influence = np.tile(config.local_influence_parameter * np.random.random(num_particles), (instance.num_materials, 1)).T global_influence = np.tile(config.global_influence_parameter * np.random.random(num_particles), (instance.num_materials, 1)).T local_distance = local_best_position.astype(int) - particle_position.astype(int) global_distance = global_best_position.astype(int) - particle_position.astype(int) particle_velocity = (config.inertia_parameter * particle_velocity + local_influence * local_distance + global_influence * global_distance) particle_velocity = np.clip(particle_velocity, -config.max_velocity, config.max_velocity) timer.add_time("update_velocity") # Calcula as novas posições particle_position = evaluate_function(particle_velocity) timer.add_time("update_position") # Calcula os novos resultados particle_new_fitness = np.apply_along_axis(counter_fitness, 1, particle_position, instance, student, timer) timer.add_time("update_fitness") # Calcula a mascara de melhores valores para cada particula change_mask = (particle_new_fitness < local_best_fitness) # Altera o melhor resultado de cada particula local_best_position[change_mask] = np.copy(particle_position[change_mask]) local_best_fitness[change_mask] = particle_new_fitness[change_mask] # Encontra o melhor resultado entre todas as particulas global_best_index = np.argmin(local_best_fitness) global_best_position = np.copy(local_best_position[global_best_index]) global_best_fitness = local_best_fitness[global_best_index] iteration_counter += 1 if global_best_fitness < old_global_best_fitness: stagnation_counter = 0 else: stagnation_counter += 1 timer.add_time("update_best") if out_info is not None: out_info["best_fitness"][-1].append(global_best_fitness) fitness_function(global_best_position, instance, student, timer, data=out_info["partial_fitness"][-1]) out_info["perf_counter"][-1].append(time.perf_counter() - start_perf_counter) out_info["process_time"][-1].append(time.process_time() - start_process_time) out_info["cost_value"][-1].append(cost_counter) results.append((global_best_position, global_best_fitness)) return results
def prey_predator_algorithm_discrete(instance, config, fitness_function, out_info=None): population_size = config.population_size if config.max_steps > instance.num_materials: config.max_steps = instance.num_materials if config.min_steps > config.max_steps: config.min_steps = config.max_steps def counter_fitness(individual, instance, student, timer, print_results=False, data=None): nonlocal cost_counter cost_counter += 1 return fitness_function(individual, instance, student, timer, print_results, data=data) if out_info is not None: out_info["best_fitness"] = [] out_info["partial_fitness"] = [] out_info["perf_counter"] = [] out_info["process_time"] = [] out_info["cost_value"] = [] results = [] for student in range(instance.num_learners): cost_counter = 0 iteration_counter = 0 stagnation_counter = 0 if out_info is not None: out_info['best_fitness'].append([]) out_info['partial_fitness'].append([]) out_info['perf_counter'].append([]) out_info['process_time'].append([]) out_info['cost_value'].append([]) timer = Timer() population = np.random.randint(2, size=(population_size, instance.num_materials), dtype=bool) population_best_individual = population[0] population_best_fitness = counter_fitness(population[0], instance, student, timer) start_perf_counter = time.perf_counter() start_process_time = time.process_time() while ((not config.cost_budget or cost_counter < config.cost_budget) and (not config.num_iterations or iteration_counter < config.num_iterations) and (not config.max_stagnation or stagnation_counter < config.max_stagnation)): timer.add_time() survival_values = np.apply_along_axis(counter_fitness, 1, population, instance, student, timer) sorted_indices = np.argsort(survival_values) population = population[sorted_indices] survival_values = survival_values[sorted_indices] iteration_counter += 1 if survival_values[0] < population_best_fitness: population_best_individual = population[0] population_best_fitness = survival_values[0] stagnation_counter = 0 else: stagnation_counter += 1 if out_info is not None: out_info["best_fitness"][-1].append(population_best_fitness) fitness_function(population_best_individual, instance, student, timer, data=out_info["partial_fitness"][-1]) out_info["perf_counter"][-1].append(time.perf_counter() - start_perf_counter) out_info["process_time"][-1].append(time.process_time() - start_process_time) out_info["cost_value"][-1].append(cost_counter) new_population = np.copy(population) timer.add_time("creation") # Cria as mascaras para separar os diferentes tipos de individuo best_prey_mask = np.zeros(population_size, dtype=bool) best_prey_mask[0] = True predator_mask = np.zeros(population_size, dtype=bool) predator_mask[-1] = True follow_mask = (np.random.rand(population_size) < config.follow_chance) run_mask = ~follow_mask follow_mask[best_prey_mask] = False # Ignora as melhores presas follow_mask[predator_mask] = False # Ignora os predadores run_mask[best_prey_mask] = False # Ignora as melhores presas run_mask[predator_mask] = False # Ignora os predadores timer.add_time() follow_indices = np.where(follow_mask)[0] follow_quant = len(follow_indices) population_distance = [[hamming_distance(population[j], population[i]) / instance.num_materials for j in range(i)] for i in follow_indices] survival_ratio = [[survival_values[j] / survival_values[i] for j in range(i)] for i in follow_indices] follow_chance = [[(2 - config.follow_distance_parameter * population_distance[i][j] - config.follow_survival_parameter * survival_ratio[i][j]) / 2 for j in range(follow_indices[i])] for i in range(follow_quant)] roulette_array = np.array([Roulette(follow_chance[i]) for i in range(follow_quant)]) timer.add_time("follow_chance") # TODO(andre:2018-05-28): Garantir que max_steps nunca é maior do que o numero de materiais # TODO(andre:2018-12-20): Verificar o calculo do número de passos. Ele está usando a distância até a proxima presa e não a distância até o predador num_steps = np.round(config.max_steps * np.random.rand(follow_quant) / np.exp(config.steps_distance_parameter * np.array([i[-1] for i in population_distance]))) new_population[follow_mask] = move_population_roulette(new_population[follow_mask], num_steps, roulette_array, population) timer.add_time("follow_roulette") num_steps = np.round(config.min_steps * np.random.rand(follow_quant)) new_population[follow_mask] = move_population_random(new_population[follow_mask], num_steps) timer.add_time("follow_random") num_steps = np.round(config.max_steps * np.random.rand(np.count_nonzero(run_mask))) new_population[run_mask] = move_population_random_complement(new_population[run_mask], num_steps, population[-1]) timer.add_time("run") new_population[best_prey_mask] = move_population_local_search(new_population[best_prey_mask], counter_fitness, config.min_steps, config.local_search_tries, instance, student, timer) timer.add_time() num_steps = np.round(config.max_steps * np.random.rand(np.count_nonzero(predator_mask))) new_population[predator_mask] = move_population_random(new_population[predator_mask], num_steps) timer.add_time("predator_random") num_steps = np.round(config.min_steps * np.random.rand(np.count_nonzero(predator_mask))) worst_prey = np.repeat(population[-2][np.newaxis, :], np.count_nonzero(predator_mask), axis=0) new_population[predator_mask] = move_population_direction(new_population[predator_mask], num_steps, worst_prey) timer.add_time("predator_follow") population = new_population survival_values = np.apply_along_axis(counter_fitness, 1, population, instance, student, timer) sorted_indices = np.argsort(survival_values) population = population[sorted_indices] survival_values = survival_values[sorted_indices] if out_info is not None: out_info["best_fitness"][-1].append(population_best_fitness) fitness_function(population_best_individual, instance, student, timer, data=out_info["partial_fitness"][-1]) out_info["perf_counter"][-1].append(time.perf_counter() - start_perf_counter) out_info["process_time"][-1].append(time.process_time() - start_process_time) out_info["cost_value"][-1].append(cost_counter) results.append((population_best_individual, population_best_fitness)) return results
def particle_swarm_optmization(instance, config, fitness_function, *, best_fitness=None, perf_counter=None, process_time=None, all_fitness=None): num_particles = config.num_particles timer = Timer() ######################################################################################################## timer.add_time() ######################################################################################################## particle_velocity = np.random.rand(num_particles, instance.num_materials) * (2 * config.max_velocity) - config.max_velocity particle_position = generate_particle_position(particle_velocity) local_best_position = np.copy(particle_position) local_best_fitness = np.apply_along_axis(fitness_function, 1, local_best_position, instance, timer, data=all_fitness) global_best_index = np.argmin(local_best_fitness, axis=0) global_best_position = np.copy(local_best_position[global_best_index]) global_best_fitness = local_best_fitness[global_best_index] timer.add_time("initialization") ######################################################################################################## start_perf_counter = time.perf_counter() start_process_time = time.process_time() for iteration in range(config.num_iterations): if best_fitness is not None: best_fitness[iteration] = global_best_fitness # best_fitness[iteration] = np.mean(survival_values) # best_fitness[iteration] = survival_values[-1] if perf_counter is not None: perf_counter[iteration] = time.perf_counter() - start_perf_counter if process_time is not None: process_time[iteration] = time.process_time() - start_process_time timer.add_time() ######################################################################################################## # TODO(andre:2018-04-18): Atualizar velocidade local_influence = np.tile(config.local_influence_parameter * np.random.random(num_particles), (instance.num_materials, 1)).T global_influence = np.tile(config.global_influence_parameter * np.random.random(num_particles), (instance.num_materials, 1)).T local_distance = local_best_position.astype(int) - particle_position.astype(int) global_distance = global_best_position.astype(int) - particle_position.astype(int) # print(particle_velocity[0]) particle_velocity = (config.inertia_parameter * particle_velocity + local_influence * local_distance + global_influence * global_distance) particle_velocity = np.clip(particle_velocity, -config.max_velocity, config.max_velocity) timer.add_time("update_velocity") ######################################################################################################## # Calcula as novas posições particle_position = generate_particle_position(particle_velocity) timer.add_time("update_position") ######################################################################################################## # Calcula os novos resultados particle_new_fitness = np.apply_along_axis(fitness, 1, particle_position, instance, timer, data=all_fitness) timer.add_time("update_fitness") ######################################################################################################## # Calcula a mascara de melhores valores para cada particula change_mask = (particle_new_fitness < local_best_fitness) # Altera o melhor resultado de cada particula local_best_position[change_mask] = np.copy(particle_position[change_mask]) # local_best_position[change_mask] = particle_position[change_mask] local_best_fitness[change_mask] = particle_new_fitness[change_mask] # Encontra o melhor resultado entre todas as particulas global_best_index = np.argmin(local_best_fitness) global_best_position = np.copy(local_best_position[global_best_index]) global_best_fitness = local_best_fitness[global_best_index] timer.add_time("update_best") ######################################################################################################## print("Tempo: ") print(timer.get_time()) print("Iterações: ") print(timer.get_iterations()) # print(timer.get_iteration_time()) print("Tempo total: {}".format(timer.get_total_time())) if best_fitness is not None: best_fitness[-1] = global_best_fitness # best_fitness[iteration] = np.mean(survival_values) # best_fitness[iteration] = survival_values[-1] if perf_counter is not None: perf_counter[-1] = time.perf_counter() - start_perf_counter if process_time is not None: process_time[-1] = time.process_time() - start_process_time # fitness_function(global_best_position, instance, timer, True) return (global_best_position, global_best_fitness)
def prey_predator_algorithm(instance, config, fitness_function, *, best_fitness=None, perf_counter=None, process_time=None): population_size = config.population_size population = np.random.randint(2, size=(population_size, instance.num_materials), dtype=bool) timer = Timer( ) ######################################################################################################## start_perf_counter = time.perf_counter() start_process_time = time.process_time() for iteration in range(config.num_iterations): timer.add_time( ) ######################################################################################################## # print('==========================' + str(iteration)) survival_values = fitness_function(population, instance, timer) sorted_indices = np.argsort(survival_values) population = population[sorted_indices] survival_values = survival_values[sorted_indices] # print('Survival values:\n{}\n'.format(survival_values)) if best_fitness is not None: best_fitness[iteration] = survival_values[0] # best_fitness[iteration] = np.mean(survival_values) # best_fitness[iteration] = survival_values[-1] if perf_counter is not None: perf_counter[iteration] = time.perf_counter() - start_perf_counter if process_time is not None: process_time[iteration] = time.process_time() - start_process_time new_population = np.copy(population) timer.add_time( "creation" ) ######################################################################################################## # Cria as mascaras para separar os diferentes tipos de individuo best_prey_mask = np.zeros(population_size, dtype=bool) best_prey_mask[0] = True predator_mask = np.zeros(population_size, dtype=bool) predator_mask[-1] = True follow_mask = (np.random.rand(population_size) < config.follow_chance) run_mask = ~follow_mask follow_mask[best_prey_mask] = False # Ignora as melhores presas follow_mask[predator_mask] = False # Ignora os predadores run_mask[best_prey_mask] = False # Ignora as melhores presas run_mask[predator_mask] = False # Ignora os predadores # print('Best prey mask: {}'.format(best_prey_mask)) # print(' Predator mask: {}'.format(predator_mask)) # print(' Follow mask: {}'.format(follow_mask)) # print(' Run mask: {}'.format(run_mask)) timer.add_time( ) ######################################################################################################## follow_indices = np.where(follow_mask)[0] follow_quant = len(follow_indices) population_distance = [[ hamming_distance(population[j], population[i]) / instance.num_materials for j in range(i) ] for i in follow_indices] survival_ratio = [[ survival_values[j] / survival_values[i] for j in range(i) ] for i in follow_indices] follow_chance = [[ (2 - config.follow_distance_parameter * population_distance[i][j] - config.follow_survival_parameter * survival_ratio[i][j]) / 2 for j in range(follow_indices[i]) ] for i in range(follow_quant)] roulette_array = np.array( [Roulette(follow_chance[i]) for i in range(follow_quant)]) timer.add_time( "follow_chance" ) ######################################################################################################## # TODO(andre:2018-05-28): Garantir que max_steps nunca é maior do que o numero de materiais num_steps = np.round( config.max_steps * np.random.rand(follow_quant) / np.exp(config.steps_distance_parameter * np.array([i[-1] for i in population_distance]))) new_population[follow_mask] = move_population_roulette( new_population[follow_mask], num_steps, roulette_array, population) timer.add_time( "follow_roulette" ) ######################################################################################################## # num_steps = np.round(config.min_steps * np.random.rand(population_size)) # new_population = move_population_random(new_population, num_steps, follow_mask) num_steps = np.round(config.min_steps * np.random.rand(follow_quant)) new_population[follow_mask] = move_population_random( new_population[follow_mask], num_steps) timer.add_time( "follow_random" ) ######################################################################################################## # num_steps = np.round(config.max_steps * np.random.rand(population_size)) # new_population = move_population_random_complement(new_population, num_steps, population[-1], run_mask) num_steps = np.round(config.max_steps * np.random.rand(np.count_nonzero(run_mask))) new_population[run_mask] = move_population_random_complement( new_population[run_mask], num_steps, population[-1]) timer.add_time( "run" ) ######################################################################################################## new_population[best_prey_mask] = move_population_local_search( new_population[best_prey_mask], fitness_function, config.min_steps, config.local_search_tries, instance, timer) timer.add_time( ) ######################################################################################################## # num_steps = np.round(config.max_steps * np.random.rand(population_size)) # new_population = move_population_random(new_population, num_steps, predator_mask) num_steps = np.round(config.max_steps * np.random.rand(np.count_nonzero(predator_mask))) new_population[predator_mask] = move_population_random( new_population[predator_mask], num_steps) timer.add_time( "predator_random" ) ######################################################################################################## # num_steps = np.round(config.min_steps * np.random.rand(population_size)) # worst_prey = np.repeat(population[-2][np.newaxis, :], population_size, axis=0) # new_population = move_population_direction(new_population, num_steps, worst_prey, predator_mask) num_steps = np.round(config.min_steps * np.random.rand(np.count_nonzero(predator_mask))) worst_prey = np.repeat(population[-2][np.newaxis, :], np.count_nonzero(predator_mask), axis=0) new_population[predator_mask] = move_population_direction( new_population[predator_mask], num_steps, worst_prey) timer.add_time( "predator_follow" ) ######################################################################################################## # new_survival_values = fitness_function(new_population, instance, timer) # print('Old population:\n{}\n'.format(population)) # print('New population:\n{}\n'.format(new_population)) # print('Comparison:\n{}\n'.format(population == new_population)) # print('Old survival values:\n{}\n'.format(survival_values)) # print('New survival values:\n{}\n'.format(new_survival_values)) population = new_population print("Tempo: ") print(timer.get_time()) print("Iterações: ") print(timer.get_iterations()) # print(timer.get_iteration_time()) print("Tempo total: {}".format(timer.get_total_time())) survival_values = fitness_function(population, instance, timer) sorted_indices = np.argsort(survival_values) population = population[sorted_indices] survival_values = survival_values[sorted_indices] if best_fitness is not None: best_fitness[-1] = survival_values[0] # best_fitness[-1] = np.mean(survival_values) # best_fitness[-1] = survival_values[-1] if perf_counter is not None: perf_counter[-1] = time.perf_counter() - start_perf_counter if process_time is not None: process_time[-1] = time.process_time() - start_process_time return (population, survival_values)
def prey_predator_algorithm_continuous(instance, config, fitness_function, out_info=None, verbose=False): population_size = config.population_size if config.max_steps > instance.num_materials: config.max_steps = instance.num_materials if config.min_steps > config.max_steps: config.min_steps = config.max_steps if config.evaluator == Evaluator.FIXED_EVALUATOR: evaluate_function = evaluate_population_fixed else: evaluate_function = evaluate_population_random def counter_fitness(individual, instance, student, timer, print_results=False, data=None): nonlocal cost_counter cost_counter += 1 return fitness_function(individual, instance, student, timer, print_results, data=data) if out_info is not None: out_info["best_fitness"] = [] out_info["partial_fitness"] = [] out_info["perf_counter"] = [] out_info["process_time"] = [] out_info["cost_value"] = [] results = [] for student in range(instance.num_learners): if verbose: print('[PPAC] Students progress: %d / %d (%d%%)' % (student + 1, instance.num_learners, (student + 1) * 100 / instance.num_learners)) cost_counter = 0 iteration_counter = 0 stagnation_counter = 0 if out_info is not None: out_info['best_fitness'].append([]) out_info['partial_fitness'].append([]) out_info['perf_counter'].append([]) out_info['process_time'].append([]) out_info['cost_value'].append([]) timer = Timer() population = np.random.rand(population_size, instance.num_materials) * (2 * config.max_position) - config.max_position population_best_evaluation = evaluate_function(population[0]) population_best_fitness = counter_fitness(population_best_evaluation, instance, student, timer) start_perf_counter = time.perf_counter() start_process_time = time.process_time() while ((not config.cost_budget or cost_counter < config.cost_budget) and (not config.num_iterations or iteration_counter < config.num_iterations) and (not config.max_stagnation or stagnation_counter < config.max_stagnation)): timer.add_time() population_evaluation = evaluate_function(population) survival_values = np.apply_along_axis(counter_fitness, 1, population_evaluation, instance, student, timer) sorted_indices = np.argsort(survival_values) population = population[sorted_indices] survival_values = survival_values[sorted_indices] iteration_counter += 1 if survival_values[0] < population_best_fitness: population_best_evaluation = population_evaluation[sorted_indices[0]] population_best_fitness = survival_values[0] stagnation_counter = 0 else: stagnation_counter += 1 if out_info is not None: out_info["best_fitness"][-1].append(population_best_fitness) fitness_function(population_best_evaluation, instance, student, timer, data=out_info["partial_fitness"][-1]) out_info["perf_counter"][-1].append(time.perf_counter() - start_perf_counter) out_info["process_time"][-1].append(time.process_time() - start_process_time) out_info["cost_value"][-1].append(cost_counter) new_population = np.copy(population) timer.add_time("creation") # Cria as mascaras para separar os diferentes tipos de individuo best_prey_mask = np.zeros(population_size, dtype=bool) best_prey_mask[0] = True predator_mask = np.zeros(population_size, dtype=bool) predator_mask[-1] = True follow_mask = (np.random.rand(population_size) < config.follow_chance) run_mask = ~follow_mask follow_mask[best_prey_mask] = False # Ignora as melhores presas follow_mask[predator_mask] = False # Ignora os predadores run_mask[best_prey_mask] = False # Ignora as melhores presas run_mask[predator_mask] = False # Ignora os predadores timer.add_time() follow_indices = np.where(follow_mask)[0] follow_quant = len(follow_indices) tau = 1 follow_direction = np.empty((follow_quant, instance.num_materials)) for index in range(follow_quant): i = follow_indices[index] population_distance = vector_size(population - population[i]) survival_ratio = survival_values[i] / survival_values population_direction = np.exp(survival_ratio ** tau - population_distance * 0.05)[:, np.newaxis] * (population - population[i]) individual_direction = np.sum(population_direction, axis=0) normalized_direction = individual_direction / vector_size(individual_direction) follow_direction[index] = normalized_direction # Gerar direção multidimensional # https://stackoverflow.com/questions/6283080/random-unit-vector-in-multi-dimensional-space timer.add_time("follow_calculate_direction") # TODO(andre:2018-05-28): Garantir que max_steps nunca é maior do que o numero de materiais omega = .5 predator_distance = survival_values[-1] - survival_values[follow_mask] num_steps = config.max_steps * np.random.rand(follow_quant) / np.exp(config.steps_distance_parameter * predator_distance ** omega) new_population[follow_mask] = move_population_direction(new_population[follow_mask], num_steps, follow_direction) timer.add_time("follow_direction") num_steps = np.round(config.min_steps * np.random.rand(follow_quant)) new_population[follow_mask] = move_population_random(new_population[follow_mask], num_steps) timer.add_time("follow_random") num_steps = np.round(config.max_steps * np.random.rand(np.count_nonzero(run_mask))) new_population[run_mask] = move_population_random_complement(new_population[run_mask], num_steps, population[-1]) timer.add_time("run") new_population[best_prey_mask] = move_population_local_search(new_population[best_prey_mask], counter_fitness, evaluate_function, config.min_steps, config.local_search_tries, instance, student, timer) timer.add_time() # TODO(andre:2018-12-17): Gerar uma direção dentro de um circulo unitário # e multiplicar por max_steps para determinar a direção aleatória num_steps = np.round(config.max_steps * np.random.rand(np.count_nonzero(predator_mask))) new_population[predator_mask] = move_population_random(new_population[predator_mask], num_steps) timer.add_time("predator_random") num_steps = np.round(config.min_steps * np.random.rand(np.count_nonzero(predator_mask))) worst_prey = np.repeat(population[-2][np.newaxis, :], np.count_nonzero(predator_mask), axis=0) new_population[predator_mask] = move_population_direction(new_population[predator_mask], num_steps, worst_prey) timer.add_time("predator_follow") new_population = np.clip(new_population, -config.max_position, config.max_position) population = new_population population_evaluation = evaluate_function(population) survival_values = np.apply_along_axis(counter_fitness, 1, population_evaluation, instance, student, timer) sorted_indices = np.argsort(survival_values) population_evaluation = population_evaluation[sorted_indices] survival_values = survival_values[sorted_indices] if out_info is not None: out_info["best_fitness"][-1].append(population_best_fitness) fitness_function(population_best_evaluation, instance, student, timer, data=out_info["partial_fitness"][-1]) out_info["perf_counter"][-1].append(time.perf_counter() - start_perf_counter) out_info["process_time"][-1].append(time.process_time() - start_process_time) out_info["cost_value"][-1].append(cost_counter) results.append((population_best_evaluation, population_best_fitness)) return results
def differential_evolution(instance, config, fitness_function, out_info=None, verbose=False): population_size = config.population_size if config.evaluator == Evaluator.FIXED_EVALUATOR: evaluate_function = evaluate_population_fixed else: evaluate_function = evaluate_population_random def counter_fitness(individual, instance, student, timer, print_results=False, data=None): nonlocal cost_counter cost_counter += 1 return fitness_function(individual, instance, student, timer, print_results, data=data) if out_info is not None: out_info["best_fitness"] = [] out_info["partial_fitness"] = [] out_info["perf_counter"] = [] out_info["process_time"] = [] out_info["cost_value"] = [] results = [] for student in range(instance.num_learners): if verbose: print('[DE] Students progress: %d / %d (%d%%)' % (student + 1, instance.num_learners, (student + 1) * 100 / instance.num_learners)) cost_counter = 0 iteration_counter = 0 stagnation_counter = 0 if out_info is not None: out_info['best_fitness'].append([]) out_info['partial_fitness'].append([]) out_info['perf_counter'].append([]) out_info['process_time'].append([]) out_info['cost_value'].append([]) timer = Timer() # TODO(andre: 2019-04-25): Testar utilizar um valor limite para os valores # dos individuos, similar ao PSO e ao PPA_C population = np.random.rand(population_size, instance.num_materials) * (2 * config.max_velocity) - config.max_velocity population_evaluation = evaluate_function(population) survival_values = np.apply_along_axis(counter_fitness, 1, population_evaluation, instance, student, timer) population_best_index = np.argmin(survival_values, axis=0) population_best_evaluation = np.copy(population_evaluation[population_best_index]) population_best_fitness = survival_values[population_best_index] start_perf_counter = time.perf_counter() start_process_time = time.process_time() while ((not config.cost_budget or cost_counter < config.cost_budget) and (not config.num_iterations or iteration_counter < config.num_iterations) and (not config.max_stagnation or stagnation_counter < config.max_stagnation)): timer.add_time() old_population_best_fitness = population_best_fitness sorted_indices = np.argsort(survival_values) population = population[sorted_indices] survival_values = survival_values[sorted_indices] if out_info is not None: out_info["best_fitness"][-1].append(population_best_fitness) fitness_function(population_best_evaluation, instance, student, timer, data=out_info["partial_fitness"][-1]) out_info["perf_counter"][-1].append(time.perf_counter() - start_perf_counter) out_info["process_time"][-1].append(time.process_time() - start_process_time) out_info["cost_value"][-1].append(cost_counter) new_population = np.copy(population) #--de for p in range(population_size): idxs = [idx for idx in range(population_size) if idx != p] a, b, c = population[np.random.choice(idxs, 3, replace = False)] # mutant = np.clip(a + config.mutation_chance * (b - c), 0, 1) # mutant = np.copy(a + config.mutation_chance * (b - c)) mutant = np.clip(a + config.mutation_chance * (b - c), -config.max_velocity, config.max_velocity) cross_points = np.random.rand(instance.num_materials) < config.crossover_rate if not np.any(cross_points): cross_points[np.random.randint(0, instance.num_materials)] = True applicant = np.where(cross_points, mutant, population[p]) applicant_evaluation = evaluate_function(applicant) applicant_fit = counter_fitness(applicant_evaluation, instance, student, timer) if applicant_fit < survival_values[p]: new_population[p] = applicant survival_values[p] = applicant_fit if applicant_fit < population_best_fitness: population_best_evaluation = applicant_evaluation population_best_fitness = applicant_fit #--end de iteration_counter += 1 if population_best_fitness < old_population_best_fitness: stagnation_counter = 0 else: stagnation_counter += 1 population = new_population if out_info is not None: out_info["best_fitness"][-1].append(population_best_fitness) fitness_function(population_best_evaluation, instance, student, timer, data=out_info["partial_fitness"][-1]) out_info["perf_counter"][-1].append(time.perf_counter() - start_perf_counter) out_info["process_time"][-1].append(time.process_time() - start_process_time) out_info["cost_value"][-1].append(cost_counter) results.append((population_best_evaluation, population_best_fitness)) return results
def genetic_algorithm(instance, config, fitness_function, out_info=None): population_size = config.population_size def counter_fitness(individual, instance, student, timer, print_results=False, data=None): nonlocal cost_counter cost_counter += 1 return fitness_function(individual, instance, student, timer, print_results, data=data) if out_info is not None: out_info['best_fitness'] = [] out_info['partial_fitness'] = [] out_info['perf_counter'] = [] out_info['process_time'] = [] out_info['cost_value'] = [] results = [] for student in range(instance.num_learners): print( '\n\n\n\n---------------------------------------------\n\n\n\nNew Student' ) cost_counter = 0 iteration_counter = 0 stagnation_counter = 0 if out_info is not None: out_info['best_fitness'].append([]) out_info['partial_fitness'].append([]) out_info['perf_counter'].append([]) out_info['process_time'].append([]) out_info['cost_value'].append([]) timer = Timer() population = np.random.randint(2, size=(population_size, instance.num_materials), dtype=bool) population_best_individual = population[0] population_best_fitness = counter_fitness(population[0], instance, student, timer) start_perf_counter = time.perf_counter() start_process_time = time.process_time() while ((not config.cost_budget or cost_counter < config.cost_budget) and (not config.num_iterations or iteration_counter < config.num_iterations) and (not config.max_stagnation or stagnation_counter < config.max_stagnation)): timer.add_time() survival_values = np.apply_along_axis(counter_fitness, 1, population, instance, student, timer) print('----------------------') sorted_indices = np.argsort(survival_values) population = population[sorted_indices] survival_values = survival_values[sorted_indices] if survival_values[0] < population_best_fitness: population_best_individual = population[0] population_best_fitness = survival_values[0] stagnation_counter = 0 else: stagnation_counter += 1 print(population_best_fitness) iteration_counter += 1 if out_info is not None: out_info['best_fitness'][-1].append(population_best_fitness) fitness_function(population_best_individual, instance, student, timer, data=out_info['partial_fitness'][-1]) out_info['perf_counter'][-1].append(time.perf_counter() - start_perf_counter) out_info['process_time'][-1].append(time.process_time() - start_process_time) out_info['cost_value'][-1].append(cost_counter) new_population = copying_gene(population, config.copying_method, config) if config.use_local_search: new_population = local_search_gene(new_population, counter_fitness, config.local_search_method, config) remaining_spots = population_size - len(new_population) selection_spots = remaining_spots if (config.crossover_method == Crossover.THREE_PARENT_CROSSOVER): selection_spots = int(3 * math.ceil(remaining_spots / 3.)) * 3 else: selection_spots = int(2 * math.ceil(remaining_spots / 2.)) parents = selection_gene(population, survival_values, selection_spots, config.selection_method, config) children = crossover_gene(parents, config.crossover_method, config) mutated = mutation_gene(children, config.mutation_method, config) new_population = np.append(new_population, mutated[:remaining_spots], axis=0) population = new_population if out_info is not None: out_info['best_fitness'][-1].append(population_best_fitness) fitness_function(population_best_individual, instance, student, timer, data=out_info['partial_fitness'][-1]) out_info['perf_counter'][-1].append(time.perf_counter() - start_perf_counter) out_info['process_time'][-1].append(time.process_time() - start_process_time) out_info['cost_value'][-1].append(cost_counter) results.append((population_best_individual, population_best_fitness)) return results
def nsga_ii(instance, config, fitness_function, out_info=None, verbose=False, **kwargs): population_size = config.population_size def counter_fitness(individual, instance, student, timer, print_results=False, data=None, **kwargs): nonlocal cost_counter cost_counter += 1 return fitness_function(individual, instance, student, timer, print_results, data=data, **kwargs) if out_info is not None: out_info['best_fitness'] = [] out_info['population_fitness'] = [] out_info['perf_counter'] = [] out_info['process_time'] = [] out_info['cost_value'] = [] results = [] for student in range(instance.num_learners): if verbose: print('[NSGA-II] Students progress: %d / %d (%d%%)' % (student + 1, instance.num_learners, (student + 1) * 100 / instance.num_learners)) cost_counter = 0 iteration_counter = 0 stagnation_counter = 0 if out_info is not None: out_info['best_fitness'].append([]) out_info['population_fitness'].append([]) out_info['perf_counter'].append([]) out_info['process_time'].append([]) out_info['cost_value'].append([]) timer = Timer() population = np.random.randint(2, size=(population_size, instance.num_materials), dtype=bool) population_best_fitness = sum(counter_fitness(population[0], instance, student, timer, **kwargs)) survival_values = np.apply_along_axis(counter_fitness, 1, population, instance, student, timer, **kwargs) sorted_fronts = sort_nondominated(survival_values, sign=-1) distance = np.zeros((survival_values.shape[0],)) for front in sorted_fronts: distance[front] = crowding_dist(survival_values[front]) start_perf_counter = time.perf_counter() start_process_time = time.process_time() while ((not config.cost_budget or cost_counter < config.cost_budget) and (not config.num_iterations or iteration_counter < config.num_iterations) and (not config.max_stagnation or stagnation_counter < config.max_stagnation)): timer.add_time() cur_best = np.min(np.sum(survival_values, axis=1)) if cur_best < population_best_fitness: population_best_fitness = cur_best stagnation_counter = 0 else: stagnation_counter += 1 iteration_counter += 1 if out_info is not None: out_info['best_fitness'][-1].append(population_best_fitness) out_info['population_fitness'][-1].append(survival_values) out_info['perf_counter'][-1].append(time.perf_counter() - start_perf_counter) out_info['process_time'][-1].append(time.process_time() - start_process_time) out_info['cost_value'][-1].append(cost_counter) remaining_spots = population_size selection_spots = remaining_spots if (config.crossover_method == Crossover.THREE_PARENT_CROSSOVER): selection_spots = int(3 * math.ceil(remaining_spots / 3.)) * 3 else: selection_spots = int(2 * math.ceil(remaining_spots / 2.)) parents = selection_gene(population, survival_values, selection_spots, Selection.NSGA_II_SELECTION, config, crowding_dist=distance) children = crossover_gene(parents, config.crossover_method, config) mutated = mutation_gene(children, config.mutation_method, config) mutated = mutated[:remaining_spots] # Calculates the survival value of only the new individuals new_survival_values = np.apply_along_axis(counter_fitness, 1, mutated, instance, student, timer, **kwargs) new_population = np.append(population, mutated, axis=0) new_survival_values = np.append(survival_values, new_survival_values, axis=0) sorted_fronts = sort_nondominated(new_survival_values, sign=-1) new_distance = np.zeros((new_survival_values.shape[0],)) sorted_indices = [] for front in sorted_fronts: front_distance = crowding_dist(new_survival_values[front]) sorted_indices.extend([x for (_, x) in sorted(zip(front_distance, front), reverse=True)]) new_distance[front] = front_distance new_population = new_population[sorted_indices] new_survival_values = new_survival_values[sorted_indices] new_distance = new_distance[sorted_indices] population = new_population[:population_size] survival_values = new_survival_values[:population_size] distance = new_distance[:population_size] if out_info is not None: out_info['best_fitness'][-1].append(population_best_fitness) out_info['population_fitness'][-1].append(survival_values) out_info['perf_counter'][-1].append(time.perf_counter() - start_perf_counter) out_info['process_time'][-1].append(time.process_time() - start_process_time) out_info['cost_value'][-1].append(cost_counter) results.append((population, survival_values)) return results