source: trunk/optimizer/src/pgapack/gekco/pgapack/test/instverf.c @ 815

Last change on this file since 815 was 815, checked in by liveletlive, 17 years ago

Committing the /tmp/gekco/pgapack folder that contains the older PGAPack version and Prof. Klimecks changes to it.

File size: 13.5 KB
Line 
1/*  Example program that shows how to run more than one GA in one
2 *  executable, _AND_ verifies the accuracy of installation.
3 *
4 *  We will run five distinct GA's, each using a different datatype, and,
5 *  thus, a different evaluation function.  The correct output of these GA's
6 *  is in instverf.data, which we read and compare after all GA's are done.
7 *
8 *  The correct solution for #4 and #5 is somewhere around 4.49339389176 for
9 *  the genes, and an evaluation value of around -6.951476096.
10 *
11 *  Author:  Brian P. Walenz
12 */
13#include <pgapack.h>
14
15
16double maxbit(PGAContext *, int, int);
17double ordering(PGAContext *, int, int);
18double name(PGAContext *, int, int);
19double function(PGAContext *, int, int);
20double functionb(PGAContext *, int, int);
21
22/*  The user defined functions.
23 *
24 *  O_* --> for the Ordering problem (integer), problem 2
25 *  N_* --> for the Name problem (character), problem 3
26 *  R_* --> for the real problem, problem 4
27 *  Rb_* -> for the real problem using the binary datatype, problem 5
28 */
29void EOG(PGAContext *);
30int  O_Mutate(PGAContext *, int, int, double);
31void O_Crossover(PGAContext *, int, int, int, int, int, int);
32int  N_Mutate(PGAContext *, int, int, double);
33int  N_StopCond(PGAContext *);
34void R_Init(PGAContext *, int, int);
35void Rb_Init(PGAContext *, int, int);
36void Rb_PrintString(PGAContext *, FILE *, int, int);
37
38char      String[65] =
39          "THEQUICKBROWNFOXJUMPESOVERTHELAZYDOGWHILETHEOLDGOOSELOOKSPUZZLED";
40double    Results[5][1001];
41int       ResultsIndex;
42
43/*  How often to print, and the size (in bits) of each number in a binary
44 *  string (used by problem 5)
45 */
46#define   PRINTFREQ  100
47#define   RBS        24
48
49int main(int argc, char **argv) {
50    PGAContext     *ctx;
51    int             i, rank;
52    FILE           *ResultsFile;
53    double          R[5];
54    int             E[5];
55
56
57    /*  Even though we aren't doing I/O, we MUST initialize MPI ourselves.
58     *  If we don't, the first call to PGADestroy will finalize MPI, and
59     *  the MPI standard does not allow any MPI calls after that (even
60     *  if it is MPI_Init())!
61     */
62    MPI_Init(&argc, &argv);
63    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
64   
65    /*  All examples use a common custom end of generation function to
66     *  stuff the best of generation evaluation into an array.
67     */
68
69
70    /*  Our first example is the ever-popular maxbit.  As usual, it is
71     *  very simple, not even setting PGAPack options!  Plus, we use a
72     *  very odd string length, 999, which is not divisible by 16, 32 or
73     *  64!  What an excellent test!
74     */
75    ResultsIndex = 0;
76    ctx = PGACreate(&argc, argv, PGA_DATATYPE_BINARY, 999, PGA_MAXIMIZE);
77    PGASetRandomSeed(ctx, 42);
78    PGASetPrintFrequencyValue(ctx, PRINTFREQ);
79    PGASetUserFunction(ctx, PGA_USERFUNCTION_ENDOFGEN,  (void *)EOG);
80    PGASetUp(ctx);
81    PGARun(ctx, maxbit);
82    PGADestroy(ctx);
83
84    /*  Second on the menu is a delicious integer ordering function.
85     *  This uses custom mutation and crossover, but permutation
86     *  initialization.  The objective is to order all alleles in the
87     *  integer datatype in an increasing fashion.
88     */
89    ResultsIndex = 1;
90    ctx = PGACreate(&argc, argv, PGA_DATATYPE_INTEGER, 64, PGA_MAXIMIZE);
91    PGASetRandomSeed(ctx, 42);
92    PGASetPrintFrequencyValue(ctx, PRINTFREQ);
93    PGASetUserFunction(ctx, PGA_USERFUNCTION_MUTATION,  (void *)O_Mutate);
94    PGASetUserFunction(ctx, PGA_USERFUNCTION_CROSSOVER, (void *)O_Crossover);
95    PGASetUserFunction(ctx, PGA_USERFUNCTION_ENDOFGEN,  (void *)EOG);
96    PGASetIntegerInitPermute(ctx, 0, 63);
97    PGASetUp(ctx);
98    PGARun(ctx, ordering);
99    PGADestroy(ctx);
100
101
102    /*  Third, and least interesting, is the character maximizer.
103     *  Much like name, it uses custom mutation and stopping conditions.
104     */
105    ResultsIndex = 2;
106    ctx = PGACreate(&argc, argv, PGA_DATATYPE_CHARACTER, 64, PGA_MAXIMIZE);
107    PGASetRandomSeed(ctx, 42);
108    PGASetPrintFrequencyValue(ctx, PRINTFREQ);
109    PGASetUserFunction(ctx, PGA_USERFUNCTION_MUTATION,  (void *)N_Mutate);
110    PGASetUserFunction(ctx, PGA_USERFUNCTION_STOPCOND,  (void *)N_StopCond);
111    PGASetUserFunction(ctx, PGA_USERFUNCTION_ENDOFGEN,  (void *)EOG);
112    PGASetCharacterInitType(ctx, PGA_CINIT_UPPER);
113    PGASetUp(ctx);
114    PGARun(ctx, name);
115    PGADestroy(ctx);
116
117
118    /*  And, finally, the last of the day.  A simple real-valued function
119     *  optimizer.  Uses custom init string.
120     */
121    ResultsIndex = 3;
122    ctx = PGACreate(&argc, argv, PGA_DATATYPE_REAL, 32, PGA_MINIMIZE);
123    PGASetRandomSeed(ctx, 42);
124    PGASetMutationType(ctx, PGA_MUTATION_CONSTANT);
125    PGASetMutationRealValue(ctx, .1);
126    PGASetPrintFrequencyValue(ctx, PRINTFREQ);
127    PGASetMutationProb(ctx, 0.1);
128    PGASetUserFunction(ctx, PGA_USERFUNCTION_INITSTRING,  (void *)R_Init);
129    PGASetUserFunction(ctx, PGA_USERFUNCTION_ENDOFGEN,    (void *)EOG);
130    PGASetUp(ctx);
131    PGARun(ctx, function);
132    PGADestroy(ctx);
133
134
135    /*  Encore, encore!  Fine.  We will now perform the last number
136     *  using the binary datatype and PGAGetRealFromBinary alternating
137     *  with PGAGetRealFromGrayCode.
138     */
139    ResultsIndex = 4;
140    ctx = PGACreate(&argc, argv, PGA_DATATYPE_BINARY, 32*RBS, PGA_MINIMIZE);
141    PGASetRandomSeed(ctx, 42);
142    PGASetPrintFrequencyValue(ctx, PRINTFREQ);
143    PGASetUserFunction(ctx, PGA_USERFUNCTION_INITSTRING,  (void *)Rb_Init);
144    PGASetUserFunction(ctx, PGA_USERFUNCTION_PRINTSTRING, (void *)Rb_PrintString);
145    PGASetUserFunction(ctx, PGA_USERFUNCTION_ENDOFGEN,    (void *)EOG);
146    PGASetUp(ctx);
147    PGARun(ctx, functionb);
148    PGADestroy(ctx);
149
150
151    /*  Compare the Results with the correct values
152     *  stored in "./test/data/Results.data"
153     */
154    if (rank == 0) {
155        ResultsFile = fopen("instverf.data", "r");
156        if (ResultsFile) {
157            E[0] = E[1] = E[2] = E[3] = E[4] = 0;
158           
159            for (i=1; i<1001; i++) {
160#if 0
161                /*  This is used to generate the results file... */
162                printf("%12.6f %12.6f %12.6f %12.6f %12.6f\n",
163                       Results[0][i], Results[1][i], Results[2][i],
164                       Results[3][i], Results[4][i]);
165#endif
166                fscanf(ResultsFile, "%lf %lf %lf %lf %lf",
167                       R, R+1, R+2, R+3, R+4);
168                if (fabs(R[0] - Results[0][i]) > 0.001)   E[0]++;
169                if (fabs(R[1] - Results[1][i]) > 0.001)   E[1]++;
170                if (fabs(R[2] - Results[2][i]) > 0.001)   E[2]++;
171                if (fabs(R[3] - Results[3][i]) > 0.001)   E[3]++;
172                if (fabs(R[4] - Results[4][i]) > 0.001)   E[4]++;
173            }
174            fclose(ResultsFile);
175            for (i=0; i<5; i++) {
176                if (E[i])
177                    printf("Test %d had %d errors.\n", i, E[i]);
178                else
179                    printf("Test %d was successful.\n", i);
180            }
181        } else {
182            fprintf(stderr, "Couldn't open \"instverf.data\".\n");
183        }
184    }
185
186    MPI_Finalize();
187
188    return 0;
189}
190
191
192/******************************************************************************
193 *
194 *  The fitness functions
195 *
196 *****************************************************************************/
197double maxbit(PGAContext *ctx, int p, int pop) {
198    int i, result;
199
200    result = 0;
201    for (i=PGAGetStringLength(ctx)-1; i>=0; i--)
202        if (PGAGetBinaryAllele(ctx, p, pop, i) == 1)
203            result = result + 1;
204
205    return((double)result);
206}
207
208
209/*  Award points if two alleles are increasing (i.e., gene = .., 1, 2, ..)
210 *  and if any allele is in the correct spot (i.e., gene = 1, 2, 3, 4, ...)
211 */
212double ordering(PGAContext *ctx, int p, int pop) {
213    int i, n, o, len, result;
214
215    len = PGAGetStringLength(ctx);
216
217    result = 0;
218    o = PGAGetIntegerAllele(ctx, p, pop, 0);
219    if (o == 0)
220        result = 2;
221    for (i=1; i<len; i++) {
222        n = PGAGetIntegerAllele(ctx, p, pop, i);
223        if (o == n-1)
224            result = result + 1;
225        if (n = i)
226            result = result + 2;
227        o = n;
228    }
229
230    return((double)result);
231}
232
233double name(PGAContext *ctx, int p, int pop) {
234    int  i, result;
235
236    result = 0;
237    for (i=PGAGetStringLength(ctx)-1; i>=0; i--)
238        if (PGAGetCharacterAllele(ctx, p, pop, i) == String[i])
239            result = result + 1;
240
241    return((double)result);
242}
243
244
245double function(PGAContext *ctx, int p, int pop) {
246    int    i;
247    double x, result;
248
249    result = 0;
250    for (i=PGAGetStringLength(ctx)-1; i>=0; i--) {
251        x = PGAGetRealAllele(ctx, p, pop, i);
252        result = result + sin(x) / x;
253    }
254
255    return(result);
256}
257
258
259double functionb(PGAContext *ctx, int p, int pop) {
260    int    i;
261    double x, result;
262
263    result = 0;
264    i = PGAGetStringLength(ctx)/RBS - 1;
265
266    for ( ; i>=0; i--) {
267        if (i % 2) {
268            x = PGAGetRealFromBinary
269                (ctx, p, pop, i*RBS, (i+1)*RBS-1, 0.0, 6.28318530718);
270        } else {
271            x = PGAGetRealFromGrayCode
272                (ctx, p, pop, i*RBS, (i+1)*RBS-1, 0.0, 6.28318530718);
273        }
274        result = result + sin(x) / x;
275    }
276    return(result);
277}
278
279
280
281/**********************************************************************/
282void EOG(PGAContext *ctx) {
283    int     best, iter;
284    double  besteval;
285
286
287   
288    iter = PGAGetGAIterValue(ctx);
289    if(!iter)
290      return;
291    best = PGAGetBestIndex(ctx, PGA_NEWPOP);
292    besteval = PGAGetEvaluation(ctx, best, PGA_NEWPOP);
293
294    Results[ResultsIndex][iter] = besteval;
295}
296
297
298
299/**********************************************************************/
300int O_Mutate(PGAContext *ctx, int p, int pop, double mr) {
301    int i, a, b, len;
302 
303    len = PGAGetStringLength(ctx);
304   
305    a = PGARandomInterval(ctx, 0, len-1);
306    b = PGARandomInterval(ctx, 0, len-1);
307
308    i = PGAGetIntegerAllele(ctx, p, pop, a);
309    PGASetIntegerAllele(ctx, p, pop, a,
310                        PGAGetIntegerAllele(ctx, p, pop, b));
311    PGASetIntegerAllele(ctx, p, pop, b, i);
312    return(1);
313}
314
315/*  Crossover:  Ripped from tsp.c  */
316void O_Crossover(PGAContext *ctx, int A, int B, int ppop,
317                 int C, int D, int cpop) {
318    int     co1, co2, i, len, a, b;
319    int     inA[64], inB[64];
320
321    len = PGAGetStringLength(ctx);
322
323    /*  Select random crossover points from [1, len-1].  */
324    co1 = PGARandomInterval(ctx, 1, len-1);
325    while (co1 == (co2 = PGARandomInterval(ctx, 1, len-1))) ;
326    if (co1 > co2) {
327        i = co1;
328        co1 = co2;
329        co2 = i;
330    }
331
332    /*  Copy a->c and b->d up to the first crossover point. */
333    for (i=0; i<co1; i++) {
334        a = PGAGetIntegerAllele(ctx, A, ppop, i);
335        b = PGAGetIntegerAllele(ctx, B, ppop, i);
336        PGASetIntegerAllele(ctx, C, cpop, i, a);
337        PGASetIntegerAllele(ctx, D, cpop, i, b);
338    }
339   
340    /*  Copy a->c and b->d from the second co point to the end of the
341     *  string.  (Yes, we're ignoring the middle for now.)
342     */
343    for (i=co2; i<len; i++) {
344        a = PGAGetIntegerAllele(ctx, A, ppop, i);
345        b = PGAGetIntegerAllele(ctx, B, ppop, i);
346        PGASetIntegerAllele(ctx, C, cpop, i, a);
347        PGASetIntegerAllele(ctx, D, cpop, i, b);
348    }
349   
350    /*  Now, copy a->d and b->c in the middle (co1 <--> co2).  We must
351     *  be careful to not use any cities twice, thus, we must check
352     *  the rest of the string to see if the allele is used.  If it is,
353     *  change the allele to that of the corresponding one in the other
354     *  string, and check again.  For efficiency, we build a couple of
355     *  tables, AtoB and BtoA.
356     */
357    for (i=0; i<len; i++) {
358        a = PGAGetIntegerAllele(ctx, A, ppop, i);
359        b = PGAGetIntegerAllele(ctx, B, ppop, i);
360        inA[a] = i;
361        inB[b] = i;
362    }
363   
364    for (i=co1; i<co2; i++) {
365        /*  While what we picked is outside the crossover region
366         *  in the other string, keep cross-referencing.
367         */
368        b = PGAGetIntegerAllele(ctx, B, ppop, i);
369        while ((inA[b]<co1) || (inA[b]>=co2))
370            b = PGAGetIntegerAllele(ctx, B, ppop, inA[b]);
371
372        a = PGAGetIntegerAllele(ctx, A, ppop, i);
373        while ((inB[a]<co1) || (inB[a]>=co2))
374            a = PGAGetIntegerAllele(ctx, A, ppop, inB[a]);
375
376        PGASetIntegerAllele(ctx, C, cpop, i, b);
377        PGASetIntegerAllele(ctx, D, cpop, i, a);
378    }
379}
380
381
382
383/**********************************************************************/
384int N_Mutate(PGAContext *ctx, int p, int pop, double mr) {
385    int i, count;
386
387    count = 0;
388    for (i=PGAGetStringLength(ctx)-1; i>=0; i--) {
389        if ((PGAGetCharacterAllele(ctx, p, pop, i) != String[i]) &&
390            (PGARandomFlip(ctx, mr) == PGA_TRUE)) {
391            PGASetCharacterAllele(ctx, p, pop, i, String[i]);
392            count += 1;
393        }
394    }
395    return(count);
396}
397
398int N_StopCond(PGAContext *ctx) {
399    int     done, len;
400    double  e;
401
402    done = 0;
403    len  = PGAGetStringLength(ctx);
404    e    = PGAGetEvaluation(ctx, PGAGetBestIndex(ctx, PGA_OLDPOP), PGA_OLDPOP);
405
406    if (PGACheckStoppingConditions(ctx) || (len == e))
407        done = 1;
408
409    return(done);
410}
411
412
413/**********************************************************************/
414void R_Init(PGAContext *ctx, int p, int pop) {
415    int     i;
416    double  r;
417   
418    for (i=PGAGetStringLength(ctx)-1; i>=0; i--) {
419        r = 6.28318530718 * PGARandom01(ctx, 0) - 3.14159265354;
420        r = 6.28318530718 * exp(r) / (exp(r) + exp(-r));
421
422        PGASetRealAllele(ctx, p, pop, i, r);
423    }
424}
425
426void Rb_Init(PGAContext *ctx, int p, int pop) {
427    int     i;
428    double  r;
429   
430    i = PGAGetStringLength(ctx) / RBS - 1;
431
432    for ( ; i>=0; i--) {
433        r = 6.28318530718 * PGARandom01(ctx, 0) - 3.14159265354;
434        r = 6.28318530718 * exp(r) / (exp(r) + exp(-r));
435
436        if (i % 2) {
437            PGAEncodeRealAsBinary
438                (ctx, p, pop, i*RBS, (i+1)*RBS-1, 0.0, 6.28318530718, r);
439        } else {
440            PGAEncodeRealAsGrayCode
441                (ctx, p, pop, i*RBS, (i+1)*RBS-1, 0.0, 6.28318530718, r);
442        }
443    }
444}
445
446void Rb_PrintString(PGAContext *ctx, FILE *file, int p, int pop) {
447    int     i, j, len;
448    double  r;
449
450    len = PGAGetStringLength(ctx) / RBS - 1;
451
452    for(i=j=0; i<len; i++, j++) {
453        if (i % 2) {
454            r = PGAGetRealFromBinary
455                (ctx, p, pop, i*RBS, (i+1)*RBS-1, 0.0, 6.28318530718);
456        } else {
457            r = PGAGetRealFromGrayCode
458                (ctx, p, pop, i*RBS, (i+1)*RBS-1, 0.0, 6.28318530718);
459        }
460        fprintf(file, "  %10.6f", r);
461        if (j==5) {
462            fprintf(file, "\n");
463            j = -1;
464        }
465    }
466}
467
Note: See TracBrowser for help on using the repository browser.