本人小白,最近想试试实现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里放的是什么啊?