Python遗传算法解决旅行商问题(TSP)
Python遗传算法解决旅行商问题(TSP)
本文介绍如何使用Python实现遗传算法来解决经典的旅行商问题(TSP)。
1. 问题描述
旅行商问题(TSP)是指:给定一系列城市和每对城市之间的距离,找到访问每个城市一次并返回原始城市的最短路径。
2. 解决方案:遗传算法
遗传算法是一种受生物进化启发的元启发式搜索算法。它通过模拟自然选择和遗传机制来寻找问题的最优解。以下是使用遗传算法解决TSP问题的步骤:
- 初始化种群: 随机生成一组可行的TSP解,每个解表示为城市的访问顺序。
- 计算适应度: 评估每个解的质量,通常使用路径总长度作为适应度函数。路径越短,适应度越高。
- 选择: 从当前种群中选择优秀的个体作为父代,用于生成下一代。
- 交叉: 将两个父代的基因信息进行组合,生成新的子代解。
- 变异: 对子代解进行随机修改,以增加种群的多样性,避免陷入局部最优解。
- 进化: 用新生成的子代种群替换旧种群,并重复步骤2-5,直到满足停止条件(例如达到最大迭代次数或找到满意解)。
3. Python代码实现
import random
import math
import matplotlib.pyplot as plt
# 定义城市坐标类
class City:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, city):
x_distance = abs(self.x - city.x)
y_distance = abs(self.y - city.y)
return math.sqrt((x_distance ** 2) + (y_distance ** 2))
def __repr__(self):
return '(' + str(self.x) + ',' + str(self.y) + ')'
# 定义遗传算法类
class GeneticAlgorithm:
def __init__(self, population_size, mutation_rate, tournament_size, elitism):
self.population_size = population_size
self.mutation_rate = mutation_rate
self.tournament_size = tournament_size
self.elitism = elitism
# 初始化种群
def initialize_population(self, num_cities):
population = []
for _ in range(self.population_size):
population.append(random.sample(range(num_cities), num_cities))
return population
# 计算个体的适应度(路径长度)
def calculate_fitness(self, individual, cities):
total_distance = 0
for i in range(len(individual)):
from_city = cities[individual[i]]
to_city = cities[individual[(i + 1) % len(individual)]]
total_distance += from_city.distance(to_city)
return total_distance
# 选择操作(锦标赛选择)
def selection(self, population, cities):
tournament = random.sample(population, self.tournament_size)
best_individual = tournament[0]
for individual in tournament:
if self.calculate_fitness(individual, cities) < self.calculate_fitness(best_individual, cities):
best_individual = individual
return best_individual
# 交叉操作(顺序交叉)
def crossover(self, parent1, parent2):
child = [-1] * len(parent1)
start_index = random.randint(0, len(parent1) - 1)
end_index = random.randint(0, len(parent1) - 1)
if start_index < end_index:
for i in range(start_index, end_index + 1):
child[i] = parent1[i]
elif start_index > end_index:
for i in range(end_index, start_index + 1):
child[i] = parent1[i]
for i in range(len(parent2)):
if parent2[i] not in child:
for j in range(len(child)):
if child[j] == -1:
child[j] = parent2[i]
break
return child
# 变异操作(随机交换两个位置的城市)
def mutation(self, individual):
if random.random() < self.mutation_rate:
index1 = random.randint(0, len(individual) - 1)
index2 = random.randint(0, len(individual) - 1)
individual[index1], individual[index2] = individual[index2], individual[index1]
return individual
# 进化操作
def evolve(self, population, cities):
new_population = []
if self.elitism:
best_individual = self.selection(population, cities)
new_population.append(best_individual)
while len(new_population) < len(population):
parent1 = self.selection(population, cities)
parent2 = self.selection(population, cities)
child = self.crossover(parent1, parent2)
child = self.mutation(child)
new_population.append(child)
return new_population
# 绘制路径图
def plot_path(self, best_individual, cities):
x = []
y = []
for city_index in best_individual:
x.append(cities[city_index].x)
y.append(cities[city_index].y)
x.append(cities[best_individual[0]].x)
y.append(cities[best_individual[0]].y)
plt.plot(x, y, 'ro-')
plt.show()
# 解决TSP问题
def solve_tsp(self, cities):
num_cities = len(cities)
population = self.initialize_population(num_cities)
best_fitness = float('inf')
best_individual = []
for generation in range(1000):
population = self.evolve(population, cities)
for individual in population:
fitness = self.calculate_fitness(individual, cities)
if fitness < best_fitness:
best_fitness = fitness
best_individual = individual
print(f'Generation {generation}: Best fitness = {best_fitness}')
print('最短路径长度:', best_fitness)
print('最短路径:', best_individual)
self.plot_path(best_individual, cities)
# 随机生成50个不同坐标的地点
cities = []
for _ in range(50):
x = random.randint(0, 100)
y = random.randint(0, 100)
cities.append(City(x, y))
# 使用遗传算法解决TSP问题
ga = GeneticAlgorithm(population_size=50, mutation_rate=0.01, tournament_size=5, elitism=True)
ga.solve_tsp(cities)
4. 代码说明
- 代码首先定义了
City类来表示城市,包含坐标信息和计算城市间距离的方法。 - 然后定义了
GeneticAlgorithm类,实现了遗传算法的核心步骤:初始化种群、计算适应度、选择、交叉、变异和进化。 - 在
solve_tsp方法中,首先初始化种群,然后迭代执行进化操作,并在每一代记录最优解。 - 最后,代码随机生成了50个城市,并使用遗传算法寻找最短路径,并将结果打印出来,并绘制路径图。
5. 总结
本文介绍了如何使用Python实现遗传算法来解决TSP问题。遗传算法是一种通用的优化算法,可以应用于各种问题。通过修改代码中的参数和目标函数,可以将其应用于其他组合优化问题。
原文地址: https://www.cveoy.top/t/topic/cyPc 著作权归作者所有。请勿转载和采集!