-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfpa.cpp
136 lines (115 loc) · 3.59 KB
/
fpa.cpp
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
#include "fpa.h"
/* Application of simple constraints */
/* s : target to be constrained */
/* lb : lower bound constraint */
/* ub : upper bound constraint */
void simplebounds(double *s, double lb[], double ub[]){
for(int i=0; i<d; ++i){
/* Apply the lower bound */
if(s[i]<lb[i]) s[i] = lb[i];
/* Apply the upper bounds */
if(s[i]>ub[i]) s[i] = ub[i];
// cout << s[i] << " ";
}
// cout << endl;
}
/* Flower pollination algorithm */
/* n : size of flowers population */
/* max_iter : maximum iteration */
/* p : switch probability */
result fpa(int n, int max_iter, double p){
int i, j;
double ub[d], lb[d], sol[n][d], s[n][d], fitness[n];
for(i=0; i<d; ++i){
lb[i] = lb_val;
ub[i] = ub_val;
}
/* Initialize the population (solutions) */
for(i=0; i<n; ++i){
for(j=0; j<d; ++j) s[i][j] = sol[i][j] = lb[j] + (ub[j] - lb[j]) * uniform();
fitness[i] = func(sol[i]);
}
/* Find the current best */
j = 0;
for(i=1; i<n; ++i) if(fitness[i] < fitness[j]) j = i;
double fmin = fitness[j];
double best[d];
for(i=0; i<d; ++i) best[i] = sol[j][i];
// for(i=0; i<n; ++i){
// cout << "Solution " << i+1 << " -> " << fitness[i] << " | ";
// for(j=0; j<d; ++j) cout << sol[i][j] << " ";
// cout << endl;
// }
// for(i=0; i<d; ++i) cout << best[i] << " ";
// cout << endl;
/* Main algorithm */
bool stop = false;
int tot_eval, i_rand, j_rand, iter = 0;
double epsilon, fnew, *l;
while((iter < max_iter) && !stop){
// cout << "Iteration " << iter+1 << endl;
/* Loop over all flower (solutions) */
for(i=0; (i<n) && !stop; ++i){
/* Pollens are carried by insects and thus can move in large scale, large distance. */
/* Formula: x[t+1][i] = x[t][i] + l*(best-x[t][i]) */
if(uniform()<p){
l = levy(d);
// for(j=0; j<d; ++j) cout << l[j] << " ";
// cout << endl;
for(j=0; j<d; ++j)
s[i][j] = sol[i][j] + l[j] * (best[j] - sol[i][j]);
// for(j=0; j<d; ++j) cout << s[i][j] << " ";
// cout << endl;
free(l);
}
/* If not, then local pollination of neighbor flowers */
/* Formula: x[t+1][i] + epsilon*(x[t][irand]-x[t][jrand]) */
else{
/* Find random flowers in the neighbourhood */
do{ i_rand = uniform_int(0,n-1); } while(i_rand==i);
do{ j_rand = uniform_int(0,n-1); } while((j_rand==i) || (j_rand==i_rand));
epsilon = uniform();
for(j=0; j<d; ++j) s[i][j] += epsilon * (sol[i_rand][j] - sol[j_rand][j]);
}
simplebounds(s[i], lb, ub); /* Check if the simple limits/bounds are OK */
fnew = func(s[i]); /* Evaluate new solutions */
/* If fitness improves (better solutions found), update then */
if (fnew<fitness[i]){
fitness[i] = fnew;
for(j=0; j<d; ++j) sol[i][j] = s[i][j];
}
/* Update the current global best */
if (fnew<fmin){
fmin = fnew;
for(j=0; j<d; ++j) best[j] = s[i][j];
}
/* Stop function */
/* Check if the the difference of fnew and solution less than eps */
if((abs(fmin-target_val)<eps)){
stop = true;
tot_eval = iter*n+i+1;
}
// cout << "Solution " << i+1 << " -> " << fitness[i] << " | ";
// for(j=0; j<d; ++j) cout << s[j] << " ";
// cout << endl;
}
++iter;
}
if(!stop) tot_eval = max_iter*n;
// cout << "Fmin : " << fmin << endl;
// cout << "Nilai terbaik : ";
// for(int i=0; i<d; ++i) cout << best[i]) << " ";
// cout << endl;
/* Return the result */
result res;
res.fmin = fmin;
res.best = new double[d];
for (int i=0; i<d; ++i) res.best[i] = best[i];
res.tot_eval = tot_eval;
return res;
}
/* Flower pollination algorithm */
/* Default parameter */
result fpa(){
return fpa(20, 2000, 0.8);
}