广州大学人工智能原理实验四:TSP问题的遗传算法实现

您所在的位置:网站首页 人工智能导论教材实验 广州大学人工智能原理实验四:TSP问题的遗传算法实现

广州大学人工智能原理实验四:TSP问题的遗传算法实现

2023-10-21 05:22| 来源: 网络整理| 查看: 265

相关资料

广州大学人工智能原理实验一:知识的表示与推理实验 广州大学人工智能原理实验二:八数码问题 广州大学人工智能原理实验三:产生式系统推理 广州大学人工智能原理实验四:TSP问题的遗传算法实现 广州大学人工智能原理实验五:基于汉诺塔的问题规约图实现 五份实验报告下载链接🔗

TSP问题的遗传算法实现 相关资料 一、实验目的二、基本要求三、实验软件四、实验内容:五、实验报告内容六、实验代码

一、实验目的

本实验课程是计算机、智能、物联网等专业学生的一门专业课程,通过实验,帮助学生更好地掌握人工智能相关概念、技术、原理、应用等;通过实验提高学生编写实验报告、总结实验结果的能力;使学生对智能程序、智能算法等有比较深入的认识。要掌握的知识点如下: 1.掌握人工智能中涉及的相关概念、算法; 2.熟悉人工智能中的知识表示方法; 3.掌握问题表示、求解及编程实现; 4.熟悉和掌握遗传算法的基本概念和基本思想; 5.理解和掌握遗传算法的各个操作算子,能够用选定的编程语言设计简单的遗传优化系统; 6.通过实验培养学生利用遗传算法进行问题求解的基本技能。

二、基本要求

1.实验前,复习《人工智能》课程中的有关内容。 2.准备好实验数据。 3.程序可以在多个同学交流下讨论完成,但是实验报告独立完成。 4.该按照自己完成的部分进行。

三、实验软件

推荐使用C或C++(Visual studio等平台)(不限制语言使用,Java,matlab,Python等)。

四、实验内容:

以N个节点的TSP(旅行商问题)问题为例,应用遗传算法进行求解,求出问题的最优解。 1 旅行商问题 旅行商问题(Traveling Salesman Problem, TSP),又译为旅行推销员问题、货担郎问题,简称为TSP问题,是最基本的路线问题。假设有n个可直达的城市,一销售商从其中的某一城市出发,不重复地走完其余n-1个城市并回到原出发点,在所有可能的路径中求出路径长度最短的一条。 TSP问题是组合数学中一个古老而又困难的问题,也是一个典型的组合优化问题,现已归入NP完备问题类。NP问题用穷举法不能在有效时间内求解,所以只能使用启发式搜索。遗传算法是求解此类问题比较实用、有效的方法之一。 下面给出30个城市的位置信息:

表1 Oliver TSP问题的30个城市位置坐标 城市编号坐标城市编号坐标城市编号坐标1(87,7)11(58,69)21(4,50)2(91,38)12(54,62)22(13,40)3(83,46)13(51,67)23(18,40)4(71,44)14(37,84)24(24,42)5(64,60)15(41,94)25(25,38)6(68,58)16(2,99)26(41,26)7(83,69)17(7,64)27(45,21)8(87,76)18(22,60)28(44,35)9(74,78)19(25,62)29(58,35)10(71,71)20(18,54)30(62,32)

最优路径为:1 2 3 4 6 5 7 8 9 10 11 12 13 14 15 16 17 19 18 20 21 22 23 24 25 28 26 27 29 30 其路径长度为:424.869292 也可取前10个城市的坐标进行测试:

表2 Oliver TSP问题的10个城市位置坐标

城市编号坐标1(87,7)2(91,38)3(83,46)4(71,44)5(64,60)6(68,58)7(83,69)8(87,76)9(74,78)10(71,71)

有人求得的最优路径为: 1 4 6 5 10 9 8 7 3 2 1 路径长度是166.541336 上述10个城市的求解中编号从0开始,把所有路径搜索完又返回到出发节点。

2 问题描述 应用遗传算法求解30/10个节点的TSP(旅行商问题)问题,求问题的最优解。

五、实验报告内容

(1)要求求出问题最优解,若得不出最优解,请分析原因; 一、取前10个城市测试: 参数设置:

交叉率突变率种群大小进化代数0.50.130300

最优路径为: 在这里插入图片描述 [ 1 2 3 7 8 9 10 5 6 4 1] 最优距离:166.54133557746266

二、取所有城市测试: 参数设置:

交叉率突变率种群大小进化代数0.60.32001000

最优路径为:在这里插入图片描述 [13 12 11 10 9 8 7 5 6 4 3 2 1 30 29 27 26 28 25 24 23 22 21 20 18 19 17 16 15 14 13] 最优距离:424.8692923184516

(2)对实验中的几个算法控制参数进行仔细定义,并能通过实验选择参数的最佳值;

① 以所有城市测试为例,进行以下参数讨论; ② 每一条基因的定义为一条旅游路线,即每一条基因对应了30个城市数字下标,这30个数字每个都是有且只有一个; ③ 选择种群:优胜劣汰,对低于平均适应度的染色体进行交叉和突变,高于平均适应度的进行保留; ④ 交叉操作:选取两条父母染色体,对母亲染色体随机截取一段S,对父染色体在S上出现的数字剔除,然后拼接S,返回交叉后的染色体; ⑤ 突变操作:对染色体进行随机截取一段,进行翻转操作; ⑥ 种群进化:种群内每一根染色体都有可能进行交叉和突变,取决于交叉率和突变率。 ⑦ 大的种群可以保证每一代里拥有的染色体更多,交叉和突变得到的新染色体更多,有助于跳出局部最优解,尽早获得全局最优解。 ⑧ 为了快速得到实验结果,默认进化代数为500、种群大小为100,对交叉率和突变率进行消融实验

表一:消融实验 pc\pm0.10.20.30.40.50.60.70.80.91.00.1498.7467.7465.8458.5468.7476428.9511.1444548.10.2459.9470.3470.5446.2457.9450.9440.5500.5466.2477.70.3465.9460.4513.5463.4428.7488.6431.8477.4532.3534.30.4506453.9424.9498.4461.1487.3458510.5548.6593.90.5484.3447.1448.7489.9471.5437533.9552.7538597.10.6445.6488429.1482.2445.6500.1445620.5588.6609.60.7439.9451.6429.1495.4521.5570574.9627.9637.8618.90.8440.7454.7499.7559.4594.1578.2571.7684.5673.1668.60.9504.8536.6590.2559.8659.7669.5641.6720.2682.7677.91.0561.5625612.4659.1638.5688.1741.9767.3792.5736.3

⑨ 可以看到pc取0.4,pm取0.3时,可取得全局最优解。但实验初始化具有随机性,参数的选择仅具有一定参考意义。 ⑩ 解决办法:采用随机初始化种子,固定随机数的产生,进行多组消融实验,因花费时间可能过多,这里不再一一展开。

(3)要求界面显示每次迭代求出的局部最优解和最终求出的全局最优解。

一、取前10个城市测试: 在这里插入图片描述

二、取所有城市测试: 在这里插入图片描述

(4)实验结果讨论。

① 本次实验,前十城市还是所有城市,都可以成功寻得全局最优值,完成了实验的基本要求。 ② 遗传算法的核心主要在于,种群淘汰、交叉与变异三个操作,因为这几个点的选择非常重要,所以要针对具体问题设计对应的操作,这样可以大大加快优化的时间。 ③ 选择合适的操作之后,还要对参数进行设置,种群大小、交叉率、变异率,这三个参数可以直接影响是否能够跳出局部最优,寻得全局最优。 ④ 在对于所有城市的求解过程中,可以发现全局最优解的获得往往要通过多次运行代码才能获得,因此对于该遗传算法应该仍有较大的优化空间。 ⑤ 通过本次实验,可以发现一个种群存在着一些问题,就是每次保留的最优染色体都一直是由该种群产生的,很容易陷入局部最优解,或许可以采用多个种群解决这一问题。 ⑥ 通过网上查阅,发现已经有人提出了多种群遗传算法MSGA,下面为多种群遗传算法流程简介图。 在这里插入图片描述

图一:多种群遗传算法流程图 ⑦ 具体操作为:将初始种群展开成N个种群,然后同时进行进化(SGA,标准的遗传算法),然后在各个种群选出最优的,合成一个精华种群,然后反复迭代更新,可以设置一个早停参数M,避免运行时间过长。

六、实验代码 import numpy as np import pandas as pd import matplotlib.pyplot as plt from matplotlib.lines import Line2D from matplotlib.font_manager import FontProperties class YIchuan(object): best_distance = -1 # 记录目前最优距离 best_gene = [] # 记录目前最优旅行方案 all_best_distance = [] #记录每一代最优距离 citys = np.array([]) # 城市数组 citys_name = np.array([]) population_size = 100 # 种群大小,每个种群含有多少条基因 cross_rate = 0.9 # 交叉率 change_rate = 0.1 # 突变率 population = np.array([]) # 种群数组 fitness = np.array([]) # 适应度数组 city_size = -1 # 标记城市数目 iter_num = 200 # 最大迭代次数 def __init__(self, cross_rate, change_rate, population_size, iter_num): self.fitness = np.zeros(self.population_size) self.cross_rate = cross_rate self.change_rate = change_rate self.population_size = population_size self.iter_num = iter_num self.fig, self.ax = plt.subplots() self.plt = plt def init(self): TSP = self TSP.load_city_data() # 加载城市数据 TSP.population = TSP.creat_population(TSP.population_size) # 创建种群 TSP.fitness = TSP.get_fitness(TSP.population) # 计算初始种群适应度 self.ax.axis([0, 100, 0, 100]) def creat_population(self, size): """ 创建种群 :param size:种群大小 :return: 种群 """ population = [] # 存储种群生成的基因 for i in range(size): gene = np.arange(self.citys.shape[0]) np.random.shuffle(gene) # 打乱数组[0,...,city_size] population.append(gene) # 加入种群 return np.array(population) def get_fitness(self, population): """ 获得适应度 :param population:种群 :return: 种群每条基因对应的适应度 """ fitness = np.array([]) # 适应度记录数组 for i in range(population.shape[0]): gene = population[i] # 取其中一条基因(编码解,个体) dis = self.compute_distance(gene) # 计算此基因优劣(距离长短) dis = self.best_distance / dis # 当前最优距离除以当前population[i](个体)距离;越近适应度越高,最优适应度为1 fitness = np.append(fitness, dis) # 保存适应度population[i] return fitness def select_population(self, population): """ 选择种群,优胜劣汰 策略:低于平均的要替换 :param population: 种群 :return: 更改后的种群 """ best_index = np.argmax(self.fitness) ave = np.median(self.fitness, axis=0) for i in range(self.population_size): if i != best_index and self.fitness[i] self.cross_rate: return parent1 index1 = np.random.randint(0, self.city_size - 1) index2 = np.random.randint(index1, self.city_size - 1) tempgene = parent2[index1:index2] # 交叉的基因片段 newgene = [] xxx = 0 for g in parent1: if xxx == index1: newgene.extend(tempgene) # 插入基因片段 if g not in tempgene: newgene.append(g) xxx += 1 newGene = np.array(newgene) return newGene def reverse_gene(self, gene, i, j): """ 翻转i到j位置的基因 :param gene: 基因 :param i: 第i个位置 :param j: 第j个位置 :return: 翻转后的基因 """ if i >= j: return gene if j > self.city_size - 1: return gene parent1 = np.copy(gene) tempgene = parent1[i:j] newgene = [] p1len = 0 for g in parent1: if p1len == i: newgene.extend(tempgene[::-1]) # 插入基因片段 if g not in tempgene: newgene.append(g) p1len += 1 return np.array(newgene) def change(self, gene): """ 突变,主要使用翻转 :param gene: 基因 :return: 突变后的基因 """ if np.random.rand() > self.change_rate: return gene index1 = np.random.randint(0, self.city_size - 1) index2 = np.random.randint(index1, self.city_size - 1) new_gene = self.reverse_gene(gene, index1, index2) #翻转 return new_gene def evolution(self): """ 迭代进化种群 :return: None """ for i in range(self.iter_num): best_index = np.argmax(self.fitness) worst_f_index = np.argmin(self.fitness) local_best_genee = self.population[best_index] local_best_distance = self.compute_distance(local_best_genee) if i == 0: #第一代记录最优基因和最短距离 self.best_gene = local_best_genee self.best_distance = self.compute_distance(local_best_genee) if local_best_distance


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3