C語言編寫遺傳演算法解決TSP旅行商問題

2021-07-06 02:05:59 字數 4542 閱讀 7548

最近在上計算智慧型的課,老師剛剛教了遺傳演算法,布置了用遺傳演算法解決tsp的問題的作業,於是經過幾小時的奮戰,終於編寫完成。

首先先對tsp問題進行分析。tsp問題,也就是旅行商問題,題目的大題內容是 一位旅行商,要遍遊n座城市(城市數量記為num_city), 已知每兩座城市之間的位置,要求每座城市必須去且只去過一次,求遍遊該n座城市的最短路程。

利用遺傳演算法解決該問題,步驟如下:

1.初始化城市之間的距離

2.生成並初始化初始種群,種群內每個個體儲存著一條完整的路徑(每個城市標號出現且只出現一次)

3.計算目前種群每個個體的適應值(要求求最短路程,路徑一定是個正數,故而得到每個個體中儲存的路徑的總路程後,取倒數,得到的數越大,適應性越高,總路程越短)

4.找出目前最優個體,讓其直接複製至下一代(即不變異)

5.對其他個體根據發生交叉互換的概率pc,得到參與交叉互換的個體集合

6.使參與交叉互換的個體隨機發生交叉互換(每個個體只參與一次)交叉互換的片段起始點和終點均隨機產生

7.對除最優個體外的每個個體,根據突變概率pm發生突變,隨機產生兩個位置點,使這兩個位置點之間的片段進行置倒(即2345變成5432)

8.迴圈執行步驟34567,直到演變代數》generations為止(暫定為5000代)

**如下所示,(注釋部分用的printf用於測試查錯,可忽視)

#include #include #include #include #define rand(x) (rand()%(x))

#define num_city (30)

#define generations (5000)

#define max_size (50)

#define lowest_alive (1.0/max_size)

typedef struct _groupgroup;

int citydistance[num_city][num_city];

group g_group[max_size];

float pm = 0.1;

float pc = 0.8;

int bestone;

void getfitness(group &group) // 得到適應值

group.adapt = distance;

group.palive = 1 / (float)distance;

}void swap(int &a, int &b) // 交換ab值

void init() // 初始化

} printf("城市距離如下:\n");

for (int i = 0; i < num_city; i++)

printf("\n");

} for (int i = 0; i < max_size; i++) // 初始化樣本數列 }

int r;

for (int i = 0; i < max_size; i++) // 打亂順序 }

printf("產生初始種群如下:\n");

for (int i = 0; i < max_size; i++)

printf("\n"); }}

void getalivep() // 存活率

for (int i = 0; i < max_size; i++) // 矯正個體存活率 讓總和為1

bestone = 0;

for (int i = 0; i < max_size; i++)

printf("目前最佳個體為:%d, 其距離為%d,其軌跡如下:\n", bestone+1, g_group[bestone].adapt);

for (int i = 0; i < num_city; i++)

printf("%d ", g_group[bestone].city[i]);

printf("\n");

}int isonit(int num, int array[num_city], int ignorepos, int pos1, int pos2) // num是否在array的pos1到pos2之間 其中跳過ignorepos(該數字的原位置)

return -1;

}void swap(int sel1,int sel2,int pos1, int pos2) // 交叉互換

//for (int j = 0; j < num_city; j++)

// printf("%4d", g_group[sel1].city[j]);

//printf("\n");

//for (int j = 0; j < num_city; j++)

// printf("%4d", g_group[sel2].city[j]);

//printf("\n");

int pos;

//printf("開始矯正重複值\n");

int times = 0;

for (int i = 0; i < num_city; i++) // 矯正重複值

do } while (pos != -1);

do} while (pos != -1);

}// printf("交叉互換過程完畢\n");

}void mutation(int sel, int pos1,int pos2)//個體突變

}void genetic() // 產生下一代種群

g_group[minnum] = g_group[maxnum]; // 使最大直接替換最小

//printf("開始交叉\n");

// 交叉配對

int selnum;

int maxtimes = 0, nowtimes = 0;

int canselected[max_size]; // 可以用於交叉的個體

bool iscanselected[max_size];

for (int i = 0; i < max_size; i++) }

for (int i = 0; i < maxtimes; i++)

int pos1, pos2;

for (int i = 0; i < maxtimes; i+=2)

/* printf("%d與%d開始交叉互換\n", canselected[i], canselected[selnum]);*/

swap(canselected[i], canselected[selnum], pos1, pos2);

/*printf("第%d個體與第%d個體進行交叉配對,得到新的兩個個體如下:\n", canselected[i] + 1, canselected[selnum] + 1);

printf("第%d個體:\n", canselected[i] + 1);

for (int j = 0; j < num_city; j++)

printf("%4d", g_group[canselected[i]].city[j]);

printf("\n第%d個體:\n", canselected[selnum] + 1);

for (int j = 0; j < num_city; j++)

printf("%4d", g_group[canselected[selnum]].city[j]);

printf("\nselnum:%d, maxtimes:%d\n",selnum,maxtimes);*/

}/*printf("開始突變\n");*/

// 突變

for (int i = 0; i < max_size; i++)

if (rand(100) / 100.0 < pm) // 符合突變概率

/*printf("第%d個體突變前:\n", i + 1);

for (int j = 0; j < num_city; j++)

printf("%4d", g_group[i].city[j]);

printf("\n");*/

mutation(i, pos1, pos2);

// printf("第%d個體突變:\n", i + 1);/*

// for (int j = 0; j < num_city; j++)

// printf("%4d", g_group[i].city[j]);

// printf("\n");

} }}void train()

while (nowgenerations < generations);

printf("經過%d次繁衍,得到的優秀個體為:\n", nowgenerations);

printf("其距離為%d,其軌跡如下:\n", g_group[bestone].adapt);

for (int i = 0; i < num_city; i++)

printf("%d ", g_group[bestone].city[i]);

printf("\n");

printf("其他個體如下:\n");

for (int i = 0; i < max_size; i++)

printf("\n"); }}

int main()

tsp問題 遺傳演算法解決

tsp問題最簡單的求解方法是列舉法。它的解是多維的 多區域性極值的 趨於無窮大的複雜解的空間,搜尋空間是n個點的所有排列的集合,大小為 n 1 可以形象地把解空間看成是乙個無窮大的丘陵地帶,各山峰或山谷的高度即是問題的極值。求解tsp,則是在此不能窮盡的丘陵地帶中攀登以達到山頂或谷底的過程。這一篇將...

遺傳演算法解決TSP問題

基本原理在 中有注釋 1 include2 include 3 include 4 include5 include 6 using std string 7 8struct position9 1617 double tsp int n,struct position position,int t...

tsp遺傳演算法

include include include include include include using namespace std define m 10 種群規模 define n 31 省會 首府城市數量 define t 10000 遺傳代數 define earth radius 637...