这个遗传算法的程序没调通,瓶颈有两方面,一是对算法理解不够深刻,步骤不够熟悉,二是语言运用不熟练,表达不出想要的东西,看来现在来写这种及数量比较高的算法是不是还太早了。
贴代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926
#define POP_SIZE 10
#define CHROM_LEN 5
#define EVO_MAX 10
#define BOUND_UP (0.9 * 3.1415926)
#define BOUND_DOWN 0
#define PCROSS 0.6
#define PVAR 0.1
/*目标函数*/
double func(double *p)
{
double x1 = *p;
double x2 = *(p + 1);
double x3 = *(p + 2);
double x4 = *(p + 3);
double x5 = *(p + 4);
double f = - 5 * sin(x1) * sin(x2) * sin(x3) * sin(x4) * sin(x5)
- sin(5 * x1) * sin(5 * x2) * sin(5 * x3) * sin(5 * x4) * sin(5 * x5) + 8;
return f;
}
/*初始化种群*/
void initPop(double p[POP_SIZE][CHROM_LEN])
{
int i, j;
for (i = 0; i < POP_SIZE; i++)
{
for (j = 0; j < CHROM_LEN; j++)
{
p[i][j] = BOUND_UP * (((double)rand()) / RAND_MAX);
}
}
}
/*求最小值*/
double *min_func(double p[POP_SIZE][CHROM_LEN])
{
int i, j, index = 0;
double min[2], min_f[POP_SIZE], _min;
for (i = 0; i < POP_SIZE; i++)
{
min_f[i] = func(p[i]);
}
_min = min_f[0];
for (i = 0; i < POP_SIZE; i++)
{
if (_min > min_f[i])
{
_min = min_f[i];
index = i;
}
}
min[0] = _min;
min[1] = (double)index;
return min;
}
/*选择操作*/
void choose(double p[POP_SIZE][CHROM_LEN])
{
int index[POP_SIZE];
double fitness[POP_SIZE], chooseP[POP_SIZE], accuP[POP_SIZE], p_temp[POP_SIZE][CHROM_LEN];
double sum_fitness;
double temp;
int i, j;
/*计算个体适应度*/
for (i = 0, sum_fitness = 0; i < POP_SIZE; i++)
{
fitness[i] = 1 / func(p[i]);
sum_fitness += fitness[i];
}
/*计算选择概率和累积概率*/
for (i = 0; i < POP_SIZE; i++)
{
accuP[i] = 0;
}
for (i = 0; i < POP_SIZE; i++)
{
chooseP[i] = fitness[i] / sum_fitness;
if (i == 0)
{
accuP[i] = chooseP[i];
}
else
{
accuP[i] = accuP[i - 1] + chooseP[i];
}
//printf("chooseP[%d]=%lf,accuP[%d]=%lf\n", i, chooseP[i], i, accuP[i]);
}
/*轮盘赌*/
for (i = 0; i < POP_SIZE; i++)
{
do
{
temp = ((double)rand()) / RAND_MAX;
} while (temp == 0);
//printf("temp=%lf\n", temp);
for (j = 0; j < POP_SIZE; j++)
{
if (temp < accuP[j])
{
index[i] = j;
break;
}
}
}
/*for (i = 0; i < POP_SIZE; i++)
{
printf("index[%d]=%d\n", i, index[i]);
}*/
/*生成新种群*/
for (i = 0; i < POP_SIZE; i++)
{
for (j = 0; j < CHROM_LEN; j++)
{
p_temp[i][j] = p[i][j];
}
}
for (i = 0; i < POP_SIZE; i++)
{
for (j = 0; j < CHROM_LEN; j++)
{
p[i][j] = p_temp[index[i]][j];
}
}
}
/*交叉操作*/
void cross(double p[POP_SIZE][CHROM_LEN])
{
int i, j, choice_1, choice_2, pos, flag;
double p_1, p_2, b, p_cross;
for (i = 0; i < POP_SIZE; i++)
{
p_cross = ((double)rand()) / RAND_MAX;
if (p_cross > PCROSS)
{
continue;
}
/*随机选择2条染色体*/
do
{
choice_1 = (int)(POP_SIZE * (((double)rand()) / RAND_MAX));
} while (choice_1 > POP_SIZE - 1);
do
{
choice_2 = (int)(POP_SIZE * (((double)rand()) / RAND_MAX));
} while (choice_2 > POP_SIZE - 1);
do
{
flag = 0;
do
{
pos = (int)(CHROM_LEN * (((double)rand()) / RAND_MAX));
} while (pos > CHROM_LEN - 1);
p_1 = p[choice_1][pos];
p_2 = p[choice_2][pos];
b = ((double)rand()) / RAND_MAX;
p[choice_1][pos] = p_1 * (1 - b) + p_2 * b;
p[choice_2][pos] = p_2 * (1 - b) + p_1 * b;
if (p[choice_1][pos] >= BOUND_DOWN && p[choice_1][pos] <= BOUND_UP && p[choice_2][pos] >= BOUND_DOWN && p[choice_2][pos] <= BOUND_UP)
{
flag = 1;
}
} while (flag == 0);
}
}
void var(double p[POP_SIZE][CHROM_LEN])
{
int i, choice, pos, flag;
double p_var, f, r_1, r_2, pp;
for (i = 0; i < POP_SIZE; i++)
{
p_var = ((double)rand()) / RAND_MAX;
if (p_var > PVAR)
{
continue;
}
/*随机选择1条染色体*/
do
{
choice = (int)(POP_SIZE * (((double)rand()) / RAND_MAX));
} while (choice > POP_SIZE - 1);
do
{
flag = 0;
r_1 = ((double)rand()) / RAND_MAX;
r_2 = ((double)rand()) / RAND_MAX;
f = r_2 * (1 - ((double)i) / (double)EVO_MAX);
do
{
pos = (int)(CHROM_LEN * (((double)rand()) / RAND_MAX));
} while (pos > CHROM_LEN - 1);
pp = p[choice][pos];
if (r_1 >= 0.5)
{
p[choice][pos] = pp + (pp - (double)BOUND_UP) * f;
}
else
{
p[choice][pos] = pp + ((double)BOUND_DOWN - pp) * f;
}
if (p[choice][pos] >= BOUND_DOWN && p[choice][pos] <= BOUND_UP)
{
flag = 1;
}
} while (flag == 0);
}
}
int main(void)
{
int i, j;
double pop[POP_SIZE][CHROM_LEN];
double best_eve[EVO_MAX + 1], best_pos[EVO_MAX + 1], best, bestPos;
double *best_zero;
srand((double)time(NULL));
/*初始化种群*/
initPop(pop);
best_zero = min_func(pop);
best_eve[0] = *best_zero;
best_pos[0] = *(best_zero + 1);
printf("best_eve[0]=%lf\n", best_eve[0]);
for (i = 1; i < (EVO_MAX + 1); i++)
{
choose(pop);
cross(pop);
var(pop);
best_zero = min_func(pop);
best_eve[i] = *best_zero;
best_pos[i] = *(best_zero + 1);
printf("best_eve[%d]=%lf\n",i , best_eve[0]);
}
best = best_eve[0];
bestPos = best_pos[0];
for (i = 0; i < (EVO_MAX + 1); i++)
{
if (best > best_eve[i])
{
best = best_eve[i];
bestPos = best_pos[i];
}
}
printf("best=%lf", best);
return 0;
}
以下四种方式实现通过指针形参对数组元素值进行改变。
#include <stdio.h>
void One_A(int *a)
{
int i;
for (i = 0; i < 5; i++)
{
a[i] = i;
}
}
void One_B(int b[])
{
int i;
for (i = 0; i < 5; i++)
{
b[i] = i;
}
}
void Two_C(int c[][5])
{
int i, j;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
c[i][j] = i + j;
}
}
}
void Two_D(int (*d)[5])
{
int i, j;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
d[i][j] = i + j;
}
}
}
int main(void)
{
int i;
int a[5], b[5], c[5][5], d[5][5], e[5][5];
One_A(a);
One_B(b);
Two_C(c);
Two_D(d);
printf("\n");
return 0;
}