用遗传算法解决旅行商问题精品毕业设计完整版Word格式.docx
- 文档编号:14937662
- 上传时间:2022-10-26
- 格式:DOCX
- 页数:13
- 大小:20.32KB
用遗传算法解决旅行商问题精品毕业设计完整版Word格式.docx
《用遗传算法解决旅行商问题精品毕业设计完整版Word格式.docx》由会员分享,可在线阅读,更多相关《用遗传算法解决旅行商问题精品毕业设计完整版Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
那么如何解决遗传算法容易陷入局部极值的问题呢?
让我们来看看大自然提供的方案。
六千五百万年以前,恐龙和灵长类动物并存,恐龙在地球上占绝对统治地位,如果恐龙没有灭绝灵长类动物是绝没有可能统治地球的。
正是恐龙的灭绝才使灵长类动物有了充分进化的余地,事实上地球至少经历了5次物种大灭绝,每次物种灭绝都给更加高级的生物提供了充分进化的余地。
所以要跳出局部极值就必须杀死当前所有的优秀个体,从而让远离当前极值的点有充分的进化余地。
这就是灾变的思想。
下一个问题是什么时候进行灾变,换句话说什么时候局部搜索已经充分了呢?
我用了一个灾变倒计数的概念:
从500开始递减,每一代递减一次,如果出现了新的最优值,就从新开始计数,如果出现新最优值的时候倒计数递减次数的2.5倍已经超过500则从新的初始值开始倒数。
例:
初始倒数500,如果倒数到200时出现新最优值,则从(500-200)*2.5=750开始从新倒数,下一次如果倒数到100时出现新最优值,则从(750-100)*2.5=1625开始倒计数(这里的2.5是一个经验值,可以在全局参数设置里面调整)。
也就是说倒计数的长度取决于进化的速度,进化速度越慢倒计数长度越长。
如果倒计数完毕还没有新的最优值,就认为局部搜索已经充分,就发生灾变。
基于上诉思想我写了一个程序来计算旅行商问题。
我现在终于体会到旅行商问题为什么会这么有名,有很多算法都可以解决旅行商问题,问题描述简单,评价函数也不复杂,问题的解可以直观地显示出来,具有各种如局部极值多等典型的性质,这些都成为算法练兵的好处,可以清晰地比较各个算法的优劣,发现算法的缺陷。
可以说旅行商问题就是一个练兵场,一个学校,为算法提供了成长的场所。
为算法能够应用到其他复杂领域打好基础。
程序输入是一个文本文件,里面记录了所有城市的坐标,以及最优个体的序列。
以一张只有10个城市的地图为例,文本中可能记录了以下内容:
0.604600,0.592500,8
0.610500,0.261400,3
0.572800,0.494300,7
0.153200,0.983900,2
0.955700,0.772000,0
0.914400,0.276500,4
0.998500,0.484800,6
0.449800,0.605300,5
0.308500,0.109000,1
0.364700,0.060100,9
表示第一个城市的坐标为0.604600,0.592500(程序客户区的宽和高为单位1,所有城市的坐标值均在[0.0,0.0]~[1.0,1.0]之内),第二个城市坐标为0.610500,0.261400...依次类推。
后面所跟的整数为最优个体的序列,上述数据表示旅行商应该从第8号城市(0.308500,0.109000)出发,经过3,7,2,0,4,6,5,1,9号城市,最后又回到第8号城市。
程序的最终目标是求取一个序列,使得旅行商按照这个序列旅行时行程最短。
程序的变异方法是自繁殖变异,有两种:
1、随机取两点,逆序这两点间的序列。
2、随机把一个城市转移到另一个序列位置。
对于一个500个城市的地图,大概在5万代左右发生第一次灾变,用时约6~8分钟,灾变前夕的灾变倒计数初始值已经从800达到2000~20000。
可以看到从一次灾变结束到下一次灾变开始,最优值的变化趋势近似呈一条拖拽线,越接近局部极值进化速度越慢,这也说明灾变倒计数的策略是正确的。
下面是一次试验的数据统计:
程序运行两个小时,进化到一百万代,发生了16次灾变,最优个体产生于第606722代,属于第11个进化周期,总行程长度为17.164006,第一次灾变发生在第49773代,第一次灾变前最优个体产生于第45523代,总行程长度为18.029128。
分析最优分趋势图,在每个进化周期内最优分图形基本呈拖拽线形状,可以看到多数进化周期已经没有进化速度,说明局部搜索已经充分,少数进化周期在发生灾变时还有明显进化速度,这是因为这些周期恰好进入一个比较长的停滞期时被程序认为局部搜索充分了,停滞期的出现根随机数有关,个人认为应该可以通过调节灾变初始值和灾变倍增值解决。
分析平均分趋势图,可以看到每次分生灾变后群体平均分会达到一个较大的值,然后迅速下降,再慢慢上升。
这说明旅行商问题的局部极值非常多,极值附近解的分数要远远低于整个解空间的平均分,这主要是因为一个较优解的进行一次变异后生成的子女绝大部分都是畸形的分数很低的个体,由于遗传算法并不放弃这些进化方向,从而影响了群体的平均分。
灾变时对整个解空间进行随机搜索,这时的群体平均分可以作为整个解空间平均分的体现,进化一定时间以后,群体迅速陷入到一个特定的局部极值附近,这个时候较优解还没有进化出来,群体中充斥着畸形个体,只有少量比较优秀的个体,所以平均分也随之迅速下降,随后由于优秀个体存活率比较高,群体渐渐被优秀个体统治,群体平均分也开始上升。
仔细分析每一个进化周期的平均分趋势图可以发现,在进化的后期群体平均分有一个稳固上升的阶段(这应该是最优个体慢慢排挤其他个体的结果),在此之前都会有一个标志性的少量下挫曲线(如图),还不知道产生这个曲线的原因。
程序下载地址:
GA旅行商问题
下面是程序的主要核心代码:
//变异函数
inlinevoidVariant(GENE&
gsource,GENE&
gdest,int*ptemp,intsize,intvarate)
{
staticinti;
staticintj,k,l,n,m;
staticinttmp;
memcpy(gdest.index,gsource.index,sizeof(int)*size);
for(i=0;
i<
varate;
i++)
{
switch(rand()%2)
{
case0:
//逆序变异
{
j=rand()%size;
k=rand()%size;
if(j==k)
{
k=(k+1)%size;
}
if(j>
k)
k+=size;
for(l=j;
l<
j+k-l;
l++)
{
n=(j+k-l)%size;
m=l%size;
tmp=gdest.index[m];
gdest.index[m]=gdest.index[n];
gdest.index[n]=tmp;
}
else
tmp=gdest.index[l];
gdest.index[l]=gdest.index[j+k-l];
gdest.index[j+k-l]=tmp;
}
break;
case1:
//转移变异
k=1;
//rand()%((size>
>
4)+1);
if(k==0)
k=1;
l=rand()%(size-k)+1;
n=(j+k)%size+l>
size?
size-(j+k)%size:
l;
memcpy(ptemp,gdest.index+(j+k)%size,n*sizeof(int));
if(n<
l)
memcpy(ptemp+n,gdest.index,(l-n)*sizeof(int));
n=j+k>
size-j:
k;
memcpy(ptemp+l,gdest.index+j,n*sizeof(int));
memcpy(ptemp+l+n,gdest.index,(k-n)*sizeof(int));
m=k+l;
n=j+m>
m;
memcpy(gdest.index+j,ptemp,n*sizeof(int));
m)
memcpy(gdest.index,ptemp+n,(m-n)*sizeof(int));
default:
}
}
}
//辅助线程
UINTCCityMap:
:
ThreadProc(LPVOI
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 遗传 算法 解决 旅行 问题 精品 毕业设计 完整版