本人小白,最近想试试实现TSP问题的遗传算法,出了bug,花了很多时间找不出原因,希望大家帮看看,谢谢
问题描述:在种群和代数小的时候可以运行,大了就会出错
以下是代码:
问题描述:在种群和代数小的时候可以运行,大了就会出错
以下是代码:
#include <stdio.h> #include <stdlib.h> #include <Math.h> #include <time.h> #define GROUP_NUM 50 #define SELECT_SIZE 2 #define P_MUTATE 0.015 #define GENERATION 1000 struct Tour { int* gene = nullptr; }p1,p2,child; struct Population { Tour* individual = nullptr; }group, newGroup; void init(int* a, int cityNum) { int i; for (i = 0; i < cityNum; i++) { a[i] = -1; } } void swap(int* a, int* b) { int temp; temp = *a; *a = *b; *b = temp; } void copy(int* a, int* b, int num) { int i; for (i = 0; i <num; i++) { a[i] = b[i]; } } bool check(struct Tour* tour, int cityNum, int city) { int i; bool token = false; for (i = 0; i < cityNum; i++) { if (city == tour->gene[i]) token = true; } return token; } void getData(FILE *fp, int *a, int n) { int i; fseek(fp, 0, 0); for (i = 0; i<n; i++) fscanf(fp, "%d", &a[i]); } int getDataNum(FILE *fp) { int i = 0, n; fseek(fp, 0, 0); while (fscanf(fp, "%d", &n) != EOF) i++; return i; } double fitValue(int* distance, struct Tour* individual, int cityNum) { int i, j; int sum = 0; for (i = 0; i < cityNum - 1; i++) { j = i + 1; sum += distance[individual->gene[i] * cityNum + individual->gene[j]]; } sum += distance[individual->gene[j] * cityNum + individual->gene[0]]; return 1.0 / sum; } int totalDis(int* distance, struct Tour* individual, int cityNum) { int i, j; int sum = 0; for (i = 0; i < cityNum - 1; i++) { j = i + 1; sum += distance[individual->gene[i] * cityNum + individual->gene[j]]; } sum += distance[individual->gene[j] * cityNum + individual->gene[0]]; return sum; } void printLine(int* distance, struct Tour individual, int cityNum) { int route, j; printf("group line:\n"); for (j = 0; j < cityNum; j++) { printf("%d ", individual.gene[j]); } route = totalDis(distance, &individual, cityNum); printf("\nsum=%d\n", route); } int getFittest(struct Population* group, int* distance, int cityNum, int size) { int i, fittest = 0; for (i = 1; i < size; i++) { if (fitValue(distance, &(group->individual[i]), cityNum) > fitValue(distance, &(group->individual[fittest]), cityNum)) fittest = i; } return fittest; } void shuffle(int* base, int num) { int index, tmp, i; int srand((int)time(NULL)); for (i = 0; i <num; i++) { swap(&base[i], &base[rand() % num]); } } void mutate(struct Tour* tour, int cityNum) { int startPos, endPos; double token; for (startPos = 0; startPos < cityNum; startPos++) { token = rand() / double(RAND_MAX); if (token < P_MUTATE) { endPos = (int)(token*cityNum); swap(&(tour->gene[startPos]), &(tour->gene[endPos])); } } } Tour select(struct Population* group, int cityNum, int* distance) { int i, ID, best; double token; Population selectGroup; Tour fittest; selectGroup.individual = (Tour*)malloc(sizeof(Tour)*SELECT_SIZE); for (i = 0; i < SELECT_SIZE; i++) { selectGroup.individual[i].gene = (int*)malloc(sizeof(int)*cityNum); init(selectGroup.individual[i].gene, cityNum); } for (i = 0; i < SELECT_SIZE; i++) { token = rand() / double(RAND_MAX); ID = (int)(token*GROUP_NUM); copy((selectGroup.individual[i].gene), (group->individual[ID].gene), cityNum); } best = getFittest(&selectGroup, distance, cityNum, SELECT_SIZE); fittest = selectGroup.individual[best]; for (i = 0; i < SELECT_SIZE; i++) { if (i != best) { free(selectGroup.individual[i].gene); selectGroup.individual[i].gene = nullptr; } } free(selectGroup.individual); selectGroup.individual = nullptr; return fittest; } Tour crossOver(struct Tour* p1, struct Tour* p2, int cityNum) { Tour child; child.gene = (int*)malloc(sizeof(int)*cityNum); int startPos, endPos, i, j; for (i = 0; i < cityNum; i++) { child.gene[i] = -1; } double token ; do { token = rand() / double(RAND_MAX); startPos = (int)(token*cityNum); token = rand() / double(RAND_MAX); endPos = (int)(token*cityNum); } while (startPos >= endPos); for (i = 0; i < cityNum; i++) { if ((i <= endPos) && (i >= startPos)) child.gene[i] = p1->gene[i]; } for (i = 0; i < cityNum; i++) { if (!(check(&child, cityNum, p2->gene[i]))) { for (j = 0; j < cityNum; j++) { if (child.gene[j] == -1) { child.gene[j] = p2->gene[i]; break; } } } } return child; } //测试代码 void printRoute(int* distance, struct Population group, int cityNum) { int route, i, j; for (i = 0; i < GROUP_NUM; i++) { printf("group %d route:\n", i); for (j = 0; j < cityNum; j++) { printf("%d ", group.individual[i].gene[j]); } route = totalDis(distance, &group.individual[i], cityNum); printf("\nsum=%d\n", route); } } int main() { int index, *distance, i, j; char *myfile = "d:\data5.txt"; FILE *fp = nullptr; if ((fp = fopen(myfile, "r")) == NULL){ printf("打开文件%s失败\n", myfile); return 0; } index = getDataNum(fp); int cityNum = (int)sqrt((double)index); distance = (int *)malloc(sizeof(int)*index); getData(fp, distance, index); //创建Population group.individual = (Tour*)malloc(sizeof(Tour)*GROUP_NUM); for (i = 0; i < GROUP_NUM; i++) { group.individual[i].gene = (int*)malloc(sizeof(int)*cityNum); init(group.individual[i].gene, cityNum); } newGroup.individual = (Tour*)malloc(sizeof(Tour)*GROUP_NUM); for (i = 0; i < GROUP_NUM; i++) { newGroup.individual[i].gene = (int*)malloc(sizeof(int)*cityNum); init(newGroup.individual[i].gene, cityNum); } int* base = (int*)malloc(sizeof(int)*cityNum); for (i = 0; i < cityNum; i++) base[i] = i; for (i = 0; i < GROUP_NUM; i++) { shuffle(base, cityNum); copy(group.individual[i].gene, base, cityNum); } printf("before GA\n"); printRoute(distance, group, cityNum); printf("after GA\n"); for (i = 0; i < GENERATION; i++) { int best, cursor; best = getFittest(&group, distance, cityNum, GROUP_NUM); copy(newGroup.individual[0].gene, group.individual[best].gene, cityNum); for (cursor = 1; cursor < GROUP_NUM; cursor++) { p1 = select(&group, cityNum, distance); // printLine(distance, p1, cityNum); p2 = select(&group, cityNum, distance); // printLine(distance, p2, cityNum); child = crossOver(&p1, &p2, cityNum); // printLine(distance, child, cityNum); copy(newGroup.individual[cursor].gene, child.gene, cityNum); free(p1.gene); p1.gene = nullptr; free(p2.gene); p2.gene = nullptr; free(child.gene); child.gene = nullptr; } // printRoute(distance, newGroup, cityNum); for (cursor = 1; cursor < GROUP_NUM; cursor++) { mutate(&(newGroup.individual[cursor]), cityNum); } // printRoute(distance, newGroup, cityNum); for (cursor = 0; cursor < GROUP_NUM; cursor++) { copy(group.individual[cursor].gene, newGroup.individual[cursor].gene, cityNum); } } printRoute(distance, group, cityNum); int best = getFittest(&group, distance, cityNum, GROUP_NUM); printf("best individual=%d\n", best); printf("best route:\n"); printf("%d -->", group.individual[best].gene[0]); for (i = 1; i < cityNum - 1; i++) { printf(" %d -->", group.individual[best].gene[i]); } printf(" %d\n", group.individual[best].gene[cityNum - 1]); /* //测试select函数和crossover函数 p1 = select(&group, cityNum, distance); p2 = select(&group, cityNum, distance); child = crossOver(&p1, &p2, cityNum); */ /* //测试矩阵 for (i = 0; i < index; i++) { printf("%d ", distance[i]); } printf("\n"); */ /* for (i = 0; i < cityNum; i++) { printf("%d ", p1.gene[i]); } printf("\n"); for (i = 0; i < cityNum; i++) { printf("%d ", p2.gene[i]); } printf("\n"); for (i = 0; i < cityNum; i++) { printf("%d ", child.gene[i]); } */ for (i = 0; i < GROUP_NUM; i++) { free(group.individual[i].gene); group.individual[i].gene = nullptr; } free(group.individual); group.individual = nullptr; for (i = 0; i < GROUP_NUM; i++) { free(newGroup.individual[i].gene); newGroup.individual[i].gene = nullptr; } free(newGroup.individual); newGroup.individual = nullptr; free(distance); distance = nullptr; //free(p1.gene); //p1.gene = nullptr; //free(p2.gene); //p2.gene = nullptr; //free(child.gene); //child.gene = nullptr; free(base); base = nullptr; fclose(fp); system("pause"); return 0; }
再次谢谢各位了,打得不好的地方请轻喷
解决方案
100
你那个data5.txt里放的是什么啊?