1 /**********************************************************************
2 test_de.c
3 **********************************************************************
4
5 test_de - Test program for GAUL.
6 Copyright ©2002-2005, Stewart Adcock <stewart@linux-domain.com>
7 All rights reserved.
8
9 The latest version of this program should be available at:
10 http://gaul.sourceforge.net/
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version. Alternatively, if your project
16 is incompatible with the GPL, I will probably agree to requests
17 for permission to use the terms of any other license.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY WHATSOEVER.
21
22 A full copy of the GNU General Public License should be in the file
23 "COPYING" provided with this distribution; if not, see:
24 http://www.gnu.org/
25
26 **********************************************************************
27
28 Synopsis: Test program for GAUL's differential evolution algorithm.
29
30 This program aims to solve a function of the form
31 (0.75-A)+(0.95-B)^2+(0.23-C)^3+(0.71-D)^4 = 0
32
33 **********************************************************************/
34
35 #include "gaul.h"
36
37 struct strategies_t
38 {
39 char *label;
40 ga_de_strategy_type strategy;
41 ga_de_crossover_type crossover;
42 int num_perturbed;
43 double crossover_factor;
44 double weighting_factor;
45 double weighting_factor2;
46 };
47
48 static struct strategies_t strategy[]={
49 { "DE/best/1/exp (DE0)", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_EXPONENTIAL, 1, 0.8, 0.5, 0.5 },
50 { "DE/best/1/exp (DE0)", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_EXPONENTIAL, 1, 0.8, 2.0, 0.0 },
51 { "DE/best/2/exp", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_EXPONENTIAL, 2, 0.8, 0.5, 0.5 },
52 { "DE/best/2/exp", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_EXPONENTIAL, 2, 0.8, 2.0, 0.0 },
53 { "'DE/best/3/exp'", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_EXPONENTIAL, 3, 0.8, 0.5, 0.5 },
54 { "'DE/best/3/exp'", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_EXPONENTIAL, 3, 0.8, 2.0, 0.0 },
55 { "DE/rand/1/exp (DE1)", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_EXPONENTIAL, 1, 0.8, 0.5, 0.5 },
56 { "DE/rand/1/exp (DE1)", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_EXPONENTIAL, 1, 0.8, 2.0, 0.0 },
57 { "DE/rand/2/exp", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_EXPONENTIAL, 2, 0.8, 0.5, 0.5 },
58 { "DE/rand/2/exp", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_EXPONENTIAL, 2, 0.8, 2.0, 0.0 },
59 { "'DE/rand/3/exp'", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_EXPONENTIAL, 3, 0.8, 0.5, 0.5 },
60 { "'DE/rand/3/exp'", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_EXPONENTIAL, 3, 0.8, 2.0, 0.0 },
61 { "DE/rand-to-best/1/exp", GA_DE_STRATEGY_RANDTOBEST, GA_DE_CROSSOVER_EXPONENTIAL, 1, 0.8, 0.5, 0.5 },
62 { "DE/rand-to-best/1/exp", GA_DE_STRATEGY_RANDTOBEST, GA_DE_CROSSOVER_EXPONENTIAL, 1, 0.8, 2.0, 0.0 },
63 { "'DE/rand-to-best/2/exp'", GA_DE_STRATEGY_RANDTOBEST, GA_DE_CROSSOVER_EXPONENTIAL, 2, 0.8, 0.5, 0.5 },
64 { "'DE/rand-to-best/2/exp'", GA_DE_STRATEGY_RANDTOBEST, GA_DE_CROSSOVER_EXPONENTIAL, 2, 0.8, 2.0, 0.0 },
65 { "DE/best/1/bin", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_BINOMIAL, 1, 0.8, 0.5, 0.5 },
66 { "DE/best/1/bin", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_BINOMIAL, 1, 0.8, 2.0, 0.0 },
67 { "DE/best/2/bin", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_BINOMIAL, 2, 0.8, 0.5, 0.5 },
68 { "DE/best/2/bin", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_BINOMIAL, 2, 0.8, 2.0, 0.0 },
69 { "'DE/best/3/bin'", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_BINOMIAL, 3, 0.8, 0.5, 0.5 },
70 { "'DE/best/3/bin'", GA_DE_STRATEGY_BEST, GA_DE_CROSSOVER_BINOMIAL, 3, 0.8, 2.0, 0.0 },
71 { "DE/rand/1/bin", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_BINOMIAL, 1, 0.8, 0.5, 0.5 },
72 { "DE/rand/1/bin", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_BINOMIAL, 1, 0.8, 2.0, 0.0 },
73 { "DE/rand/2/bin", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_BINOMIAL, 2, 0.8, 0.5, 0.5 },
74 { "DE/rand/2/bin", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_BINOMIAL, 2, 0.8, 2.0, 0.0 },
75 { "'DE/rand/3/bin'", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_BINOMIAL, 3, 0.8, 0.5, 0.5 },
76 { "'DE/rand/3/bin'", GA_DE_STRATEGY_RAND, GA_DE_CROSSOVER_BINOMIAL, 3, 0.8, 2.0, 0.0 },
77 { "DE/rand-to-best/1/bin", GA_DE_STRATEGY_RANDTOBEST, GA_DE_CROSSOVER_BINOMIAL, 1, 0.8, 0.5, 0.5 },
78 { "DE/rand-to-best/1/bin", GA_DE_STRATEGY_RANDTOBEST, GA_DE_CROSSOVER_BINOMIAL, 1, 0.8, 2.0, 0.0 },
79 { "'DE/rand-to-best/2/bin'", GA_DE_STRATEGY_RANDTOBEST, GA_DE_CROSSOVER_BINOMIAL, 2, 0.8, 0.5, 0.5 },
80 { "'DE/rand-to-best/2/bin'", GA_DE_STRATEGY_RANDTOBEST, GA_DE_CROSSOVER_BINOMIAL, 2, 0.8, 2.0, 0.0 },
81 { NULL, 0, 0, 0, 0.0, 0.0 } };
82
83
84 /**********************************************************************
85 test_score()
86 synopsis: Fitness function.
87 parameters:
88 return:
89 updated: 25 Nov 2002
90 **********************************************************************/
91
test_score(population * pop,entity * entity)92 boolean test_score(population *pop, entity *entity)
93 {
94 double A, B, C, D; /* Parameters. */
95
96 A = ((double *)entity->chromosome[0])[0];
97 B = ((double *)entity->chromosome[0])[1];
98 C = ((double *)entity->chromosome[0])[2];
99 D = ((double *)entity->chromosome[0])[3];
100
101 entity->fitness = -(fabs(0.75-A)+SQU(0.95-B)+fabs(CUBE(0.23-C))+FOURTH_POW(0.71-D));
102
103 return TRUE;
104 }
105
106
107 /**********************************************************************
108 test_generation_callback()
109 synopsis: Generation callback
110 parameters:
111 return:
112 updated: 21 Mar 2005
113 **********************************************************************/
114
test_generation_callback(int generation,population * pop)115 boolean test_generation_callback(int generation, population *pop)
116 {
117
118 /*
119 * This is a easy method for implementing randomly selected
120 * scaling factor (F in original paper) for each generation, as
121 * suggested in:
122 *
123 * Karaboga D., Okdem, S. "A simple and global optimization algorithm
124 * for engineering problems: differential evolution algorithm",
125 * Elec. Engin. 12:53-60 (2004).
126 *
127 * Uncomment, if desired.
128 */
129 /*
130 pop->de_params->weighting_factor = random_double_range(-2.0, 2.0);
131 */
132
133 /*
134 * Write rank 1 solution every tenth generation. Note, that this is
135 * not neccesarily the best solution because DE doesn't require the
136 * population to be sorted, as genetic algorithms usually do.
137 */
138 if ( generation%10 == 0)
139 printf( "%d: A = %f B = %f C = %f D = %f (fitness = %f)\n",
140 generation,
141 ((double *)pop->entity_iarray[0]->chromosome[0])[0],
142 ((double *)pop->entity_iarray[0]->chromosome[0])[1],
143 ((double *)pop->entity_iarray[0]->chromosome[0])[2],
144 ((double *)pop->entity_iarray[0]->chromosome[0])[3],
145 pop->entity_iarray[0]->fitness );
146
147 return TRUE;
148 }
149
150
151 /**********************************************************************
152 test_seed()
153 synopsis: Seed genetic data.
154 parameters: population *pop
155 entity *adam
156 return: success
157 last updated: 25 Nov 2002
158 **********************************************************************/
159
test_seed(population * pop,entity * adam)160 boolean test_seed(population *pop, entity *adam)
161 {
162
163 /* Checks. */
164 if (!pop) die("Null pointer to population structure passed.");
165 if (!adam) die("Null pointer to entity structure passed.");
166
167 /* Seeding. */
168 ((double *)adam->chromosome[0])[0] = random_double(2.0);
169 ((double *)adam->chromosome[0])[1] = random_double(2.0);
170 ((double *)adam->chromosome[0])[2] = random_double(2.0);
171 ((double *)adam->chromosome[0])[3] = random_double(2.0);
172
173 return TRUE;
174 }
175
176
177 /**********************************************************************
178 main()
179 synopsis: Main function.
180 parameters:
181 return:
182 updated: 21 Mar 2005
183 **********************************************************************/
184
main(int argc,char ** argv)185 int main(int argc, char **argv)
186 {
187 population *pop; /* Population of solutions. */
188 int i=0; /* Loop variable over strategies. */
189
190 random_seed(23091975);
191
192 log_init(LOG_NORMAL, NULL, NULL, FALSE);
193
194 while ( strategy[i].label != NULL )
195 {
196 if ( strategy[i].weighting_factor != strategy[i].weighting_factor2 )
197 {
198 printf( "Strategy %s ; C = %f ; F = rand( %f, %f )\n",
199 strategy[i].label,
200 strategy[i].crossover_factor,
201 strategy[i].weighting_factor, strategy[i].weighting_factor2 );
202 }
203 else
204 {
205 printf( "Strategy %s ; C = %f ; F = %f\n",
206 strategy[i].label,
207 strategy[i].crossover_factor,
208 strategy[i].weighting_factor );
209 }
210
211 pop = ga_genesis_double(
212 40, /* const int population_size */
213 1, /* const int num_chromo */
214 4, /* const int len_chromo */
215 test_generation_callback,/* GAgeneration_hook generation_hook */
216 NULL, /* GAiteration_hook iteration_hook */
217 NULL, /* GAdata_destructor data_destructor */
218 NULL, /* GAdata_ref_incrementor data_ref_incrementor */
219 test_score, /* GAevaluate evaluate */
220 test_seed, /* GAseed seed */
221 NULL, /* GAadapt adapt */
222 NULL, /* GAselect_one select_one */
223 NULL, /* GAselect_two select_two */
224 NULL, /* GAmutate mutate */
225 NULL, /* GAcrossover crossover */
226 NULL, /* GAreplace replace */
227 NULL /* vpointer User data */
228 );
229
230 ga_population_set_differentialevolution_parameters(
231 pop, strategy[i].strategy, strategy[i].crossover,
232 strategy[i].num_perturbed, strategy[i].weighting_factor, strategy[i].weighting_factor2,
233 strategy[i].crossover_factor
234 );
235
236 ga_differentialevolution(
237 pop, /* population *pop */
238 50 /* const int max_generations */
239 );
240
241 printf( "Final: A = %f B = %f C = %f D = %f (fitness = %f)\n",
242 ((double *)pop->entity_iarray[0]->chromosome[0])[0],
243 ((double *)pop->entity_iarray[0]->chromosome[0])[1],
244 ((double *)pop->entity_iarray[0]->chromosome[0])[2],
245 ((double *)pop->entity_iarray[0]->chromosome[0])[3],
246 pop->entity_iarray[0]->fitness );
247
248 ga_extinction(pop);
249
250 i++;
251 }
252
253 exit(EXIT_SUCCESS);
254 }
255
256
257