一、问题分析
如图如示,将节点编号,依次为1.2.3.4.5.6.7.8.9.10.11,由图论知识,则可写出其带权邻接矩阵为:
0 2 8 1 500 500 500 500 500 500 500
2 0 6 500 1 500 500 500 500 500 500
8 6 0 7 500 1 500 500 500 500 500
1 500 7 0 500 500 9 500 500 500 500
500 1 500 500 0 3 500 2 500 500 500
500 500 1 500 3 0 4 500 6 500 500
500 500 500 9 500 4 0 500 500 1 500
500 500 500 500 2 500 500 0 7 500 9
500 500 500 500 500 6 500 7 0 1 2
500 500 500 500 500 500 1 500 1 0 4
500 500 500 500 500 500 500 9 2 4 0
注:为避免计算时无穷大数吃掉小数,此处为令inf=500。
问题要求求出任意两点间的最短路径,Floyd算法采用的是在两点间尝试插入顶点,比较距离长短的方法。我思考后认为,用遗传算法很难找到一个可以统一表示最短路径的函数,但是可以对每一对点分别计算,然后加入for循环,可将相互之间的所有情况解出。观察本题可发现,所有节点都是可双向行走,则可只计算i到j的路径与距离,然后将矩阵按主对角线翻折即可得到全部数据。
二、实验原理与数学模型
实现原理为遗传算法原理:
按所选择的适应度函数并通过遗传中的复制、交叉及变异对个体进行筛选,使得适应度高的个体被保留下来,组成新的群体,新的群体既继承了上一代的信息,又优于上一代。这样周而复始,群体中个体适应度不断提高,直到满足一定的条件。
数学模型如下:
实验具体:
第一:编码与初始化
因采用自然编码,且产生的编码不能重复,于是我采用了randperm函数产生不重复的随机自然数。因解题方法是使用的是计算每一对点,则我们编码时将第一个节点单独放入,合并成完整编码。
因为节点有11个,可采用一个1行11列的矩阵储存数据,同时,由于编号为数字,可直接使用数字编码表示路径的染色体。具体如下:
采用等长可变染色体的方式,例如由2到9的路径,染色体编码可能为(2,5,1,8,4,6,9,3,10,7,11),超过9之后的编码,用来进行算子的运算,不具备实际意义。
第二:计算适应度,因取最短路径值,即最小值,常用方法为C-F(x)或C/F(x)(C为一常数),此处采用前一种方式。于是,可进一步计算相对适应度。
第三:选择与复制
采用轮盘赌算法,产生一个随机值,比较它与累计相对适应度的关系,从而选择出优良个体进入下一代。
第四:交叉。
因编码是不重复的数字,所以采用传统的交叉方法,即上一行与下一行对位交叉,会产生无效路径,于是,采用了不同的交叉方法,具体如下:
(1)在表示路径的染色体Tx 和Ty中,随机选取两个基因座(不能为起点基因座)i和j, 即将i个基因座和第j个基因座之间的各个基因座定义为交叉域,并将交叉的内容分别记忆为temp1和temp2。
(2)根据交叉区域中的映射关系,在个体Tx中找出所有与temp2相同的元素,在个体Ty中找出所有与temp1相同的元素,全部置为0。
(3)将个体Tx、Ty进行循环左移,遇到0就删除,直到编码串中交叉区域的左端不再有0:然后将所有空位集中到交叉区域,而将交叉区域内原有的基因依次向后移动。因0元素可能较多,在程序实现时,我是将非零元素提出,后面再合成。
(4)将temp2插入到Tx的交叉区域,temp1插入到Ty的交叉区域。形成新的染色体。
第五:变异
染色体编码为从1到11的无重复编码,所以不能采用一般的生成一个随机数替代的办法。此处采用交换变异法。即随机产生两个数,交换两个节点的顺序。
距离矩阵:a(i,j) i表示起点,j表示终点。
outdistance =
0 2 7 1 3 6 10 5 12 11 14
2 0 5 3 1 4 8 3 10 9 12
7 5 0 7 4 1 5 6 7 6 9
1 3 7 0 4 8 9 6 11 10 13
3 1 4 4 0 3 7 2 9 8 11
6 4 1 8 3 0 4 5 6 5 8
10 8 5 9 7 4 0 9 2 1 4
5 3 6 6 2 5 9 0 7 8 9
12 10 7 11 9 6 2 7 0 1 2
11 9 6 10 8 5 1 8 1 0 3
14 12 9 13 11 8 4 9 2 3 0
路径:b(i,j) i表示起点,j表示终点。
outpath: