TSP_遗传算法求解
生活随笔
收集整理的這篇文章主要介紹了
TSP_遗传算法求解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
head.h
#define N 10class Generation { public:int state[4][N+1];//染色體---種群規模為4,有10個城市float loadlength[4];//染色體的路徑長度float Fitness[4];//適應度float SPro[4];//選擇概率float AcPro[4];//累積概率int ChoiceNum[4];//選擇次數 Generation(){int i;for(i=0;i<4;i++)for(int j=0;j<N+1;j++)state[i][j]=-1;for(i=0;i<4;i++){loadlength[i]=0;Fitness[i]=0;SPro[i]=0;AcPro[i]=0;ChoiceNum[i]=0;}} }; class Point { public:int x;int y;Point(int a,int b){x=a; y=b; } };void RAND(double *r); Generation Init(Generation G);//初始化群體 void count_distance();//計算各個城市之間的直線距離 float count_loadlegth(Generation* G);//計算路徑長度 void count_fitness(Generation* G);//計算適應度 void count_pro(Generation* G);//計算選擇概率和累計概率 void count_choiceNum(Generation* G);//計算被選中的次數 void addtoopen(Generation G); void Copy_Generation(Generation* G1,Generation G0);//根據被選中次數復制上一代染色體 void Variation(Generation *G1); void Cross(Generation *G1);?
Main.cpp
#include<iostream> #include"head.h" using namespace std; #define N 10Generation OPEN[5000];//隊列-----(數據保護)每一代各染色體的情況 int OPhead=0,OPtail=0,openlen=5000; float Distance[N][N]={0};//存儲各個城市之間的直線距離 float MinShort=3000;//最短路徑長度 int MinShortLoad[N+1]={0};//最短路徑int main() {int i;//計算各個城市之間的直線距離 count_distance(); Generation G0,G1;G0=Init(G0);//初始種群 G1=G0;int GNUM=0;while(MinShort>167){G0=G1;printf("第%d代染色體情況:\n",GNUM);count_loadlegth(&G0);//計算路徑長度 printf("已搜索到的路徑中最短為: %f\n",MinShort);printf("已搜索到的路徑中最短路徑: ");for(i=0;i<N+1;i++)printf("%d ",MinShortLoad[i]);printf("\n");count_fitness(&G0);//計算適應度 count_pro(&G0); //計算選擇概率和累計概率 count_choiceNum(&G0);//計算被選中的次數addtoopen(G0);//保護每一代的記錄 printf("下一代:\n");//復制printf("復制后:\n"); Copy_Generation(&G1,G0);//根據被選中次數復制上一代染色體G0//交叉printf("交叉后:\n");Cross(&G1);/////變異 if(GNUM%5==0)//每5代(20條染色體)里變異一次(約0.5條染色體變異)-----變異率2.5% {printf("變異后:\n");Variation(&G1); }printf("\n\n");GNUM++;}return 0; }?
Function.cpp
#include<iostream> #include<stdlib.h>//for rand(),srand() #include<time.h> //for time() #include<math.h> #include<string.h> #include"head.h" #define N 10extern Generation OPEN[5000];//隊列-----(數據保護)每一代各染色體的情況 extern int OPhead,OPtail,openlen; extern float Distance[N][N];//存儲各個城市之間的直線距離 extern float MinShort;//最短路徑長度 extern int MinShortLoad[N+1];//最短路徑void count_distance() {//各個城市的位置坐標Point Position[N]={ Point(87,7),Point(91,38),Point(83,46),Point(71,44),Point(64,60),Point(68,58),Point(83,69),Point(87,76),Point(74,78),Point(71,71)//Point(58,69),Point(54,62),Point(51,67),Point(37,84),Point(41,94),//Point(2,99),Point(7,64),Point(22,60)//,Point(25,62),Point(18,54)//Point(4,50),Point(13,40),Point(18,40),Point(24,42),Point(25,38),//Point(41,26),Point(45,21),Point(44,35),Point(58,35),Point(62,32) };int i,j; for(i=0;i<N;i++)for(j=0;j<N;j++)Distance[i][j]=sqrt(pow(Position[i].x-Position[j].x,2)+pow(Position[i].y-Position[j].y,2)); } Generation Init(Generation G) {int i,j;int Arr[4][N+1]={0};/*={{7,8,9,4,5,6,1,2,3,0,7},//{9,8,7,3,2,1,6,5,4,0,9},//{1,3,5,7,9,2,4,6,8,0,1},//{0,1,2,3,4,5,6,7,8,9,0}};// //初始四條路徑*/for(i=0;i<4;i++)//產生隨機初始種群 {for(j=0;j<N;j++)//j---已經得到的序列個數 {int temp=rand()%N;for(int t=0;t<j ;t++)if(temp==Arr[i][t]){ temp=rand()%N; t=-1; }Arr[i][j]=temp;}Arr[i][N]=Arr[i][0];}for(i=0;i<4;i++)for(j=0;j<N+1;j++)G.state[i][j]=Arr[i][j];//初始化第0代的的種群狀態return G; } float count_loadlegth(Generation* G)//計算路徑長度 {int i,j;float Short=10000.0;int Snum;for(i=0;i<4;i++){float DistanceAdd=0.0;for(j=0;j<N;j++)//11-1 {int c1=(*G).state[i][j];int c2=(*G).state[i][j+1];DistanceAdd += Distance[c1][c2];}(*G).loadlength[i]=DistanceAdd;if(DistanceAdd<Short) { Short=DistanceAdd ; Snum=i; } }for(i=0;i<4;i++){for(j=0;j<N+1;j++)printf("%d ",(*G).state[i][j]);printf(" ----路徑長: %f\n",(*G).loadlength[i]);}printf("最短路徑為: ");for(j=0;j<N+1;j++) printf("%d ",(*G).state[Snum][j]);printf("\n最短路徑長: ---%f\n",Short);//輸出當代最短路徑if(Short<MinShort)//獲取全局最短路徑長度及其最短路徑 {MinShort=Short;for(j=0;j<N+1;j++)MinShortLoad[j]=(*G).state[Snum][j];}return Short;//返回當代最短路徑 } void count_fitness(Generation* G)//計算適應度 {for(int i=0;i<4;i++)(*G).Fitness[i]=(float)1000/(*G).loadlength[i];//計算得每個染色體的適應度((float)10000用于調整數值) } void count_pro(Generation* G)//計算選擇概率和累計概率 {int i;float ALL_fitness=(*G).Fitness[0]+(*G).Fitness[1]+(*G).Fitness[2]+(*G).Fitness[3];for(i=0;i<4;i++)//選擇概率(*G).SPro[i]=(*G).Fitness[i]/ALL_fitness;for(i=0;i<4;i++)//累計概率 {if(i==0) (*G).AcPro[i]=(*G).SPro[i];else (*G).AcPro[i]=(*G).SPro[i]+(*G).AcPro[i-1];} } void RAND(double *r)//產生隨機數 {//獲得當前的時間作為隨機數的種子//seed=time(0)srand(time(0));//兩次獲取隨機數時間之差大于1s產生的隨機數才會不同int i;for(i=0;i<4;i++){r[i]=(double)rand()/(double)RAND_MAX;//RAND_MAX=32767 } } void count_choiceNum(Generation* G)//計算被選中的次數 {//產生隨機數double r[4]={0.0};RAND(&r[0]); int i,j;for(i=0;i<4;i++)for(j=0;j<4;j++)//對于每一個隨機概率 {if(i==0){ if(r[j]<(*G).AcPro[i])(*G).ChoiceNum[i]++;}else{if(r[j]>=(*G).AcPro[i-1] && r[j]<(*G).AcPro[i] )(*G).ChoiceNum[i]++;}}printf("被選中的次數: ");for(i=0;i<4;i++)printf("%d ",(*G).ChoiceNum[i]);printf("\n"); } void addtoopen(Generation G) {OPEN[OPtail++]=G; //向尾部添加節點 OPtail = OPtail%openlen; }?
Cross.cpp(交叉)
#include<iostream> #include<stdlib.h>//for rand(),srand() #include<time.h> //for time() #include"head.h" #define N 10extern Generation OPEN[5000];//隊列-----(數據保護)每一代各染色體的情況 extern int OPhead,OPtail,openlen; extern float Distance[N][N];//存儲各個城市之間的直線距離//交叉 void Cross(Generation *G1) {int i;char OffSpr_A[N+1]={0},OffSpr_B[N+1]={0}, OffSpr_C[N+1]={0},OffSpr_D[N+1]={0};//記錄交叉序列int kk;//*****獲取1、2號后的交叉**************************// Generation Gt=*G1;//保護G1int C=rand()%N;//獲取隨機城市代號//int CV=C;//保護COffSpr_A[0]=C;//將城市C加入記錄---第1個子孫int count=N;//對前10個基因進行交叉(最后一個是重復的城市)kk=1;while(count!=1){int Ra,Rb;for(i=0;i<N;i++)//求城市C在Gt.state[0][]、Gt.state[1][]中的下標位置 { if(Gt.state[0][i]==C) Ra=i;//記錄下標 if(Gt.state[1][i]==C) Rb=i;}//printf("隨機起始城市: %d---下標: %d %d ",C,Ra,Rb); int Cright_A,Cright_B;for(i=(Ra+1)%N; ;)/尋找C在G1.state[0][]中的右城市號 {if(Gt.state[0][i]!=-1){ Cright_A=Gt.state[0][i]; break; }i=(i+1)%N;}//printf("右城市A:%d ",Cright_A);for(i=(Rb+1)%N; ;)/尋找C在G1.state[1][]中的右城市號 {if(Gt.state[1][i]!=-1){ Cright_B=Gt.state[1][i]; break; }i=(i+1)%N;}//printf("右城市B:%d\n",Cright_B);float da,db;da=Distance[C][Cright_A];db=Distance[C][Cright_B];if(da<=db) { OffSpr_A[kk++]=Cright_A;//加入記錄 C=Cright_A;}else{OffSpr_A[kk++]=Cright_B; C=Cright_B;}Gt.state[0][Ra]=-1;//刪除城市G1.state[0][Ra]---標記為-1Gt.state[1][Rb]=-1;count--;}OffSpr_A[N]=OffSpr_A[0];//最后一個城市與第一個城市相同 Gt=*G1;//保護G1//C=CV;C=rand()%N;//獲取隨機城市代號OffSpr_B[0]=C;//第2個子孫count=N;kk=1;while(count!=1){int Ra,Rb;for(i=0;i<N;i++)//求城市C在Gt.state[0][]、Gt.state[1][]中的下標位置 { if(Gt.state[0][i]==C) Ra=i;//記錄下標 if(Gt.state[1][i]==C) Rb=i;}//printf("隨機起始城市: %d---%d %d ",C,Ra,Rb); int Cleft_A,Cleft_B;for(i=(Ra-1+N)%N; ;)/尋找C在G1.state[0][]中的左城市號 {if(Gt.state[0][i]!=-1){ Cleft_A=Gt.state[0][i]; break; }i=(i-1+N)%N;}//printf("右城市A:%d ",Cleft_A);for(i=(Rb-1+N)%N; ;)/尋找C在G1.state[1][]中的左城市號 {if(Gt.state[1][i]!=-1){ Cleft_B=Gt.state[1][i]; break; }i=(i-1+N)%N;}//printf("右城市B:%d\n",Cleft_B);float da,db;da=Distance[C][Cleft_A];db=Distance[C][Cleft_B];if(da<=db) { OffSpr_B[kk++]=Cleft_A;//加入記錄 C=Cleft_A;}else{OffSpr_B[kk++]=Cleft_B;C=Cleft_B;}Gt.state[0][Ra]=-1;//刪除城市G1.state[0][Ra]---標記為-1Gt.state[1][Rb]=-1;count--;}OffSpr_B[N]=OffSpr_B[0];//最后一個城市與第一個城市相同// //*****獲取3、4號后代的交叉**************************// Gt=*G1;//保護G1C=rand()%N;//獲取隨機城市代號//CV=C;//保護COffSpr_C[0]=C;//將城市C加入記錄---第3個子孫count=N;kk=1;while(count!=1){int Ra,Rb;for(i=0;i<N;i++)//求城市C在Gt.state[0][]、Gt.state[1][]中的下標位置 { if(Gt.state[2][i]==C) Ra=i;//記錄下標 if(Gt.state[3][i]==C) Rb=i;}//printf("隨機起始城市: %d---%d %d ",C,Ra,Rb); int Cright_A,Cright_B;for(i=(Ra+1)%N; ;)/尋找C在G1.state[0][]中的右城市號 {if(Gt.state[2][i]!=-1){ Cright_A=Gt.state[2][i]; break; }i=(i+1)%N;}//printf("右城市A:%d ",Cright_A);for(i=(Rb+1)%N; ;)/尋找C在G1.state[1][]中的右城市號 {if(Gt.state[3][i]!=-1){ Cright_B=Gt.state[3][i]; break; }i=(i+1)%N;}//printf("右城市B:%d\n",Cright_B);float da,db;da=Distance[C][Cright_A];db=Distance[C][Cright_B];if(da<=db) { OffSpr_C[kk++]=Cright_A;//加入記錄 C=Cright_A;}else{OffSpr_C[kk++]=Cright_B;C=Cright_B;}Gt.state[2][Ra]=-1;//刪除城市G1.state[0][Ra]---標記為-1Gt.state[3][Rb]=-1;count--;}OffSpr_C[N]=OffSpr_C[0];//最后一個城市與第一個城市相同 Gt=*G1;//保護G1//C=CV;C=rand()%N;//獲取隨機城市代號OffSpr_D[0]=C;//第4個子孫count=N; kk=1;while(count!=1){int Ra,Rb;for(i=0;i<N;i++)//求城市C在Gt.state[0][]、Gt.state[1][]中的下標位置 { if(Gt.state[2][i]==C) Ra=i;//記錄下標 if(Gt.state[3][i]==C) Rb=i;}//printf("隨機起始城市: %d---%d %d ",C,Ra,Rb); int Cleft_A,Cleft_B;for(i=(Ra-1+N)%N; ;)/尋找C在G1.state[0][]中的左城市號 {if(Gt.state[2][i]!=-1){ Cleft_A=Gt.state[2][i]; break; }i=(i-1+N)%N;}//printf("右城市A:%d ",Cleft_A);for(i=(Rb-1+N)%N; ;)/尋找C在G1.state[1][]中的左城市號 {if(Gt.state[3][i]!=-1){ Cleft_B=Gt.state[3][i]; break; }i=(i-1+N)%N;}//printf("右城市B:%d\n",Cleft_B);float da,db;da=Distance[C][Cleft_A];db=Distance[C][Cleft_B];if(da<=db) { OffSpr_D[kk++]=Cleft_A;//加入記錄 C=Cleft_A;}else{OffSpr_D[kk++]=Cleft_B; C=Cleft_B;}Gt.state[2][Ra]=-1;//刪除城市G1.state[0][Ra]---標記為-1Gt.state[3][Rb]=-1;count--;}OffSpr_D[N]=OffSpr_D[0];//最后一個城市與第一個城市相同//for(i=0;i<N+1;i++)//將交叉得到的序列復制回G1(*G1).state[0][i]=OffSpr_A[i];for(i=0;i<N+1;i++)(*G1).state[1][i]=OffSpr_B[i];for(i=0;i<N+1;i++)(*G1).state[2][i]=OffSpr_C[i];for(i=0;i<N+1;i++)(*G1).state[3][i]=OffSpr_D[i];for(i=0;i<4;i++){ for(int j=0;j<N+1;j++)printf("%d ",(*G1).state[i][j]);printf("\n");}}?
Copy_Variation.cpp(復制和變異)
#include<iostream> #include<stdlib.h>//for rand(),srand() #include<time.h> //for time() #include<math.h> #include<string.h> #include"head.h" #define N 10extern Generation OPEN[5000];//隊列-----(數據保護)每一代各染色體的情況 extern int OPhead,OPtail,openlen; extern float Distance[N][N];//存儲各個城市之間的直線距離 extern float MinShort;//最短路徑長度 extern int MinShortLoad[N+1];//最短路徑void Copy_Generation(Generation* G1,Generation G0)//根據被選中次數復制上一代染色體G0 { int i,j;int k=0;float maxloadlen=0;//選取路徑最長的用MinShortLoad[]替換int maxindex;for(i=0;i<4;i++)if(G0.loadlength[i]>maxloadlen){maxloadlen=G0.loadlength[i];maxindex=i;//記錄最長路徑下標 }for(j=0;j<N+1;j++)G0.state[i][j]=MinShortLoad[j];//替換最長的路徑為搜索過的最短路徑for(i=0;i<4;i++)//對于G0的每一個染色體for(j=0;j<G0.ChoiceNum[i];j++)//根據被選中次數復制G0染色體 {for(int t=0;t<N+1;t++)(*G1).state[k][t]=G0.state[i][t];k++;}for(i=0;i<3;i++)//交換子染色體的位置(減少相同染色體相鄰) {for(int k=0;k<N+1;k++) if((*G1).state[i][k]!=(*G1).state[i+1][k])//判斷第[i]個和第[i+1]個是否相同break;if(k==N+1)//相鄰染色體相同 {char temp[N+1]={0}; for(j=0;j<N+1;j++) temp[j]=(*G1).state[i+1][j];for(j=0;j<N+1;j++) (*G1).state[i+1][j]=(*G1).state[(i+2)%4][j];for(j=0;j<N+1;j++) (*G1).state[(i+2)%4][j]=temp[j];}}for(i=0;i<4;i++)//輸出復制后的情況 { for(j=0;j<N+1;j++)printf("%d ",(*G1).state[i][j]);printf("\n");} } void Variation(Generation *G1) {int i,j;int k=rand()%4;//取其中一條進行變異int R=rand()%N;//產生隨機起始城市下標//printf("%d %d\n",k,R);//printf("隨機起始城市: %d\n",(*G1).state[k][R]);float D=10000;int City=0;for(i=0;i<N;i++)//尋找距離起始城市最近的非鄰城市 {if(i!=(*G1).state[k][R] && i!=(*G1).state[k][(R-1+N)%N] && i!=(*G1).state[k][(R+1)%N])if(Distance[ (*G1).state[k][R] ][i]<D){D=Distance[ (*G1).state[k][R] ][i];//取離城市G1.state[0][R]最小距離City=i;//距離最近的城市號 }}//printf("最近城市: %d 距離: %f\n",City,D);//倒位int Sindex=(R+1)%N;//從隨機起始城市的--右邊城市開始進行倒位int Eindex;for(i=0;i<N;i++)//掃描染色體if((*G1).state[k][i]==City)Eindex=i;if(Sindex>Eindex) //保證起點下標<終點下標 {int temp=Sindex;Sindex=Eindex;Eindex=temp;}//printf("起點下標: %d 終點下標: %d\n",Sindex,Eindex);for(i=Sindex,j=Eindex;i<j;i++,j--){int temp=(*G1).state[k][i];(*G1).state[k][i]=(*G1).state[k][j];(*G1).state[k][j]=temp;}(*G1).state[k][N]=(*G1).state[k][0];for(i=0;i<4;i++){ for(j=0;j<N+1;j++)printf("%d ",(*G1).state[i][j]);printf("\n");} }?
?
?
轉載于:https://www.cnblogs.com/IThaitian/archive/2012/10/16/2726559.html
總結
以上是生活随笔為你收集整理的TSP_遗传算法求解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常量和字段
- 下一篇: IIS中架设二级域名网站