Compare commits
4 Commits
ac300129ce
...
7056534872
Author | SHA1 | Date |
---|---|---|
coolneng | 7056534872 | |
coolneng | 135d1c48b8 | |
coolneng | 7c434fb9cd | |
coolneng | 49d8383133 |
|
@ -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, solution, data):
|
def compute_distance(element, individual, data):
|
||||||
accumulator = 0
|
accumulator = 0
|
||||||
distinct_elements = solution.query(f"point != {element}")
|
distinct_elements = individual.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, solution, data):
|
||||||
return accumulator
|
return accumulator
|
||||||
|
|
||||||
|
|
||||||
def generate_first_solution(n, m, data):
|
def generate_individual(n, m, data):
|
||||||
solution = DataFrame(columns=["point", "distance"])
|
individual = DataFrame(columns=["point", "distance", "fitness"])
|
||||||
solution["point"] = choice(n, size=m, replace=False)
|
individual["point"] = choice(n, size=m, replace=False)
|
||||||
solution["distance"] = solution["point"].apply(
|
individual["distance"] = individual["point"].apply(
|
||||||
func=compute_distance, solution=solution, data=data
|
func=compute_distance, individual=individual, data=data
|
||||||
)
|
)
|
||||||
return solution
|
return individual
|
||||||
|
|
||||||
|
|
||||||
def evaluate_element(element, data):
|
def evaluate_individual(individual, data):
|
||||||
fitness = []
|
fitness = []
|
||||||
genotype = element.point.values
|
genotype = individual.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,12 +82,13 @@ def get_matching_genes(parents):
|
||||||
|
|
||||||
|
|
||||||
def populate_offspring(values):
|
def populate_offspring(values):
|
||||||
offspring = DataFrame(columns=["point", "distance"])
|
offspring = DataFrame(columns=["point", "distance", "fitness"])
|
||||||
for element in values:
|
for element in values:
|
||||||
aux = DataFrame(columns=["point", "distance"])
|
aux = DataFrame(columns=["point", "distance", "fitness"])
|
||||||
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
|
||||||
|
|
||||||
|
@ -104,8 +105,9 @@ 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)
|
||||||
offspring = populate_offspring(values=[matching_genes, shuffled_genes])
|
first_offspring = populate_offspring(values=[matching_genes, shuffled_genes])
|
||||||
return offspring
|
second_offspring = populate_offspring(values=[matching_genes, shuffled_genes])
|
||||||
|
return [first_offspring, second_offspring]
|
||||||
|
|
||||||
|
|
||||||
def crossover(mode, parents, m):
|
def crossover(mode, parents, m):
|
||||||
|
@ -114,15 +116,15 @@ def crossover(mode, parents, m):
|
||||||
return position_crossover(parents, m)
|
return position_crossover(parents, m)
|
||||||
|
|
||||||
|
|
||||||
def element_in_dataframe(solution, element):
|
def element_in_dataframe(individual, element):
|
||||||
duplicates = solution.query(f"point == {element}")
|
duplicates = individual.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(solution=individual, element=new_gene):
|
if not element_in_dataframe(individual=individual, element=new_gene):
|
||||||
return new_gene
|
return new_gene
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,11 +143,31 @@ def mutate(population, n, probability=0.001):
|
||||||
return population
|
return population
|
||||||
|
|
||||||
|
|
||||||
def tournament_selection(solution):
|
def tournament_selection(population):
|
||||||
individuals = solution.sample(n=2)
|
individuals = population.sample(n=2)
|
||||||
best_index = solution["distance"].astype(float).idxmax()
|
best_index = population["distance"].idxmax()
|
||||||
return individuals.iloc[best_index]
|
return individuals.iloc[best_index]
|
||||||
|
|
||||||
|
|
||||||
def genetic_algorithm(n, m, data):
|
def generational_replacement(previous_population, current_population):
|
||||||
first_solution = generate_first_solution(n, m, data)
|
new_population = current_population
|
||||||
|
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)]
|
||||||
|
|
Loading…
Reference in New Issue