forked from YuejiaoGong/genetic_learning_PSO
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathglpso.cpp
More file actions
340 lines (287 loc) · 10.4 KB
/
glpso.cpp
File metadata and controls
340 lines (287 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*******************************************************************************/
/* This is a simple implementation of Genetic Learning PSO (GLPSO). */
/* The codes are written in C. */
/* For any questions, please contact Y. Gong (gongyuejiaoATgmail.com). */
/* GLPSO_1.0, Edited on March 6th, 2013. */
/*******************************************************************************/
/* add your header files here */
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
#include<fstream.h>
#include<math.h>
#include<string.h>
#include<time.h>
#include"function.h"
/* Change any of these parameters to match your needs */
#define PARSIZE 50 /* particle population size */
#define FES 300000 /* max. number of function evaluations */
#define MAXGENS 3000 /* max. number of generations */
#define TIMES 30 /* number of runs */
#define dimensions 30 /* max. number of problem variables */
#define NSEL 10 /* tournament size in the selection*/
const double w = 0.7298; /* inertia weight */
const double c1 = 1.49618; /* accelerate coefficient */
const int sg = 7; /* stopping gap of generations */
const double pm = 0.01; /* mutation probability */
double lbound, ubound; /* the lower and upper bounds of variables */
const double RHO=0.2;
double vmax; /* max velocity = RHO * (ubound - lbound) */
struct ParticleType /* a particle in the population */
{
double velocity[dimensions];
double position[dimensions];
double pbest[dimensions];
double pbestval;
int stop;
};
ParticleType particle[PARSIZE];
struct ExemplarType /* the exemplar of a particle */
{
double x[dimensions];
double f;
int stop;
};
ExemplarType exemplar[PARSIZE];
ExemplarType newexemplar[PARSIZE];
/* control parameters used by the program */
int generation;
int fes;
int bestpar;
double gbestval;
double foundbest;
#define betterthan <
#define worsethan >
#define worstvalue 1e300
/* declaration of functions used by this algorithm */
double (*function_name)(double pos[],int dim);
double randval(double low,double high);
double calfit(double pos[],int dim);
void exemplar_crossover(int num);
void exemplar_mutation(int num);
void exemplar_selection(int num);
void exemplar_tour_selection(int num);
void exemplar_update(int num);
void Initialize();
void Evaluate(int num);
void Update();
void Process();
/***********************************************************/
/* Random value generator: generates a value within bounds */
/***********************************************************/
double randval(double low,double high)
{
return (double(rand())/RAND_MAX)*(high-low)+low;
}
/***********************************************************/
/* Fitness calculation: calculating the fitness of an */
/* individual/position and fes ++. */
/* this takes a user defined function. */
/* "function_name" indicates the object function you are */
/* testing, which should be initialized before used. */
/***********************************************************/
double calfit(double pos[],int dim)
{
fes++;
return function_name(pos,dim);
}
/***********************************************************/
/* Exemplar crossover: each dimension of the new exemplar */
/* is bred by either the uniform crossover of the pbest */
/* and gbest or randomly copying another particle's pbest. */
/***********************************************************/
void exemplar_crossover(int num)
{
double r;
int i, n;
for(i = 0; i < dimensions; i ++){
n = rand()%PARSIZE;
if(particle[n].pbestval betterthan particle[num].pbestval || num == bestpar){ /* random copy */
newexemplar[num].x[i] = particle[n].pbest[i];
}
else { /* uniform crossover */
r = randval(0,1);
newexemplar[num].x[i] = r*particle[num].pbest[i]+(1-r)*particle[bestpar].pbest[i];
}
}
}
/***********************************************************/
/* Exemplar mutation: reinitialize a dimension with a */
/* mutation probability pm */
/***********************************************************/
void exemplar_mutation(int num)
{
for(int i = 0; i < dimensions; i ++){
if(randval(0,1) < pm){
newexemplar[num].x[i] = randval(lbound,ubound);
}
}
}
/***********************************************************/
/* Exemplar selection: new exemplar replaces the old */
/* one if it has a better fitness value. */
/***********************************************************/
void exemplar_selection(int num)
{
newexemplar[num].f = calfit(newexemplar[num].x,dimensions);
if(newexemplar[num].f betterthan exemplar[num].f){
exemplar[num] = newexemplar[num];
exemplar[num].stop = 0;
if(exemplar[num].f betterthan foundbest)
foundbest=exemplar[num].f;
}
else
exemplar[num].stop++;
}
/***********************************************************/
/* Exemplar tournament Selection: when the exemplar of a */
/* particle is trapped, employ the 20%M-tournament */
/* selection to update the particle's exemplar. */
/***********************************************************/
void exemplar_tour_selection(int num)
{
int j;
int child[NSEL], temp;
double good;
for(j=0; j<NSEL; j++){
child[j]=rand()%PARSIZE;
}
good=exemplar[child[0]].f;
temp=child[0];
for(j=1; j<NSEL; j++){
if(exemplar[child[j]].f betterthan good){
good=exemplar[child[j]].f;
temp=child[j];
}
}
exemplar[num]=exemplar[temp];
}
/*************************************************************/
/* Exemplar update: this function contains the overall */
/* for update the exemplar of a particle. */
/*************************************************************/
void exemplar_update(int num)
{
exemplar_crossover(num);
exemplar_mutation(num);
exemplar_selection(num);
if(exemplar[num].stop > sg){
exemplar[num].stop = 0;
exemplar_tour_selection(num);
}
}
/***************************************************************/
/* Initialization function: initializes the particles, pbests, */
/* gbest, and exempalrs */
/***************************************************************/
void Initialize()
{
int i,j;
fes=0;
generation=0;
vmax=RHO*(ubound-lbound);
/* initialize particles */
for(i = 0; i < PARSIZE; i ++){
for(j = 0; j < dimensions; j ++){
particle[i].position[j] = randval(lbound, ubound);
particle[i].velocity[j] = randval(lbound-particle[i].position[j], ubound-particle[i].position[j]);
particle[i].pbest[j] = particle[i].position[j];
}
particle[i].pbestval = calfit(particle[i].position,dimensions);
}
/* find the gbest */
gbestval = particle[0].pbestval;
bestpar = 0;
for(i = 1; i < PARSIZE; i ++){
if(particle[i].pbestval betterthan gbestval){
gbestval = particle[i].pbestval;
bestpar = i;
}
}
foundbest = gbestval;
/* initialize exemplars */
for(i = 0; i <PARSIZE; i ++) exemplar[i].f = worstvalue;
for(i = 0; i < PARSIZE; i ++) exemplar_update(i);
}
/***************************************************************/
/* Evaluation function: evaluate the fitness of particle i */
/* and update the pbest and gbest if a better fitness value */
/* is found. Otherwise, the stopping generations ++. */
/***************************************************************/
void Evaluate(int num)
{
int j;
double tmp;
tmp=calfit(particle[num].position,dimensions);
if(tmp betterthan particle[num].pbestval){
particle[num].stop=0;
for(j=0;j<dimensions;j++)
particle[num].pbest[j]=particle[num].position[j];
particle[num].pbestval=tmp;
if(tmp betterthan particle[bestpar].pbestval){
bestpar=num;
if(tmp betterthan foundbest)
foundbest=tmp;
}
}
else
particle[num].stop++;
}
/***************************************************************/
/* Update function: for each particle, it first updates its */
/* exemplar, then learns from the exemplar to update position */
/* and velocity. Note that the velocity and position should be */
/* restricted in the specified range. */
/***************************************************************/
void Update()
{
int i, j;
double rnd;
for(i = 0; i < PARSIZE; i ++){
if(fes >= FES) break;
exemplar_update(i);
for(j = 0; j < dimensions; j ++){
rnd = randval(0,1);
particle[i].velocity[j] = w * particle[i].velocity[j] + c1 * rnd * (exemplar[i].x[j] - particle[i].position[j]);
if(particle[i].velocity[j] < -vmax) particle[i].velocity[j] = -vmax;
else if(particle[i].velocity[j] > vmax) particle[i].velocity[j] = vmax;
particle[i].position[j] += particle[i].velocity[j];
if(particle[i].position[j] < lbound){
particle[i].position[j] = lbound;
particle[i].velocity[j] *= -0.5;
}
else if(particle[i].position[j] > ubound){
particle[i].position[j] = ubound;
particle[i].velocity[j] *= -0.5;
}
}
Evaluate(i);
}
}
/*************************************************************/
/* Process: this function contains the overall procedure for */
/* running the genetic learning PSO. */
/*************************************************************/
void Process()
{
Initialize();
while(generation<MAXGENS && fes<FES){
Update();
generation++;
}
}
/*************************************************************/
/* The main function */
/*************************************************************/
void main()
{
int i;
function_name = ff8; /* set the objective function here */
lbound = -500; ubound = 500; /* set the variable range */
for(i = 0; i < TIMES; i++){
Process(); /* run the GLPSO algorithm */
/* you can output results using foundbest here, e.g., */
printf("%g\n", foundbest);
}
printf("Successful!\n");
}