Example #1
0
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
Example #4
0
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)
Example #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)
Example #6
0
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
Example #9
0
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