关于TSP问题的遗传算法(C)的问题

C语言 码拜 9年前 (2016-05-02) 1159次浏览
本人小白,最近想试试实现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;
}

关于TSP问题的遗传算法(C)的问题
关于TSP问题的遗传算法(C)的问题
关于TSP问题的遗传算法(C)的问题
再次谢谢各位了,打得不好的地方请轻喷关于TSP问题的遗传算法(C)的问题

解决方案

100

你那个data5.txt里放的是什么啊?

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于TSP问题的遗传算法(C)的问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)