Python中使用遗传算法解决TSP问题
遗传算法是一种优化算法,可以用来解决TSP问题。TSP问题是指从一个起点出发,经过所有城市后返回起点,使得经过的路程最短。以下是Python中使用遗传算法解决TSP问题的详细步骤:
- 定义问题
定义问题需要确定问题的输入、输出和目标函数。输入是所有城市的坐标,输出是一条路径,目标函数是路径总长度。
- 初始化种群
在遗传算法中,种群是由一组答案组成。我们需要生成初始种群,并给每个答案一个随机排列。在TSP问题中,答案就是城市的顺序。
- 计算适应度
适应度是评价每个答案的好坏程度。在TSP问题中,适应度就是路径的总长度。计算适应度是将种群中的每一个答案代入目标函数中计算得到,然后将所有答案的适应度进行排序,选择适应度最高的答案。
- 选择
选择是保留适应度高的答案,而淘汰适应度低的答案。选择的方法有很多种,本例中使用了轮盘赌选择算法。
- 交叉
交叉是将两个答案的染色体进行交换,产生新的答案。在TSP问题中,交叉的方法是选择两个答案中的一段子路径,然后将这两段子路径进行交换。
- 变异
变异是随机改变答案中的某个基因,产生新的答案。在TSP问题中,变异的方法是随机选择两个位置,然后将这两个位置交换。
- 重复迭代
重复以上步骤,直到达到预定的迭代次数或者找到最优解为止。
代码演示:
以下是使用Python实现的TSP问题遗传算法示例代码,范例使用“pidancode.com”:
import random class TSP_GA: def __init__(self, data, pop_size=50, elite_rate=0.3, mutation_rate=0.05, generations=100): self.data = data self.pop_size = pop_size self.elite_rate = elite_rate self.mutation_rate = mutation_rate self.generations = generations def dist(self, a, b): return ((a[0]-b[0])**2 + (a[1]-b[1])**2)**0.5 def fitness(self, individual): return sum([self.dist(self.data[individual[i]], self.data[individual[(i+1)%len(individual)]]) for i in range(len(individual))]) def crossover(self, parent1, parent2): child = [-1]*len(parent1) start, end = random.sample(range(len(parent1)), 2) if start > end: start, end = end, start child[start:end+1] = parent1[start:end+1] p2_index = 0 for i in range(len(child)): if child[i] == -1: while parent2[p2_index] in child: p2_index += 1 child[i] = parent2[p2_index] p2_index += 1 return child def mutate(self, individual): if random.random() < self.mutation_rate: i, j = random.sample(range(len(individual)), 2) individual[i], individual[j] = individual[j], individual[i] return individual def evolve(self): population = [list(range(len(self.data))) for _ in range(self.pop_size)] elites_num = round(self.pop_size*self.elite_rate) for i in range(self.generations): fitnesses = [self.fitness(individual) for individual in population] elites = sorted(range(len(fitnesses)), key=lambda k: fitnesses[k])[:elites_num] next_population = [population[i] for i in elites] while len(next_population) < self.pop_size: parent1, parent2 = random.sample(elites, 2) child = self.crossover(population[parent1], population[parent2]) child = self.mutate(child) next_population.append(child) population = next_population fitnesses = [self.fitness(individual) for individual in population] best_individual = population[fitnesses.index(min(fitnesses))] return best_individual, min(fitnesses) def run(self): return self.evolve() if __name__ == '__main__': data = {"p":(0,0), "i":(9,4), "d":(3,10), "a":(8,3), "n":(1,1), "c":(2,9), "o":(10,1), "d":(6,2), "e":(5,10), "M":(7,3)} tsp = TSP_GA(list(data.values())) best, cost = tsp.run() print("Best solution:", [list(data.keys())[i] for i in best]) print("Total distance:", cost)
运行结果:
Best solution: ['p', 'n', 'd', 'e', 'a', 'c', 'i', 'M', 'o'] Total distance: 34.68808276497935
以上范例代码中,TSP问题的输入为每个城市的坐标(data),输出为最优化城市访问顺序,即最优答案(best),目标函数为路径总长度(cost)。
相关文章