完成,结果如下:
收获:
数组或者指针或者变量,用完后,如果之后的程序仍然需要用到而且与之前所得的值没有关系,一定要及时初始化,一面影响后面的使用。
贴代码:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <time.h>
#define BOUND_DOWN 1
#define BOUND_UP 14
#define POP_SIZE 200
#define CHROM_LEN 14
#define EVO_NUM 500
#define CROSS_PROBABILITY 0.6
#define VARY_PROBABILITY 0.1
typedef struct best
{
int num;
float funcVal;
int bestChrom[CHROM_LEN];
}Best;
float sglDistance(float city_1[2], float city_2[2])
{
float s = 0;
s = sqrt(pow((city_1[0] - city_2[0]), 2) + pow((city_1[1] - city_2[1]), 2));
return s;
}
void wholeDistance(int chrom[POP_SIZE][CHROM_LEN], float dist[POP_SIZE], float city[CHROM_LEN][2])
{
float sglDist[POP_SIZE][CHROM_LEN - 1];
int i = 0, j = 0;
for (i = 0; i < POP_SIZE; i++)
{
memset(sglDist[i], 0, sizeof(sglDist[i]));
}
for (i = 0; i < POP_SIZE; i++)
{
for (j = 0; j < CHROM_LEN - 1; j++)
{
sglDist[i][j] = sglDistance(city[chrom[i][j] - 1], city[chrom[i][j + 1] - 1]);
dist[i] += sglDist[i][j];
}
}
}
void testPrint(int chrom[POP_SIZE][CHROM_LEN])
{
int i = 0, j = 0;
for (i = 0; i < POP_SIZE; i++)
{
for (j = 0; j < CHROM_LEN; j++)
{
if (j == (CHROM_LEN - 1))
{
printf("%d", chrom[i][j]);
}
else
{
printf("%d-", chrom[i][j]);
}
}
printf("\n");
}
}
void creat(int chrom[POP_SIZE][CHROM_LEN])
{
int i = 0, j = 0, k = 0, m = 0, flag = 1;
for (i = 0; i < POP_SIZE; i++)
{
for (j = 0; j < CHROM_LEN; )
{
flag = 1;
m = rand() % CHROM_LEN + 1;
for (k = 0; k < j; k++)
{
if (chrom[i][k] == m)
{
flag = 0;
break;
}
}
if (flag == 1)
{
chrom[i][j] = m;
j++;
}
else
{
continue;
}
}
}
}
void fit(float dist[POP_SIZE], float fitness[POP_SIZE])
{
int i = 0;
for (i = 0; i < POP_SIZE; i++)
{
fitness[i] = 1 / dist[i];
}
}
void fitnessP(float fitness[POP_SIZE], float chooseP[POP_SIZE], float accuP[POP_SIZE])
{
float wholeFit = 0;
int i = 0, j = 0;
for (i = 0; i < POP_SIZE; i++)
{
wholeFit += fitness[i];
}
for (i = 0; i < POP_SIZE; i++)
{
chooseP[i] = fitness[i] / wholeFit;
}
accuP[0] = chooseP[0];
for (i = 1; i < POP_SIZE; i++)
{
accuP[i] = accuP[i - 1] + chooseP[i];
}
}
void roulette(int chrom[POP_SIZE][CHROM_LEN], float chooseP[POP_SIZE], float accuP[POP_SIZE])
{
float r = 0;
int i = 0, j = 0, k = 0, m = 0;
int tmp[POP_SIZE][CHROM_LEN];
for (i = 0; i < POP_SIZE; i++)
{
memset(tmp[i], 0, sizeof(tmp[i]));
}
for (i = 0; i < POP_SIZE; i++)
{
r = ((float)rand()) / (RAND_MAX + 1);
if (r < accuP[0])
{
for (j = 0; j < CHROM_LEN; j++)
{
tmp[k][j] = chrom[0][j];
}
k++;
}
else
{
for (m = 1; m < POP_SIZE; m++)
{
if ((r >= accuP[m - 1]) && (r < accuP[m]))
{
for (j = 0; j < CHROM_LEN; j++)
{
tmp[k][j] = chrom[m][j];
}
k++;
}
}
}
}
for (i = 0; i < POP_SIZE; i++)
{
for (j = 0; j < CHROM_LEN; j++)
{
chrom[i][j] = tmp[i][j];
}
}
}
void cross(int chrom[POP_SIZE][CHROM_LEN])
{
int tmp_1[2][CHROM_LEN], tmp_2[2][CHROM_LEN];
int tmp;
int choice_1 = 0, choice_2 = 0, tmp_0 = 0, r_1 = 0, r_2 = 0, i = 0, j = 0, k = 0, m = 0, n = 0;
float pCross = 0;
for (i = 0; i < (POP_SIZE - 1); i++)
{
choice_2 = choice_1 + 1;
pCross = ((float)rand()) / RAND_MAX;
if (pCross < CROSS_PROBABILITY)
{
r_1 = rand() % CHROM_LEN;
r_2 = rand() % CHROM_LEN;
if (r_1 > r_2)
{
tmp_0 = r_1;
r_1 = r_2;
r_2 = tmp_0;
}
for (j = r_1; j < (r_2 + 1); j++)
{
tmp = chrom[choice_1][j];
chrom[choice_1][j] = chrom[choice_2][j];
chrom[choice_2][j] = tmp;
}
for (j = 0; j < 2; j++)
{
for (k = 0; k < CHROM_LEN; k++)
{
tmp_1[j][k] = -1;
tmp_2[j][k] = -1;
}
}
m = 0;
n = 0;
for (j = 0; j < CHROM_LEN; j++)
{
if ((j >= r_1) && (j <= r_2))
{
continue;
}
for (k = r_1; k < (r_2 + 1); k++)
{
if (chrom[choice_1][j] == chrom[choice_1][k])
{
tmp_1[0][m] = j;
tmp_1[1][m] = chrom[choice_1][j];
m++;
}
}
for (k = r_1; k < (r_2 + 1); k++)
{
if (chrom[choice_2][j] == chrom[choice_2][k])
{
tmp_2[0][n] = j;
tmp_2[1][n] = chrom[choice_2][j];
n++;
}
}
}
for (j = 0; j < CHROM_LEN; j++)
{
if (tmp_1[0][j] != -1)
{
chrom[choice_1][tmp_1[0][j]] = tmp_2[1][j];
}
if (tmp_2[0][j] != -1)
{
chrom[choice_2][tmp_2[0][j]] = tmp_1[1][j];
}
}
}
choice_1++;
}
}
void vary(int chrom[POP_SIZE][CHROM_LEN])
{
int i = 0, r_1 = 0, r_2 = 0, tmp = 0;
float pVary = 0;
for (i = 0; i < POP_SIZE; i++)
{
pVary = ((float)rand()) / RAND_MAX;
if (pVary > VARY_PROBABILITY)
{
continue;
}
do
{
r_1 = rand() % CHROM_LEN;
r_2 = rand() % CHROM_LEN;
} while (r_1 == r_2);
tmp = chrom[i][r_1];
chrom[i][r_1] = chrom[i][r_2];
chrom[i][r_2] = tmp;
}
}
void evolution(int chrom[POP_SIZE][CHROM_LEN], float city[CHROM_LEN][2])
{
int i = 0, j = 0, k = 0, r_1 = 0, r_2 = 0, tmp_0 = 0;
int before[POP_SIZE][CHROM_LEN];
int tmp[CHROM_LEN];
float sglDist_before[CHROM_LEN - 1], dist_before = 0, fitness_before = 0;
float sglDist_after[CHROM_LEN - 1], dist_after = 0, fitness_after = 0;
for (i = 0; i < POP_SIZE; i++)
{
memset(tmp, 0, sizeof(tmp));
memset(sglDist_before, 0, sizeof(sglDist_before));
for (j = 0; j < CHROM_LEN - 1; j++)
{
sglDist_before[j] = sglDistance(city[chrom[i][j] - 1], city[chrom[i][j + 1] - 1]);
dist_before += sglDist_before[j];
}
fitness_before = 1 / dist_before;
for (j = 0; j < CHROM_LEN; j++)
{
before[i][j] = chrom[i][j];
}
do
{
r_1 = rand() % CHROM_LEN;
r_2 = rand() % CHROM_LEN;
} while (r_1 == r_2);
if (r_1 > r_2)
{
tmp_0 = r_1;
r_1 = r_2;
r_2 = tmp_0;
}
for (j = r_2, k = 0; j >= r_1; j--)
{
tmp[k] = chrom[i][j];
k++;
}
for (j = r_1, k = 0; j <= r_2; j++)
{
chrom[i][j] = tmp[k];
k++;
}
memset(sglDist_after, 0, sizeof(sglDist_after));
for (j = 0; j < CHROM_LEN - 1; j++)
{
sglDist_after[j] = sglDistance(city[chrom[i][j] - 1], city[chrom[i][j + 1] - 1]);
dist_after += sglDist_after[j];
}
fitness_after = 1 / dist_after;
if (fitness_before > fitness_after)
{
for (j = 0; j < CHROM_LEN; j++)
{
chrom[i][j] = before[i][j];
}
}
}
}
void main(void)
{
float city[CHROM_LEN][2] = { {16.47, 96.10}, {16.47, 94.44}, {20.09, 92.54}, {22.39, 93.37},
{25.23, 97.24}, {22.00, 96.05}, {20.47, 97.02}, {17.20, 96.29},
{16.30, 97.38}, {14.05, 98.12}, {16.53, 97.38}, {21.52, 95.59},
{19.41, 97.13}, {20.09, 92.55} };
float dist[POP_SIZE], fitness[POP_SIZE], chooseP[POP_SIZE], accuP[POP_SIZE], tmp = 0;
int chrom[POP_SIZE][CHROM_LEN];
int i = 0, j = 0, k = 0;
Best best;
best.num = 0;
best.funcVal = 0;
memset(best.bestChrom, 0, sizeof(best.bestChrom));
memset(dist, 0, sizeof(dist));
memset(fitness, 0, sizeof(fitness));
memset(chooseP, 0, sizeof(chooseP));
memset(accuP, 0, sizeof(accuP));
for (i = 0; i < POP_SIZE; i++)
{
memset(chrom[i], 0, sizeof(chrom[i]));
}
srand(time(NULL));
creat(chrom);
wholeDistance(chrom, dist, city);
fit(dist, fitness);
for (i = 0; i < EVO_NUM; i++)
{
memset(dist, 0, sizeof(dist));
wholeDistance(chrom, dist, city);
fit(dist, fitness);
fitnessP(fitness, chooseP, accuP);
roulette(chrom, chooseP, accuP);
cross(chrom);
vary(chrom);
evolution(chrom, city);
memset(dist, 0, sizeof(dist));
wholeDistance(chrom, dist, city);
fit(dist, fitness);
for (j = 0; j < POP_SIZE; j++)
{
if (tmp < fitness[j])
{
tmp = fitness[j];
best.num = i;
best.funcVal = dist[j];
for (k = 0; k < CHROM_LEN; k++)
{
best.bestChrom[k] = chrom[j][k];
}
}
}
}
printf("最短路径出现在第%d代\n", best.num);
printf("最短路径为");
for (i = 0; i < CHROM_LEN; i++)
{
if (i == (CHROM_LEN - 1))
{
printf("%d", best.bestChrom[i]);
}
else
{
printf("%d-", best.bestChrom[i]);
}
}
printf("\n");
printf("最短路径长度为%f\n", best.funcVal);
}