a692108116
Signed-off-by: Neerka <kuba.markil0220@gmail.com>
68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
import pickle
|
|
import random
|
|
|
|
|
|
def manhattan_distance(point1, point2):
|
|
return abs(point1[0] - point2[0]) + abs(point1[1] - point2[1])
|
|
|
|
|
|
def calculate_fitness(individual, points):
|
|
return -sum(manhattan_distance(points[individual[i - 1]], points[individual[i]]) for i in range(len(individual)))
|
|
|
|
|
|
def crossover(parent1, parent2):
|
|
size = len(parent1)
|
|
start, end = sorted(random.sample(range(size), 2))
|
|
child = [None] * size
|
|
|
|
# Copy subset from first parent
|
|
child[start:end + 1] = parent1[start:end + 1]
|
|
|
|
# Copy remaining genes from second parent, wrapping around
|
|
wrapped_parent2 = parent2[end + 1:] + parent2[:end + 1]
|
|
remaining_genes = [gene for gene in wrapped_parent2 if gene not in child]
|
|
|
|
child[end + 1:] = remaining_genes[:size - end - 1]
|
|
child[:start] = remaining_genes[size - end - 1:]
|
|
|
|
return child
|
|
|
|
|
|
def mutate(individual):
|
|
idx1, idx2 = random.sample(range(len(individual)), 2)
|
|
individual[idx1], individual[idx2] = individual[idx2], individual[idx1]
|
|
|
|
|
|
def genetic_algorithm(points, population_size, generations):
|
|
population = [random.sample(range(len(points)), len(points)) for _ in range(population_size)]
|
|
for _ in range(generations):
|
|
population.sort(key=lambda individual: calculate_fitness(individual, points), reverse=True)
|
|
next_generation = population[:population_size // 10]
|
|
while len(next_generation) < population_size:
|
|
parent1, parent2 = random.choices(population[:population_size // 2], k=2)
|
|
child = crossover(parent1, parent2)
|
|
if random.random() < 0.01:
|
|
mutate(child)
|
|
next_generation.append(child)
|
|
population = next_generation
|
|
best_individual = max(population, key=lambda individual: calculate_fitness(individual, points))
|
|
best_path = [points[i] for i in best_individual]
|
|
|
|
with open('best_path.pkl', 'wb') as f:
|
|
pickle.dump(best_path, f)
|
|
|
|
return best_path, -calculate_fitness(best_individual, points)
|
|
|
|
|
|
point_list = []
|
|
for i in range(1, 29):
|
|
if i % 2 == 1:
|
|
point_list.append((i, 6))
|
|
point_list.append((i, 12))
|
|
elif i % 2 == 0:
|
|
point_list.append((i, 9))
|
|
if i % 2 == 1 and i % 4 != 1:
|
|
point_list.append((i, 10))
|
|
|
|
print(genetic_algorithm(point_list, 100, 1000))
|