用c语言编了一个粒子群算法,但是迭代过程中目标函数值一直没有变化,不知道是哪里出问题了,请帮忙看一下
以下是代码:
/*
- 使用C语言实现粒子群算法(PSO)
- 参考自《MATLAB智能算法30个案例分析》
- https://www.cnblogs.com/lyrichu/p/6151272.html */
#include
#include
#include
#include
#define C1 1.49445 /*加速度因子一般是根据大量实验所得*/
#define C2 1.49445
#define maxgen 3000 /*迭代次数*/
#define sizepop 2000 /*种群规模*/
#define popmax 10 /*个体最大取值*/
#define popmin 0 /*个体最小取值*/
#define Vmax 1 /*速度最大值*/
#define Vmin 0 /*速度最小值*/
/*#define dim 2 // 粒子的维数*/
#define q 5
#define T 12
#define delta 0.995
#define c1 0.5
#define c2 0.15
#define c3 0.37
#define c4 0.9
#define c5 0.9
#define rt 10.0
#define I 170.0
#define x_a0 5.0
#define x_a6 5.0
#define x_d 7.0
#define Po 2.0
#define Pm 5.0
#define K 12
#define Ko 1.0
#define Km 5.0
#define PI 3.1415926 /*圆周率*/
int dim; /*粒子的维数*/
double fitnessgbest; /* 群体极值适应度值*/
double pop,V,*fitness,*result,**pbest,*fitnesspbest,**genbest,*gbest;
/*适应度函数*/
double func(double * arr)
{
int i, N = 6;
double x_a, *obj, temp, fit, sum = 0.0;
x_a = (double *)malloc(dim*sizeof(double));
obj = (double *)malloc(N*sizeof(double));
x_a[0] = x_a0;
for (i=1;i<dim;i++)
{
if ((arr + i - 1) < x_a[i - 1])
x_a[i] = (arr + i - 1);
else
x_a[i] = x_a[i - 1];
if (i == 5) x_a[i] = x_a6;
}
for (i=0;i<N;i++)
obj[i] = 0.0;
for (i=0;i<q;i++)
{
temp = *(arr + i);
/*printf("%d\t%lf\t%lf",i,temp/x_a[i] * Po / Pm,log(temp/x_a[i] * Po / Pm));/
obj[0] += pow(delta,i) * c1 * log(temp/x_a[i] * Po / Pm);
sum += temp;
}
for (i=q;i
{
temp = *(arr + i);
obj[1] += pow(delta,i) * c2 * log(temp/rt * i /K );
obj[2] += c3 * temp * Ko / Km ;
if (*(arr + i)
obj[3] += c4 * log(temp/x_a[i]);
else
obj[3] += c4 * log(temp/x_d);
sum += temp;
}
/*约束0
if (sum > I)
obj[4] = (sum - I) * (sum - I) / I / I;
else if (sum < 0)
obj[4] = sum * sum / I / I;
else
obj[4] = 0.0;
/*约束0<=t/k*xi/rt <=1作为惩罚函数加入目标函数中*/
for (i=q;i
{
temp = *(arr + i);
if (temp> 1)
sum += ( temp - 1) * (temp - 1);
else if (temp < 0)
sum += temp * temp;
else
sum += 0.0;
}
obj[5] = sum;
/*如果还有其它约束,同样以惩罚函数的方式处理*/
fit = 0.0;
for (i=0;i<N;i++)
fit += obj[i];
free(x_a);
x_a = NULL;
free(obj);
obj = NULL;
fit = -fit;/*模型是最大化,目标改为最小化*/
return fit;
}
/* 种群初始化*/
void pop_init(void)
{
int i,j;
for(i=0;i
{
for(j=0;j
{
pop[i][j] = popmin + (((double)rand())/RAND_MAX)*(popmax-popmin); /*-2到2之间的随机数*/
V[i][j] = Vmin + (((double)rand())/RAND_MAX)*(Vmax-Vmin); /*-0.5到0.5之间*/
}
fitness[i] = func(pop[i]); /*计算适应度函数值*/
}
}
/* max()函数定义*/
double * max(double * fit,int size)
{
int index = 0; /* 初始化序号*/
int i;
double max = *fit; /* 初始化最大值为数组第一个元素*/
static double best_fit_index[2];
for(i=1;i
{
if(*(fit+i) > max)
max = *(fit+i);
index = i;
}
best_fit_index[0] = index;
best_fit_index[1] = max;
return best_fit_index;
}
/* 迭代寻优*/
void PSO_func(void)
{
pop_init();
double * best_fit_index; /* 用于存放群体极值和其位置(序号)*/
int i,j,k;
best_fit_index = max(fitness,sizepop); /*求群体极值*/
int index = (int)(*best_fit_index);
/* 群体极值位置*/
for(i=0;i<dim;i++)
{
gbest[i] = pop[index][i];
}
/* 个体极值位置*/
for(i=0;i<sizepop;i++)
{
for(j=0;j<dim;j++)
{
pbest[i][j] = pop[i][j];
}
}
/* 个体极值适应度值*/
for(i=0;i<sizepop;i++)
{
fitnesspbest[i] = fitness[i];
}
/*群体极值适应度值*/
double bestfitness = *(best_fit_index+1);
fitnessgbest = bestfitness;
/*迭代寻优*/
for(i=0;i<maxgen;i++)
{
for(j=0;j<sizepop;j++)
{
/*速度更新及粒子更新*/
for(k=0;k<dim;k++)
{
/* 速度更新*/
double rand1 = (double)rand()/RAND_MAX; /*0到1之间的随机数*/
double rand2 = (double)rand()/RAND_MAX;
V[j][k] = V[j][k] + C1*rand1*(pbest[j][k]-pop[j][k]) + C2*rand2*(gbest[k]-pop[j][k]);
if(V[j][k] > Vmax)
V[j][k] = Vmax;
if(V[j][k] < Vmin)
V[j][k] = Vmin;
/* 粒子更新*/
pop[j][k] = pop[j][k] + V[j][k];
if(pop[j][k] > popmax)
pop[j][k] = popmax;
if(pop[j][k] < popmin)
pop[j][k] = popmin;
}
fitness[j] = func(pop[j]); /*新粒子的适应度值*/
}
for(j=0;j<sizepop;j++)
{
/* 个体极值更新*/
if(fitness[j] > fitnesspbest[j])
{
for(k=0;k<dim;k++)
{
pbest[j][k] = pop[j][k];
}
fitnesspbest[j] = fitness[j];
}
/* 群体极值更新*/
if(fitness[j] > fitnessgbest)
{
for(k=0;k<dim;k++)
gbest[k] = pop[j][k];
fitnessgbest = fitness[j];
}
}
for(k=0;k<dim;k++)
{
genbest[i][k] = gbest[k]; /* 每一代最优值取值粒子位置记录*/
}
result[i] = fitnessgbest; /* 每代的最优值记录到数组*/
}
}
/* 主函数*/
int main(void)
{
clock_t start,finish; /*程序开始和结束时间*/
int i;
FILE fp;
start = clock(); /开始计时*/
dim = T;
pop = (double**)malloc(sizeof(double*)*sizepop);
V = (double**)malloc(sizeof(double*)*sizepop);
pbest = (double**)malloc(sizeof(double*)*sizepop);
genbest = (double**)malloc(sizeof(double*)*maxgen);
for(i=0;i<sizepop;i++){
pop[i]=(double*)malloc(sizeof(double)*dim); /* 创建种群数组*/
V[i]=(double*)malloc(sizeof(double)*dim); /* 创建种群速度数组*/
pbest[i]=(double*)malloc(sizeof(double)*dim); /* 个体极值的位置*/
}
for(i=0;i<maxgen;i++)
genbest[i]=(double*)malloc(sizeof(double)*dim); /*每一代最优值取值粒子*/
fitness = (double *)malloc(sizepop*sizeof(double)); /*创建种群的适应度数组*/
result = (double *)malloc(maxgen*sizeof(double)); /*创建存放每次迭代种群最优值的数组*/
gbest = (double *)malloc(dim*sizeof(double)); /*群体极值的位置*/
fitnesspbest = (double *)malloc(sizepop*sizeof(double)); /*个体极值适应度的值*/
srand((unsigned)time(NULL)); /* 初始化随机数种子*/
PSO_func();
double * best_arr;
best_arr = max(result,maxgen);
int best_gen_number = *best_arr; /* 最优值所处的代数*/
double best = *(best_arr+1); /*最优值*/
printf("迭代了%d次,在第%d次取到最优值,最优值为:%lf.\n",maxgen,best_gen_number+1,best);
if((fp=fopen("x_best.txt","w"))==NULL)
{
printf("file x_best.txt cannot open \n");
exit(-1);
}
else
{
for (i=0;i<dim;i++)
fprintf(fp,"%lf\n", genbest[best_gen_number][i]);
}
printf("取到最优值的位置已输出到x_best.txt\n");
fclose(fp);
if((fp=fopen("objective.txt","w"))==NULL)
{
printf("file objective.txt cannot open \n");
exit(-1);
}
else
{
for (i=0;i<maxgen;i++)
fprintf(fp,"%lf\n", result[i]);
}
printf("取到最优值的位置已输出到objective.txt\n");
fclose(fp);
finish = clock(); /*结束时间*/
double duration = (double)(finish - start)/CLOCKS_PER_SEC; /* 程序运行时间*/
printf("程序运行耗时:%lf\n",duration);
return 0;
}