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

x554014298 2016-07-12 10:42:04
本人小白,最近想试试实现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;
}




再次谢谢各位了,打得不好的地方请轻喷
...全文
205 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
x554014298 2016-07-13
  • 打赏
  • 举报
回复
0 107 241 190 124  80 316  76 152 157 283 133 113 297 228 129 348 276 188 150  65 341 184  67 221 169 108  45 167
107   0 148 137  88 127 336 183 134  95 254 180 101 234 175 176 265 199 182  67  42 278 271 146 251 105 191 139  79
241 148   0 374 171 259 509 317 217 232 491 312 280 391 412 349 422 356 355 204 182 435 417 292 424 116 337 273  77
190 137 374   0 202 234 222 192 248  42 117 287  79 107  38 121 152  86  68  70 137 151 239 135 137 242 165 228 205
124  88 171 202   0  61 392 202  46 160 319 112 163 322 240 232 314 287 238 155  65 366 300 175 307  57 220 121  97
80 127 259 234  61   0 386 141  72 167 351  55 157 331 272 226 362 296 232 164  85 375 249 147 301 118 188  60 185
 
316 336 509 222 392 386   0 233 438 254 202 439 235 254 210 187 313 266 154 282 321 298 168 249  95 437 190 314 435

76 183 317 192 202 141 233   0 213 188 272 193 131 302 233  98 344 289 177 216 141 346 108  57 190 245  43  81 243
152 134 217 248  46  72 438 213   0 206 365  89 209 368 286 278 360 333 284 201 111 412 321 221 353  72 266 132 111
157  95 232  42 160 167 254 188 206   0 159 220  57 149  80 132 193 127 100  28  95 193 241 131 169 200 161 189 163
 
283 254 491 117 319 351 202 272 365 159   0 404 176 106  79 161 165 141  95 187 254 103 279 215 117 359 216 308 322
 
133 180 312 287 112  55 439 193  89 220 404   0 210 384 325 279 415 349 285 217 138 428 310 200 354 169 241 112 238
 
113 101 280  79 163 157 235 131 209  57 176 210   0 186 117  75 231 165  81  85  92 230 184  74 150 208 104 158 206
 
297 234 391 107 322 331 254 302 368 149 106 384 186   0  69 191  59  35 125 167 255  44 309 245 169 327 246 335 288
 
228 175 412  38 240 272 210 233 286  80  79 325 117  69   0 122 122  56  56 108 175 113 240 176 125 280 177 266 243
 
129 176 349 121 232 226 187  98 278 132 161 279  75 191 122   0 244 178  66 160 161 235 118  62  92 277  55 155 275
 
348 265 422 152 314 362 313 344 360 193 165 415 231  59 122 244   0  66 178 198 286  77 362 287 228 358 299 380 319
 
276 199 356  86 287 296 266 289 333 127 141 349 165  35  56 178  66   0 112 132 220  79 296 232 181 292 233 314 253
188 182 355  68 238 232 154 177 284 100  95 285  81 125  56  66 178 112   0 128 167 169 179 120  69 283 121 213 281
 
150  67 204  70 155 164 282 216 201  28 187 217  85 167 108 160 198 132 128   0  88 211 269 159 197 172 189 182 135
  
65  42 182 137  65  85 321 141 111  95 254 138  92 255 175 161 286 220 167  88   0 299 229 104 236 110 149  97 108
 
341 278 435 151 366 375 298 346 412 193 103 428 230  44 113 235  77  79 169 211 299   0 353 289 213 371 290 379 332
 
184 271 417 239 300 249 168 108 321 241 279 310 184 309 240 118 362 296 179 269 229 353   0 121 162 345  80 189 342
  
67 146 292 135 175 147 249  57 221 131 215 200  74 245 176  62 287 232 120 159 104 289 121   0 154 220  41  93 218
 
221 251 424 137 307 301  95 190 353 169 117 354 150 169 125  92 228 181  69 197 236 213 162 154   0 352 147 247 350
 
169 105 116 242  57 118 437 245  72 200 359 169 208 327 280 277 358 292 283 172 110 371 345 220 352   0 265 178  39
 
108 191 337 165 220 188 190  43 266 161 216 241 104 246 177  55 299 233 121 189 149 290  80  41 147 265   0 124 263
  
45 139 273 228 121  60 314  81 132 189 308 112 158 335 266 155 380 314 213 182  97 379 189  93 247 178 124   0 199
 
167  79  77 205  97 185 435 243 111 163 322 238 206 288 243 275 319 253 281 135 108 332 342 218 350  39 263 199   0
您好,谢谢您的回复,data5里面放的是矩阵数据,我的解读是a[i][j]的数值是i城市到j城市的距离
flying_music 2016-07-13
  • 打赏
  • 举报
回复
你那个data5.txt里放的是什么啊?

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧