之前的一篇中贴出了自己研究生期间C实现的基本粒子群算法,执行速度显然要比其他的高级语言快,这也是各个编程语言之间的差别,现在对于曾经辉煌过的差分进化算法进行C语言实现。变异策略采用DE/rand/1,这个是最常见的。有错误之处请之处。
/***************Differential Evolution Algorithm*************************/
/*
* @Author: Gong Xu
* (c) Copyright 2018 ,DSP Laboratory of Lanzhou University of Technology, All rights reserved.
*
*/
# include<stdio.h>
# include<time.h>
# include<stdlib.h>
#include <string.h>
#define nVar 30 // Number of variables
#define nPop 50 // Number of Population
#define Iter 1000 // Maximum number of iterations
struct individual
{
double position[nVar];
double fitness;
};
struct DE
{
struct individual ptcle[nPop];
double F;
double CR;
double(*function)(double *); // Function pointer definition
double global_fitness;
double global_solution[nVar];
double x_low_bound;
double x_up_bound;
};
// sum(X^2)
double function_fitness(double *var)
{
double result = 0;
for (int i = 0; i<nVar; i++)
{
result += *(var + i)* *(var + i);// method one : pointer
//result += var[i] * var[i]; // method two : array
}
return result;
}
void runde(double F, double CR, double x_low_bound, double x_up_bound, double(*function_fitness)(double *))
{
struct DE de;
de.F = F;
de.CR= CR;
de.x_low_bound = x_low_bound;
de.x_up_bound = x_up_bound;
de.function =function_fitness;
srand((unsigned)time(NULL));
// inital de for iteration program
for (int i = 0; i<nPop; i++)
{
for (int j = 0; j<nVar; j++)
{
double randx = (double)rand() / RAND_MAX;
de.ptcle[i].position[j] = de.x_low_bound + (de.x_up_bound - de.x_low_bound)*randx;
}
de.ptcle[i].fitness = de.function(de.ptcle[i].position);
}
memcpy(&de.global_solution, &de.ptcle[0].position, sizeof(double)*nVar);
de.global_fitness = de.ptcle[0].fitness;
struct individual mutate[nPop];
struct individual cross[nPop];
// End of initialization
for (int it = 1; it <= Iter; it++)
{
// mutate
for (int i = 0; i < nPop; i++)
{
int rand1 = (int)rand() % nPop;
int rand2 = (int)rand() % nPop;
int rand3 = (int)rand() % nPop;
if(rand1 == i || rand2 == i || rand3 == i || rand1 == rand2 || rand2 == rand3)
{
rand1 = (int)rand() % nPop;
rand2 = (int)rand() % nPop;
rand3 = (int)rand() % nPop;
}
for (int j = 0; j<nVar; j++)
{
mutate[i].position[j] = de.ptcle[rand1].position[j] + F*(de.ptcle[rand2].position[j] - de.ptcle[rand3].position[j]);
if (mutate[i].position[j] > de.x_up_bound)
{
mutate[i].position[j] = de.x_up_bound;
}
if (mutate[i].position[j] < de.x_low_bound)
{
mutate[i].position[j] = de.x_low_bound;
}
}
}
//crossover
for (int i = 0; i < nPop; i++)
{
int randc = (int)rand() % nVar;
for (int j = 0; j < nVar; j++)
{
double rand_cr = (double)rand() / RAND_MAX;
if ((j == randc) || (rand_cr < de.CR))
{
cross[i].position[j] = mutate[i].position[j];
}
else
{
cross[i].position[j] = de.ptcle[i].position[j];
}
// limit of variables of bound
if (cross[i].position[j] > de.x_up_bound)
{
cross[i].position[j] = de.x_up_bound;
}
if (cross[i].position[j] < de.x_low_bound)
{
cross[i].position[j] = de.x_low_bound;
}
}
cross[i].fitness = de.function(cross[i].position);
}
// select
for (int i = 0; i < nPop; i++)
{
if (cross[i].fitness < de.ptcle[i].fitness)
{
de.ptcle[i].fitness = cross[i].fitness;
memcpy(&de.ptcle[i].position, &cross[i].position, sizeof(double)*nVar);
if (de.ptcle[i].fitness<de.global_fitness)
{
de.global_fitness = de.ptcle[i].fitness;
memcpy(&de.global_solution, &de.ptcle[i].position, sizeof(double)*nVar);
}
}
}
// 一次迭代结束
printf("This is %d iteration, globalfitness is %f\n ", it, de.global_fitness);
}
printf("The iteration is end, show the soultion and fitness!\n");
printf("global_fitness :%f\n", de.global_fitness);
for (int i = 0; i < nVar; i++)
{
printf("%f,", de.global_solution[i]);
}
}
void main(void)
{ // Test the running time of the program . including time.h
printf("the program is running!\n");
clock_t pro_start, pro_finished;
pro_start = clock();
runde(0.8, 0.4, -100.0, 100.0, function_fitness);
pro_finished = clock();
double Total_time = (double)(pro_finished - pro_start) / CLOCKS_PER_SEC;
printf("the program ran for : %3f second", Total_time);
system("pause");
}