示例#1
0
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
示例#2
0
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
示例#3
0
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
示例#5
0
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)