实验五:用遗传算法解决旅行商问题.DOC
文本预览下载声明
姓名: 学号:
实验五:用遗传算法解决旅行商问题
实验内容
使用MPI编写一个并行程序,利用遗传算法来解决旅行商问题。
实验原理
旅行商问题概述
旅行商问题,即TSP问题(Traveling Salesman Problem)是数学领域中著名问题之一。假设有一个旅行商人要拜访N个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。旅行商问题可以归纳为寻找加权图中的最短回路问题。
由于TSP是NP问题,我们无法对该问题寻找多项式时间算法,因此只能构造一些启发式近似算法来求得问题的较优解。在这里,我们采用遗传算法来找出近似最佳路径。
遗传算法概述
遗传算法(Genetic Algorithm)是模拟达尔文的遗传选择和自然淘汰的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。 遗传算法是从代表问题可能潜在的解集的一个种群(population)开始的,而一个种群则由经过基因(gene)编码的一定数目的个体(individual)组成。每个个体实际上是染色体(chromosome)带有特征的实体。染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现。
初代种群产生之后,按照适者生存和优胜劣汰的原理,逐代(generation)演化产生出越来越好的近似解,在每一代,根据问题域中个体的适应度(fitness)大小挑选(selection)个体,并借助于自然遗传学的遗传算子(genetic operators)进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的种群。这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码(decoding),可以作为问题近似最优解。
遗传算法并行化
在遗传算法中,种群的规模往往很大,并且要经过多代的进化和变异,因此其需要的计算量会很大。使用并行化方法可以极大的提高计算速率,并有利于增大计算规模,使用更复杂的交叉进化和突变函数,从而得到更精确的解。本次实验将采用MPI进行并行化程序设计。
实现方法
设计思路
将每一个进程当作一个并行的种群,首先初始化一个种群,从中随机选取两个个体进行交叉进化,产生两个子个体,并根据突变率从种群中随机选取几个个体进行突变。如果这两个子个体的适应度比其余所有前代个体的适应度都差,则将起杀死;否则,将这个两个子个体加入种群,并在前代个体中淘汰掉两个适应度最差的个体,从而产生新一代的种群,并保持种群规模的不变。每进化十代进行一次“移民”,即每个种群将其目前适应度最好的个体发给其它种群,再淘汰掉几个适应度较差的个体,保持种群规模不变。经过规定的进化次数后,选出当前适应度最强的个体,即得到最终解。
图3-1 每个进程的基本流程
实现细节
种群:
每个种群由一个链表表示,每个结点表示一个个体,个体的结构如下:
struct group_member
{
int order[node_num+1]; //首元素记录回路的路径长度,1为起始结点
group_member *pointer;
}
其中,order[]记录访问城市的顺序。采用链表结构的优点在于可以动态分配存储空间,操作灵活,缺点在于与数组相比其访问速度较慢。
适应度:
为了便于记算,这里每个个体的适应度就用访问路径的长度来代替,路度长度越短,其适应度就越强。
交叉函数(crossover())的设计
采用由Davis提出OX算子—通过从一个亲体中挑选一个子序列旅行并保存另一个亲体的城市相对次序来构造后代。例如,两个亲体(切割点以“|”标记)
par1=(1 2 3 | 4 5 6 7 | 8 9)
par2=(4 5 2 | 1 8 7 6 | 9 3)
将按照下面的方式产生后代。首先,切割点之间的片段被拷贝到后代里:
chd1=(x x x | 4 5 6 7 | x x)
chd2=(x x x | 1 8 7 6 | x x)
为了得到chd 1,我们只需要移走par2中已在o1中的城市4、5、6和7后,得到
2—1—8—9—3
该序列顺次放在chd 1中:
chd 1=(2 1 8 | 4 5 6 7 | 9 3)
相似地,我们可以得到另一个后代:
chd 2=(2 3 4 | 1 8 7 6 | 5 9)
OX交叉开拓了路径表达的一个特性,即城市的次序(不是它们的位置)是重要的,即两个旅行
5—1—7—8—9—4—6—2—3
8—9—4—6—2—3—5—1—7
是相同的。
突变函数(mutate())的设计
对于变异算子我们采用倒置变异。倒置变
显示全部