Compare commits

..

No commits in common. "7056534872917f07670da8218409684c0f26c56d" and "ac300129ce9fe12cf09dcf72cbde915493a2349e" have entirely different histories.

1 changed files with 22 additions and 44 deletions

View File

@ -12,9 +12,9 @@ def get_row_distance(source, destination, data):
return row["distance"].values[0] return row["distance"].values[0]
def compute_distance(element, individual, data): def compute_distance(element, solution, data):
accumulator = 0 accumulator = 0
distinct_elements = individual.query(f"point != {element}") distinct_elements = solution.query(f"point != {element}")
for _, item in distinct_elements.iterrows(): for _, item in distinct_elements.iterrows():
accumulator += get_row_distance( accumulator += get_row_distance(
source=element, destination=item.point, data=data source=element, destination=item.point, data=data
@ -22,18 +22,18 @@ def compute_distance(element, individual, data):
return accumulator return accumulator
def generate_individual(n, m, data): def generate_first_solution(n, m, data):
individual = DataFrame(columns=["point", "distance", "fitness"]) solution = DataFrame(columns=["point", "distance"])
individual["point"] = choice(n, size=m, replace=False) solution["point"] = choice(n, size=m, replace=False)
individual["distance"] = individual["point"].apply( solution["distance"] = solution["point"].apply(
func=compute_distance, individual=individual, data=data func=compute_distance, solution=solution, data=data
) )
return individual return solution
def evaluate_individual(individual, data): def evaluate_element(element, data):
fitness = [] fitness = []
genotype = individual.point.values genotype = element.point.values
distances = data.query(f"source in @genotype and destination in @genotype") distances = data.query(f"source in @genotype and destination in @genotype")
for item in genotype[:-1]: for item in genotype[:-1]:
element_df = distances.query(f"source == {item} or destination == {item}") element_df = distances.query(f"source == {item} or destination == {item}")
@ -82,13 +82,12 @@ def get_matching_genes(parents):
def populate_offspring(values): def populate_offspring(values):
offspring = DataFrame(columns=["point", "distance", "fitness"]) offspring = DataFrame(columns=["point", "distance"])
for element in values: for element in values:
aux = DataFrame(columns=["point", "distance", "fitness"]) aux = DataFrame(columns=["point", "distance"])
aux["point"] = element aux["point"] = element
offspring = offspring.append(aux) offspring = offspring.append(aux)
offspring["distance"] = 0 offspring["distance"] = 0
offspring["fitness"] = 0
offspring = offspring[1:] offspring = offspring[1:]
return offspring return offspring
@ -105,9 +104,8 @@ def uniform_crossover(parents, m):
def position_crossover(parents, m): def position_crossover(parents, m):
matching_genes = get_matching_genes(parents) matching_genes = get_matching_genes(parents)
shuffled_genes = select_random_genes(matching_genes, parents, m) shuffled_genes = select_random_genes(matching_genes, parents, m)
first_offspring = populate_offspring(values=[matching_genes, shuffled_genes]) offspring = populate_offspring(values=[matching_genes, shuffled_genes])
second_offspring = populate_offspring(values=[matching_genes, shuffled_genes]) return offspring
return [first_offspring, second_offspring]
def crossover(mode, parents, m): def crossover(mode, parents, m):
@ -116,15 +114,15 @@ def crossover(mode, parents, m):
return position_crossover(parents, m) return position_crossover(parents, m)
def element_in_dataframe(individual, element): def element_in_dataframe(solution, element):
duplicates = individual.query(f"point == {element}") duplicates = solution.query(f"point == {element}")
return not duplicates.empty return not duplicates.empty
def select_new_gene(individual, n): def select_new_gene(individual, n):
while True: while True:
new_gene = randint(n) new_gene = randint(n)
if not element_in_dataframe(individual=individual, element=new_gene): if not element_in_dataframe(solution=individual, element=new_gene):
return new_gene return new_gene
@ -143,31 +141,11 @@ def mutate(population, n, probability=0.001):
return population return population
def tournament_selection(population): def tournament_selection(solution):
individuals = population.sample(n=2) individuals = solution.sample(n=2)
best_index = population["distance"].idxmax() best_index = solution["distance"].astype(float).idxmax()
return individuals.iloc[best_index] return individuals.iloc[best_index]
def generational_replacement(previous_population, current_population): def genetic_algorithm(n, m, data):
new_population = current_population first_solution = generate_first_solution(n, m, data)
best_previous_individual = max(previous_population, key=lambda x: x.fitness)
if best_previous_individual not in new_population:
worst_index = new_population.index(min(new_population, key=lambda x: x.fitness))
new_population[worst_index] = best_previous_individual
return new_population
def stationary_replacement(previous_population, current_population):
new_population = previous_population
return new_population
def replace_population(previous_population, current_population, mode):
if mode == "generational":
return generational_replacement(previous_population, current_population)
return stationary_replacement(previous_population, current_population)
def genetic_algorithm(n, m, data, mode):
population = [generate_individual(n, m, data) for _ in range(n)]