def _roulette_selection_gene(population, survival_values, quant): # TODO(andre:2018-08-17): Rever a forma como as chances de escolher um gene são calculadas roulette = Roulette(1 / survival_values) parents_indexes = [roulette.spin() for i in range(quant)] parents = population[parents_indexes] return parents
def roulette_concepts_selector(stats, num_materials): count_histogram = stats['count_histogram'] materials_list = [] quant_roulette = Roulette(count_histogram.astype(float)) for i in range(num_materials): quant_concepts = quant_roulette.spin() + 1 materials_list.append(select_concepts(stats, quant_concepts)) return materials_list
def histogram_concepts_selector(stats, num_materials, smoothing): concepts_quant = stats['concepts_quant'] count_histogram = stats['count_histogram'] coocurrence_matrix = np.sum(stats['n_coocurrence_matrix'], axis=0) + smoothing num_concepts = len(stats['concepts_name']) materials_list = [] concept_roulette = Roulette(concepts_quant.astype(float)) quant_roulette = Roulette(count_histogram.astype(float)) for i in range(num_materials): new_material = [] remaining_concepts_id = list(range(num_concepts)) concept_id = concept_roulette.spin() new_material.append(remaining_concepts_id.pop(concept_id)) quant_concepts = quant_roulette.spin() + 1 for j in range(quant_concepts - 1): new_probability = np.sum( coocurrence_matrix[new_material][:, remaining_concepts_id], axis=0) concept_id = roulette_spin(new_probability) new_material.append(remaining_concepts_id.pop(concept_id)) materials_list.append(new_material) return materials_list
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 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 generate_materials(stats, num_materials, gen_type, args): concepts_name = stats['concepts_name'] quant_resource_types_histogram = stats['quant_resource_types_histogram'] resource_types_frequency = stats['resource_types_frequency'] interactivity_level_frequency = stats['interactivity_level_frequency'] interactivity_type_frequency = stats['interactivity_type_frequency'] if gen_type == 'random': materials_list = random_concepts_selector(stats, num_materials, args.mean_concepts, args.smoothing) elif gen_type == 'histogram': materials_list = histogram_concepts_selector(stats, num_materials, args.smoothing) elif gen_type == 'roulette': materials_list = roulette_concepts_selector(stats, num_materials) materials_list = [sorted(material) for material in materials_list] # materials_list = [[concepts_name[concept] for concept in material] for material in sorted(materials_list)] materials_list = [[concepts_name[concept] for concept in material] for material in materials_list] difficulty_roulette = Roulette([16, 72, 130, 48, 18]) quant_resource_types_roulette = Roulette( quant_resource_types_histogram.tolist()) resource_types_name = list(resource_types_frequency.keys()) resource_types_frequency_values = list(resource_types_frequency.values()) interactivity_type_name = list(interactivity_type_frequency.keys()) interactivity_type_frequency_values = list( interactivity_type_frequency.values()) interactivity_type_frequency_roulette = Roulette( interactivity_type_frequency_values) interactivity_level_name = list(interactivity_level_frequency.keys()) interactivity_level_frequency_values = list( interactivity_level_frequency.values()) interactivity_level_frequency_roulette = Roulette( interactivity_level_frequency_values) materials_difficulty = np.empty((num_materials, ), dtype=int) materials_duration = np.empty((num_materials, ), dtype=int) materials_resource_types = [None] * num_materials materials_interactivity_type = [None] * num_materials materials_interactivity_level = [None] * num_materials for i in range(num_materials): materials_difficulty[i] = difficulty_roulette.spin() + 1 if materials_difficulty[i] == 1: max_indice = 16 power_a = 68.12307258 power_b = 0.2095535293 if materials_difficulty[i] == 2: max_indice = 72 power_a = 134.6334519 power_b = 0.04677506963 if materials_difficulty[i] == 3: max_indice = 130 power_a = 175.1923166 power_b = 0.0293693865 if materials_difficulty[i] == 4: max_indice = 48 power_a = 106.7568341 power_b = 0.09490106732 if materials_difficulty[i] == 5: max_indice = 18 power_a = 84.89245786 power_b = 0.3313514637 power_x = (random.random() * max_indice) + 1 materials_duration[i] = int(power_a * math.e**(power_b * power_x)) material_quant_resource_types = quant_resource_types_roulette.spin( ) + 1 materials_resource_types[i] = [] remaining_resource_types = resource_types_name.copy() remaining_resource_types_frequency = resource_types_frequency_values.copy( ) for j in range(material_quant_resource_types): new_resource_type_index = roulette_spin( remaining_resource_types_frequency) materials_resource_types[i].append( remaining_resource_types[new_resource_type_index]) del remaining_resource_types[new_resource_type_index] del remaining_resource_types_frequency[new_resource_type_index] materials_interactivity_type[i] = interactivity_type_name[ interactivity_type_frequency_roulette.spin()] materials_interactivity_level[i] = interactivity_level_name[ interactivity_level_frequency_roulette.spin()] interactivity_type = materials_interactivity_type interactivity_level = materials_interactivity_level learning_resource_types = materials_resource_types difficulty = [ _difficulty_strings[difficulty_values] for difficulty_values in materials_difficulty ] typical_learning_time = [ time_to_string(duration_values) for duration_values in materials_duration ] lom_data = { 'interactivity_type': interactivity_type, 'interactivity_level': interactivity_level, 'learning_resource_types': learning_resource_types, 'difficulty': difficulty, 'typical_learning_time': typical_learning_time, } return (materials_list, lom_data)