遗传算法求解TSP问题Word下载.docx
《遗传算法求解TSP问题Word下载.docx》由会员分享,可在线阅读,更多相关《遗传算法求解TSP问题Word下载.docx(21页珍藏版)》请在冰豆网上搜索。
二、结果:
源码:
/*问题:
用遗传算法求解TSP问题:
为保证有解用完全图做样例*/
/*洪文杰2016-3-16.智能优化算法第二次作业*/
#include<
iostream>
stdlib.h>
time.h>
usingnamespacestd;
//--------------------------------宏定义----------------------------------//
#defineNUMBER50//种群规模
#defineGENE_NUMBER10//迭代次数
#defineG20//图的顶点个数
#defineCROSS0.85//交叉概率
#defineABERRANCE0.15//变异概率
//-------------------------------全局变量定义-----------------------------//
intFigure[G][G];
//保存图信息
intUnit[NUMBER][G];
//保存初始种群
intChoose_Unit[NUMBER][G];
//保存更新的种群
intChoose_Number[NUMBER];
//被选择的个体编号
intCross[NUMBER];
//要交叉的个体一览
floatselect_probability[NUMBER];
//选择概率
floataccumula_probability[NUMBER];
//积累概率
inthwj[G];
//grefenstette编码的个体、也保存最短路径
intFigure_best=100000;
//最短路径长度
//--------------------------------函数声明--------------------------------//
voidhwj_figure();
//生成完全图
voidhwj_initial_population();
//生成初始种群
voidhwj_swap(int*a,int*b);
//交换两个数的值
voidhwj_fitness();
//计算适应度、选择概率、积累概率
voidhwj_choose();
//轮盘赌选择法找到被选择的个体
inthwj_bisearch(floattemp);
//顺序查找
voidhwj_cross();
//进行交叉
voidhwj_cross2(inta,intb,intkey);
//利用grefenstette编码交叉
voidhwj_aberrance();
//进行变异
voidhwj_aberrance2(inta,intkey);
//利用grefenstette编码变异
voidhwj_best();
//找到最短路径
//--------------------------------主函数----------------------------------//
intmain(){
intkey=0;
cout<
<
"
thisisthefigure:
endl;
hwj_figure();
//cout<
--------------------------1生成完全图-------------------"
hwj_initial_population();
--------------------------2初始种群---------------------"
while(key!
=GENE_NUMBER){
hwj_fitness();
--------------------------3适应度-----------------------"
hwj_choose();
--------------------------4被选择的个体-----------------"
hwj_cross();
--------------------------5交叉后的种群-----------------"
hwj_aberrance();
--------------------------6变异后的种群-----------------"
hwj_best();
--------------------------7找到最短路径-----------------"
key++;
}
Theshortestpathlengthis:
Figure_best<
Shortestpathis:
for(inti=0;
i<
G;
i++){
cout<
hwj[i]<
'
'
;
return0;
}
//--------------------------------生成完全图----------------------------------//
voidhwj_figure(){
srand(time(NULL));
inti,j;
for(i=0;
for(j=i+1;
j<
j++){
Figure[i][j]=rand()%100+1;
//只需要上三角信息
cout<
Figure[i][j]<
}
//--------------------------------交换两个数的值------------------------------//
voidhwj_swap(int*a,int*b){
if(*a!
=*b){//异或操作交换两个数字的位置
*a^=*b;
*b^=*a;
}
//--------------------------------生初始种群----------------------------------//
voidhwj_initial_population(){
inta[G];
for(j=0;
a[j]=j;
for(i=0;
NUMBER;
for(j=0;
hwj_swap(&
a[j],&
a[j+rand()%(G-j)]);
Unit[i][j]=a[j];
//cout<
Unit[i][j]<
//输出验证完全不一样的种群且个体没有重复基因
//cout<
//-----------------------计算适应度、选择概率、积累概率-------------------------//
voidhwj_fitness(){
intsum[NUMBER];
//保存个体环路长度
inttemp;
floatSUM=0.0;
temp=0;
G-1;
if(Unit[i][j]>
Unit[i][j+1]){
temp+=Figure[Unit[i][j+1]][Unit[i][j]];
}
else{
temp+=Figure[Unit[i][j]][Unit[i][j+1]];
if(Unit[i][0]>
Unit[i][G]){
sum[i]=temp+Figure[Unit[i][G]][Unit[i][0]];
//计算每个个体的环路长度
sum[i]=temp+Figure[Unit[i][0]][Unit[i][G]];
sum[i]<
SUM+=sum[i];
SUM=100000-SUM;
select_probability[0]=(2000-sum[0])/(SUM);
accumula_probability[0]=select_probability[0];
for(i=1;
select_probability[i]=(2000-sum[i])/(SUM);
//计算选择概率
accumula_probability[i]=accumula_probability[i-1]+select_probability[i];
//计算累积概率
accumula_probability[i]<
//-----------------------------------------顺序查找---------------------------------//
inthwj_bisearch(floattemp){
if(temp<
=accumula_probability[i]&
&
temp>
accumula_probability[i-1]){
returni;
return-1;
}
//-----------------------------轮盘赌选择法找到被选择的个体-------------------------//
voidhwj_choose(){
floattemp=0.0;
temp=(rand()%1000+1)/1000.0;
temp<
Choose_Number[i]=hwj_bisearch(temp);
Choose_Number[i]<
Choose_Unit[i][j]=Unit[Choose_Number[i]][j];
Choose_Unit[i][j]<
}
//-----------------------------------------进行交叉---------------------------------//
voidhwj_cross(){
intsum=0;
intkey;
//交叉点
inta,b;
i=j=0;
temp=(rand()%1000)/1000.0;
CROSS){
Cross[i]=1;
sum++;
Cross[i]<
i=0;
if(sum%2==1){
while(Cross[i]!
=0){
i++;
Cross[i]=1;
//当交叉个体数为奇数时,多增加一个交叉的个体
Cross[i];
){
if(Cross[i]==1){
a=i;
j=i+1;
if(j<
NUMBER){
while(Cross[j]!
=1){
j++;
}
b=j;
i=j+1;
key=rand()%G;
key<
hwj_cross2(a,b,key);
a<
b<
else{
//hwj_cross2(i-1,i-1-q,key);
//-------------------------------------利用grefenstette编码交叉---------------------------------//
voidhwj_cross2(inta,intb,intkey){
inthwj1[G],hwj2[G];
//grefenstette编码的个体
intC[G];
//顺序表
C[i]=0;
hwj1[i]=hwj2[i]=0;
Choose_Unit[a][i]<
Choose_Unit[a][i];
if(C[j]==0){
temp++;
C[Choose_Unit[a][i]]=1;
hwj1[i]=temp;
//grefenstette编码
hwj1[i]<
Choose_Unit[b][i]<
Choose_Unit[b][i];
C[Choose_Unit[b][i]]=1;
hwj2[i]=temp;
hwj2[i]<
if(i<
=key){
temp=hwj1[i];
hwj1[i]=hwj2[i];
hwj2[i]=temp;
//进行交叉
for(i=G-1;
i>
=0;
i--){
for(j=i-1;
j>
j--){
if(hwj1[j]<
=hwj1[i]){
hwj1[i]++;
Choose_Unit[a][i]=hwj1[i];
//反grefenstette编码
if(hwj2[j]<
=hwj2[i]){
hwj2[i]++;
Choose_Unit[b][i]=hwj2[i];
//-----------------------------------------进行变异---------------------------------//
voidhwj_aberrance(){
intkey1,key2;
//双点变异
inta;
ABERRANCE){
while((key1=rand()%G)==(key2=rand()%G)){
a=Choose_Unit[i][key1];
Choose_Unit[i][key1]=Choose_Unit[i][key2];
Choose_Unit[i][key2]=a;
//hwj_aberrance2(a,key);
//-----------------------------------------利用grefenstette编码变异--------------------//
voidhwj_aberrance2(inta,intkey){
hwj[i]=0;
hwj[i]=temp;
hwj[key]=rand()%G;
//变异
if(hwj[j]<
=hwj[i]){
hwj[i]++;
Choose_Unit[a][i]=hwj[i];
//-----------------------------------------找到最短路径--------------------//
voidhwj_best(){
if(Figure_best>
sum[i]){
Figure_best=sum[i];
key=i;
hwj[i]=Choose_Unit[key][i];