예제 #1
0
def test_crossover():
    #use these 2 individuals for all sub tests
    individual_1 = individual.Ind(size=5,
                                  genes={
                                      "a": 1,
                                      "b": 2,
                                      "c": 3,
                                      "d": 4,
                                      "e": 5
                                  },
                                  fitness=0)
    individual_2 = individual.Ind(size=5,
                                  genes={
                                      "a": 6,
                                      "b": 7,
                                      "c": 8,
                                      "d": 9,
                                      "e": 10
                                  },
                                  fitness=0)
    ranges = [
        individual.ParamRange("a", 0, 10, 1),
        individual.ParamRange("b", 0, 10, 1),
        individual.ParamRange("c", 0, 10, 1),
        individual.ParamRange("d", 0, 10, 1),
        individual.ParamRange("e", 0, 10, 1)
    ]
    isError = False
    print("--------\nTesting crossover for individuals", individual_1.genes,
          "and", individual_2.genes)
    for cross_point in range(1, 4):
        print("Testing crossover point ", cross_point, "...")
        ret_pop = []  #restart each time through
        individual.crossover(individual_1, individual_2, ret_pop, ranges,
                             cross_point)

        #Test that the individuals are correct
        print(ret_pop[0], ret_pop[1])
        for i in range(
                cross_point
        ):  #check up to cross point in each individual in ret_pop for no change
            if (ret_pop[0].genes[ranges[i].name]!=individual_1.genes[ranges[i].name]) or \
                (ret_pop[1].genes[ranges[i].name] != individual_2.genes[ranges[i].name]):
                isError = True
                print("Error at gene ", ranges[i].name,
                      " using crossover point ", cross_point)
        for i in range(cross_point, len(ranges)):
            if (ret_pop[0].genes[ranges[i].name] != individual_2.genes[ranges[i].name]) or \
                (ret_pop[1].genes[ranges[i].name] != individual_1.genes[ranges[i].name]):
                isError = True
                print("Error at gene ", ranges[i].name,
                      " using crossover point ", cross_point)

    if not isError:
        print("Crossover test complete with no errors")
 def testCrossover(self):
     (i3, i4) = crossover(self.i1, self.i2)
     union1 = self.i1.chromosome.union(self.i2.chromosome)
     union2 = i3.chromosome.union(i4.chromosome)
     self.assertEqual(union1, union2)
     self.assertEqual(len(i3.chromosome), self.p)
     self.assertEqual(len(i4.chromosome), self.p)
 def testCrossoverDiffIndividuals(self):
     (i3, i4) = crossover(self.i1, self.i2, c=3)
     self.assertNotEqual(i3, i4)
     union1 = self.i1.chromosome.union(self.i2.chromosome)
     union2 = i3.chromosome.union(i4.chromosome)
     self.assertEqual(union1, union2)
     self.assertEqual(len(i3.chromosome), self.p)
     self.assertEqual(len(i4.chromosome), self.p)
예제 #4
0
def crossover(pop, ranges, keep, tournament_size):

    # Choose the parent pairs
    ret_pop = []  # this will hold the new population
    number_of_pairs = int((len(pop) - keep) / 2)
    pairs_for_crossover = choose_individuals(
        pop, "tournament", number_of_pairs,
        tournament_size)  # holds indices of individuals as a list of pairs

    # ensures choose_individuals can't break this function
    if len(pairs_for_crossover) != int(number_of_pairs):
        print("Error. Incorrect number of pairs for crossover chosen:",
              len(pairs_for_crossover), number_of_pairs)
        sys.exit(-1)

    # crosses over two individuals at a time from the pair list
    for i in range(len(pairs_for_crossover)):
        # random point to cross over
        cross_point = random.randint(
            1,
            len(ranges) - 1)  # forces crosspoint to not be before or after end
        #print("Crossoverpoint:", cross_point)
        # get the random individuals
        individual_1 = pop[pairs_for_crossover[i][0]]
        individual_2 = pop[pairs_for_crossover[i][1]]

        #print(individual_1,individual_2)
        # send over individuals and crossover point. ret_pop will be modified to hold two new individuals
        individual.crossover(individual_1, individual_2, ret_pop, ranges,
                             cross_point)

    #add elitism individuals to the new population
    elitism(pop, ret_pop, keep)

    assert (
        len(pop) == len(ret_pop)), "new population is not the correct size!"

    return ret_pop
예제 #5
0
def run():
    p_cross = 0.7
    p_mutation = 0.01
    config = read_file('data/had12.dat')
    distances = config['distances']
    flows = config['flows']
    individual_size = config['size']
    new_population = []
    population_size = 100
    tour_size = 5
    num_of_gen = 100
    result_matrix = np.zeros((4, num_of_gen, 5))
    print(result_matrix)
    for e in range(5):
        current_population = generate_init_population(population_size,
                                                      individual_size)
        current_population_costs = calculate_population_cost(
            distances, flows, current_population)
        result_matrix[:, 0, e] = ([
            0,
            min(current_population_costs),
            np.average(current_population_costs),
            max(current_population_costs)
        ])
        print('poczatek fora')
        for gen in range(1, num_of_gen):
            print('current' + str(current_population))
            for _ in range(population_size):
                new_population.append(
                    tournament(current_population, current_population_costs,
                               tour_size))
            print('after tournamtent' + str(new_population))
            # new_population = roulette(current_population, current_population_costs)
            new_population = [
                crossover(individual_parent, choice(new_population))
                if random() <= p_cross else individual_parent
                for individual_parent in new_population
            ]
            print('after crossover: ' + str(new_population))
            new_population = [
                mutate_individual(indiv) if random() <= p_mutation else indiv
                for indiv in new_population
            ]
            current_population = new_population
            new_population = []
            current_population_costs = calculate_population_cost(
                distances, flows, current_population)
            print('gen' + str(gen))
            result_matrix[:, gen, e] = ([
                gen,
                min(current_population_costs),
                np.average(current_population_costs),
                max(current_population_costs)
            ])
            print('generation ' + str(gen))

    plt.xlabel('Generations')
    plt.ylabel('Costs')
    plt.errorbar(np.arange(num_of_gen),
                 np.average(result_matrix[1, :, :], axis=1),
                 np.std(result_matrix[1, :, :], axis=1),
                 fmt='-o',
                 label="Best")
    plt.errorbar(np.arange(num_of_gen),
                 np.average(result_matrix[2, :, :], axis=1),
                 np.std(result_matrix[2, :, :], axis=1),
                 fmt='-o',
                 label="Avg")
    plt.errorbar(np.arange(num_of_gen),
                 np.average(result_matrix[3, :, :], axis=1),
                 np.std(result_matrix[3, :, :], axis=1),
                 fmt='-o',
                 label="Worst")
    plt.legend(bbox_to_anchor=(1.05, 1), loc=4, borderaxespad=0.)
    plt.show()
    random_search(num_of_gen, individual_size, distances, flows)
def evolve(G, p, popsize, gener, mutprob, coprob, tsize, elitism=None):
    nodes_ordered_by_demand = sorted(G.node.items(),
                                     key=lambda t: t[1]['demand'],
                                     reverse=True)
    t1 = clock()
    pop = []
    # generating first population, which will be random
    for i in range(popsize):
        individual = Individual(p, G)
        individual.calculate_fitness(G, nodes_ordered_by_demand)
        pop.append(individual)

    rank_population(pop)
    report = {
        'worst_i': pop[-1].fitness,
        'best_i': pop[0].fitness,
        'generation': 0,
        'better_sons': 0,
        'total_sons': 0,
        'best_i_hist': [pop[0].fitness],
        'mean_fitness_hist': [sum([i.fitness for i in pop]) / popsize],
        'repeated_i_hist': [popsize - unique_individuals(pop)]
    }
    for generation in range(gener):
        # applying elitism if relevant
        if elitism:
            topelite = int(ceil(elitism * popsize))
            new_pop = pop[0:topelite]
        else:  # if no elitism specified, simply create a new population
            new_pop = []

        # while the population is not complete
        while len(new_pop) < popsize:
            random_number = random()
            subpop = sample(pop, tsize)  # tournament individuals
            if random_number < mutprob:  # mutating
                new_pop.append(mutate(subpop[0], G))
                new_pop[-1].calculate_fitness(G, nodes_ordered_by_demand)
            elif random_number < coprob:  # doing crossover
                mean_fitness = (subpop[0].fitness + subpop[1].fitness) / 2.0
                i1, i2 = crossover(subpop[0], subpop[1])
                i1.calculate_fitness(G, nodes_ordered_by_demand)
                if i1.fitness > mean_fitness:
                    report['better_sons'] += 1
                report['total_sons'] += 1
                new_pop.append(i1)
                if i2 is not None:
                    i2.calculate_fitness(G, nodes_ordered_by_demand)
                    if i2.fitness > mean_fitness:
                        report['better_sons'] += 1
                    new_pop.append(i2)
                    report['total_sons'] += 1
            else:  # if no mutation or crossover, insert the best individual
                new_pop.append(deepcopy(subpop[0]))
            if len(new_pop) > popsize:
                new_pop.pop()
                report['total_sons'] -= 1
        pop = rank_population(new_pop)
        report['best_i_hist'].append(pop[0].fitness)
        report['mean_fitness_hist'].append(sum([i.fitness for i in pop]) /
                                                  popsize)
        report['repeated_i_hist'].append(popsize - unique_individuals(pop))
        if report['best_i'] > pop[0].fitness:
            report['best_i'] = pop[0].fitness
            report['generation'] = generation
        if report['worst_i'] < pop[-1].fitness:
            report['worst_i'] = pop[-1].fitness

    t2 = clock()
    report['time'] = round(t2 - t1, 3)
    report['gener_per_s'] = gener / report['time']
    return report
def evolve(G, p, popsize, gener, mutprob, coprob, tsize, elitism=None):
    nodes_ordered_by_demand = sorted(G.node.items(),
                                     key=lambda t: t[1]['demand'],
                                     reverse=True)
    t1 = clock()
    pop = []
    # generating first population, which will be random
    for i in range(popsize):
        individual = Individual(p, G)
        individual.calculate_fitness(G, nodes_ordered_by_demand)
        pop.append(individual)

    rank_population(pop)
    report = {
        'worst_i': pop[-1].fitness,
        'best_i': pop[0].fitness,
        'generation': 0,
        'better_sons': 0,
        'total_sons': 0,
        'best_i_hist': [pop[0].fitness],
        'mean_fitness_hist': [sum([i.fitness for i in pop]) / popsize],
        'repeated_i_hist': [popsize - unique_individuals(pop)]
    }
    for generation in range(gener):
        # applying elitism if relevant
        if elitism:
            topelite = int(ceil(elitism * popsize))
            new_pop = pop[0:topelite]
        else:  # if no elitism specified, simply create a new population
            new_pop = []

        # while the population is not complete
        while len(new_pop) < popsize:
            random_number = random()
            subpop = sample(pop, tsize)  # tournament individuals
            if random_number < mutprob:  # mutating
                new_pop.append(mutate(subpop[0], G))
                new_pop[-1].calculate_fitness(G, nodes_ordered_by_demand)
            elif random_number < coprob:  # doing crossover
                mean_fitness = (subpop[0].fitness + subpop[1].fitness) / 2.0
                i1, i2 = crossover(subpop[0], subpop[1])
                i1.calculate_fitness(G, nodes_ordered_by_demand)
                if i1.fitness > mean_fitness:
                    report['better_sons'] += 1
                report['total_sons'] += 1
                new_pop.append(i1)
                if i2 is not None:
                    i2.calculate_fitness(G, nodes_ordered_by_demand)
                    if i2.fitness > mean_fitness:
                        report['better_sons'] += 1
                    new_pop.append(i2)
                    report['total_sons'] += 1
            else:  # if no mutation or crossover, insert the best individual
                new_pop.append(deepcopy(subpop[0]))
            if len(new_pop) > popsize:
                new_pop.pop()
                report['total_sons'] -= 1
        pop = rank_population(new_pop)
        report['best_i_hist'].append(pop[0].fitness)
        report['mean_fitness_hist'].append(
            sum([i.fitness for i in pop]) / popsize)
        report['repeated_i_hist'].append(popsize - unique_individuals(pop))
        if report['best_i'] > pop[0].fitness:
            report['best_i'] = pop[0].fitness
            report['generation'] = generation
        if report['worst_i'] < pop[-1].fitness:
            report['worst_i'] = pop[-1].fitness

    t2 = clock()
    report['time'] = round(t2 - t1, 3)
    report['gener_per_s'] = gener / report['time']
    return report
 def testCrossoverSameIndividuals(self):
     (i3, i4) = crossover(self.i1, self.i1)
     self.assertEqual(i3, self.i1)
     self.assertEqual(i4, None)