source: trunk/packages/optimizer/src/pgapack/gekco/pgapack/source/utility.c @ 1018

Last change on this file since 1018 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: 17.8 KB
Line 
1/*
2 * 
3 *  *********************************************************************
4 *  (C) COPYRIGHT 1995 UNIVERSITY OF CHICAGO
5 *  *********************************************************************
6 * 
7 *  This software was authored by
8 * 
9 *  D. Levine
10 *  Mathematics and Computer Science Division Argonne National Laboratory
11 *  Argonne IL 60439
12 *  levine@mcs.anl.gov
13 *  (708) 252-6735
14 *  (708) 252-5986 (FAX)
15 * 
16 *  with programming assistance of participants in Argonne National
17 *  Laboratory's SERS program.
18 * 
19 *  This program contains material protectable under copyright laws of the
20 *  United States.  Permission is hereby granted to use it, reproduce it,
21 *  to translate it into another language, and to redistribute it to
22 *  others at no charge except a fee for transferring a copy, provided
23 *  that you conspicuously and appropriately publish on each copy the
24 *  University of Chicago's copyright notice, and the disclaimer of
25 *  warranty and Government license included below.  Further, permission
26 *  is hereby granted, subject to the same provisions, to modify a copy or
27 *  copies or any portion of it, and to distribute to others at no charge
28 *  materials containing or derived from the material.
29 * 
30 *  The developers of the software ask that you acknowledge its use in any
31 *  document referencing work based on the  program, such as published
32 *  research.  Also, they ask that you supply to Argonne National
33 *  Laboratory a copy of any published research referencing work based on
34 *  the software.
35 * 
36 *  Any entity desiring permission for further use must contact:
37 * 
38 *  J. Gleeson
39 *  Industrial Technology Development Center Argonne National Laboratory
40 *  Argonne IL 60439
41 *  gleesonj@smtplink.eid.anl.gov
42 *  (708) 252-6055
43 * 
44 *  ********************************************************************
45 *  DISCLAIMER
46 * 
47 *  THIS PROGRAM WAS PREPARED AS AN ACCOUNT OF WORK SPONSORED BY AN AGENCY
48 *  OF THE UNITED STATES GOVERNMENT.  NEITHER THE UNIVERSITY OF CHICAGO,
49 *  THE UNITED STATES GOVERNMENT NOR ANY OF THEIR EMPLOYEES MAKE ANY
50 *  WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL LIABILITY OR
51 *  RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF ANY
52 *  INFORMATION OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT
53 *  INFRINGE PRIVATELY OWNED RIGHTS.
54 * 
55 *  **********************************************************************
56 *  GOVERNMENT LICENSE
57 * 
58 *  The Government is granted for itself and others acting on its behalf a
59 *  paid-up, non-exclusive, irrevocable worldwide license in this computer
60 *  software to reproduce, prepare derivative works, and perform publicly
61 *  and display publicly.
62 */
63
64/*****************************************************************************
65*     FILE: utility.c: This file contains routines that perform utility
66*                      functions.
67*
68*     Authors: David M. Levine, Philip L. Hallstrom, David M. Noelle,
69*              Brian P. Walenz
70*****************************************************************************/
71
72#include <pgapack.h>
73
74/*U****************************************************************************
75  PGAMean - calculates the mean value of an array of elements
76
77  Category: Utility
78
79  Inputs:
80    ctx  - context variable
81    a    - array to take the mean of
82    n    - number of elements in array a
83
84  Outputs:
85    The mean of the n elements in array a
86
87  Example:
88    PGAContext *ctx;
89    double a[100], mean;
90    :
91    mean = PGAMean(ctx, a, 100);
92
93****************************************************************************U*/
94double PGAMean ( PGAContext *ctx, double *a, int n)
95{
96    int i;
97    double result;
98
99    PGADebugEntered("PGAMean");
100
101    result = 0.;
102    for( i=n-1; i>=0; i-- )
103        result += a[i];
104
105    PGADebugExited("PGAMean");
106
107    return (result / (double) n );
108}
109
110
111/*U****************************************************************************
112  PGAStddev - calculates the standard deviation of an array of elements
113
114  Category: Utility
115
116  Inputs:
117    ctx  - context variable
118    a    - array to take the standard deviation of
119    n    - number of elements in array a
120    mean - the mean of the elements in array a
121
122  Outputs:
123    The standard deviation of the n elements in array a
124
125  Example:
126    PGAContext *ctx;
127    double a[100], mean, sigma;
128    :
129    mean  = PGAMean(ctx, a, 100);
130    sigma = PGAStddev(ctx, a, 100, mean);
131
132****************************************************************************U*/
133double PGAStddev ( PGAContext *ctx, double *a, int n, double mean)
134{
135    int i;
136    double result;
137
138    PGADebugEntered("PGAStddev");
139
140    result = 0;
141    for(i=n-1; i>=0; i--)
142        result += (a[i] - mean) * (a[i] - mean);
143    result  = sqrt(result/n);
144
145    PGADebugExited("PGAStddev");
146    return (result);
147}
148
149/*U****************************************************************************
150  PGARound - Mathematically round a double to an integer, using 0.5 as the
151  cutoff value.
152
153  Category: Utility
154
155  Inputs:
156     ctx - context variable
157     x - the number to be rounded
158
159  Outputs:
160     The rounded number.
161
162  Example:
163     PGAContext *ctx;
164     int y;
165     y = PGARound(ctx, -78.6);
166
167****************************************************************************U*/
168int PGARound(PGAContext *ctx, double x)
169{
170    double ipart, frac;
171
172    PGADebugEntered("PGARound");
173
174    frac = modf(x, &ipart);
175    if (frac <= -0.5)
176      ipart--;
177    else if (frac >= 0.5)
178      ipart++;
179
180    PGADebugExited("PGARound");
181
182    return ((int)ipart);
183}
184
185/*U****************************************************************************
186  PGACopyIndividual - copies string p1 in population pop1 to position p2 in
187  population pop2
188
189  Category: Generation
190
191  Inputs:
192     ctx  - context variable
193     p1   - string to copy
194     pop1 - symbolic constant of population containing string p1
195     p2   - string to copy p1 to
196     pop2 - symbolic constant of population containing string p2
197
198  Outputs:
199     String p2 is an exact copy of string p1.
200
201  Example:
202    PGAContext *ctx;
203    int i,j;
204    :
205    PGACopyIndividual(ctx, i, PGA_OLDPOP, j, PGA_NEWPOP);
206
207****************************************************************************U*/
208void PGACopyIndividual( PGAContext *ctx, int p1, int pop1, int p2, int pop2)
209{
210    PGAIndividual *source, *dest;
211
212    PGADebugEntered("PGACopyIndividual");
213
214    source = PGAGetIndividual ( ctx, p1, pop1 );
215    dest   = PGAGetIndividual ( ctx, p2, pop2 );
216
217    dest->evalfunc     = source->evalfunc;
218    dest->fitness      = source->fitness;
219    dest->evaluptodate = source->evaluptodate;
220
221    (*ctx->cops.CopyString)(ctx, p1, pop1, p2, pop2);
222
223    PGADebugExited("PGACopyIndividual");
224}
225
226/*U****************************************************************************
227  PGACheckSum - maps a string to a number to be used a verification check
228  PGA_DATATYPE_USER is not supported.
229
230  Category: Utility
231
232  Inputs:
233     ctx    - context variable
234     p      - string index
235     pop    - symbolic constant for the population
236
237  Outputs:
238     An integer representing the "value" of the string.
239
240  Example:
241     PGAContext *ctx;
242     int p, sum;
243     :
244     sum = PGACheckSum(ctx, p, PGA_NEWPOP);
245
246****************************************************************************U*/
247int PGACheckSum(PGAContext *ctx, int p, int pop)
248{
249    long stringlen, totalchars, charbits, i, j, checksum, totalbytes, out_bit;
250    unsigned char *message, specimen;
251
252    PGADebugEntered("PGACheckSum");
253
254    stringlen = PGAGetStringLength(ctx);
255    switch (ctx->ga.datatype) {
256      case PGA_DATATYPE_BINARY:
257        totalbytes = ctx->ga.tw * sizeof(PGABinary);
258        break;
259      case PGA_DATATYPE_INTEGER:
260        totalbytes = stringlen * sizeof(PGAInteger);
261        break;
262      case PGA_DATATYPE_REAL:
263        totalbytes = stringlen * sizeof(PGAReal);
264        break;
265      case PGA_DATATYPE_CHARACTER:
266        totalbytes = stringlen * sizeof(PGACharacter);
267        break;
268      default:
269        totalbytes = 0;
270        PGAError(ctx, "PGACheckSum: User datatype checksum may be invalid.",
271                 PGA_WARNING, PGA_VOID, NULL);
272        break;
273      }
274
275    message = (unsigned char *)PGAGetIndividual(ctx, p, pop)->chrom;
276    totalchars = totalbytes / sizeof(unsigned char);
277    charbits = sizeof(unsigned char) * 8;
278    checksum = 0;
279    for (i = 0; i < totalchars; i++) {
280      specimen = *(message + i);
281      for (j = 0; j < charbits; j++) {
282        out_bit = (checksum & 0x80000000) == 1;
283        checksum = (checksum << 1) + ((specimen & 0x80) == 0x80);
284        if (out_bit)
285          checksum ^= 0x04c11db7;
286        specimen <<= 1;
287      }
288    }
289
290    PGADebugExited("PGACheckSum");
291
292    return (checksum);
293}
294
295/*U***************************************************************************
296  PGAGetWorstIndex - returns the index of the string with the worst
297  evaluation function value in population pop
298
299  Category: Utility
300
301  Inputs:
302     ctx - context variable
303     pop - symbolic constant of the population to find the worst string in
304
305  Outputs:
306     Index of the string with the worst evaluation function value
307
308  Example:
309     PGAContext *ctx;
310     int worst;
311     :
312     worst = PGAGetWorstIndex(ctx,PGA_OLDPOP);
313
314***************************************************************************U*/
315int PGAGetWorstIndex(PGAContext *ctx, int pop)
316{
317    int     p, worst_indx = 0;
318    double  eval, worst_eval;
319
320    PGADebugEntered("PGAGetWorstIndex");
321
322    for (p = 0; p < ctx->ga.PopSize; p++)
323        if (!PGAGetEvaluationUpToDateFlag(ctx, p, pop))
324            PGAError(ctx, "PGAGetWorstIndex: Evaluate function not up to "
325                     "date:", PGA_FATAL, PGA_INT, (void *) &p);
326
327    worst_eval = PGAGetEvaluation(ctx, 0, pop);
328    switch (PGAGetOptDirFlag(ctx)) {
329    case PGA_MAXIMIZE:
330        for (p = 1; p < ctx->ga.PopSize; p++) {
331            eval = PGAGetEvaluation(ctx, p, pop);
332            if (eval < worst_eval) {
333                worst_indx = p;
334                worst_eval = eval;
335            }
336        }
337        break;
338
339    case PGA_MINIMIZE:
340        for (p = 1; p < ctx->ga.PopSize; p++) {
341            eval = PGAGetEvaluation(ctx, p, pop);
342            if (eval > worst_eval) {
343                worst_indx = p;
344                worst_eval = eval;
345            }
346        }
347        break;   
348    }
349
350    PGADebugExited("PGAGetWorstIndex");
351
352    return (worst_indx);
353}
354
355/*U***************************************************************************
356  PGAGetBestIndex - returns the index of the string with the best evaluation
357  function value in population pop
358
359  Category: Utility
360
361  Inputs:
362     ctx - context variable
363     pop - symbolic constant of the population to find the best string in
364
365  Outputs:
366     Index of the string with the best evaluation function value
367
368  Example:
369     PGAContext *ctx;
370     int best;
371     :
372     best = PGAGetBestIndex(ctx,PGA_OLDPOP);
373
374***************************************************************************U*/
375int PGAGetBestIndex(PGAContext *ctx, int pop)
376{
377     int     p, Best_indx = 0;
378     double  eval, Best_eval;
379
380    PGADebugEntered("PGAGetBestIndex");
381     
382     for (p = 0; p < ctx->ga.PopSize; p++)
383         if (!PGAGetEvaluationUpToDateFlag(ctx, p, pop))
384             PGAError(ctx, "PGAGetBestIndex: Evaluate function not up to "
385                      "date:", PGA_FATAL, PGA_INT, (void *) &p);
386     
387     Best_eval = PGAGetEvaluation(ctx, 0, pop);
388
389     switch (PGAGetOptDirFlag(ctx)) {
390     case PGA_MAXIMIZE :
391         for (p = 1; p < ctx->ga.PopSize; p++) {
392             eval = PGAGetEvaluation(ctx, p, pop);
393             if (eval > Best_eval) {
394                 Best_indx = p;
395                 Best_eval = eval;
396             }
397         }
398         break;
399     case PGA_MINIMIZE :
400         for (p = 1; p < ctx->ga.PopSize; p++) {
401             eval = PGAGetEvaluation(ctx, p, pop);
402             if (eval < Best_eval) {
403                 Best_indx = p;
404                 Best_eval = eval;
405             }
406         }
407         break;
408     }
409     
410    PGADebugExited("PGAGetBestIndex");
411
412     return (Best_indx);
413}
414
415
416/*I****************************************************************************
417  PGAGetIndividual - translate string index and population symbolic constant
418  into pointer to an individual
419
420  Inputs:
421     ctx - context variable
422     p   - string index
423     pop - symbolic constant of the population the string is in
424
425  Outputs:
426     Address of the PGAIndividual structure for string p in population pop
427
428  Example:
429    PGAIndividual *source;
430    PGAContext *ctx;
431    int p;
432    :
433    source = PGAGetIndividual ( ctx, p, PGA_NEWPOP );
434
435****************************************************************************I*/
436PGAIndividual *PGAGetIndividual ( PGAContext *ctx, int p, int pop)
437{
438    PGAIndividual *ind;
439
440    PGADebugEntered("PGAGetIndividual");
441
442#ifdef OPTIMIZE
443    ind = (pop == PGA_OLDPOP) ? ctx->ga.oldpop : ctx->ga.newpop;
444
445    if (p>=0)
446      ind += p;
447    else
448      {
449      if(p== PGA_TEMP1)
450        ind += (ctx->ga.PopSize);
451      else if(p==PGA_TEMP2)
452        ind += (ctx->ga.PopSize) + 1;
453      else if(p==PGA_TEMP3)
454        ind += (ctx->ga.PopSize) + 2;
455
456    }
457#else
458    if (pop == PGA_OLDPOP)
459      ind = ctx->ga.oldpop;
460    else
461      if (pop == PGA_NEWPOP)
462        ind = ctx->ga.newpop;
463      else
464        PGAError(ctx, "PGAGetIndividual: Invalid value of pop:",
465                 PGA_FATAL, PGA_INT, (void *) &pop );
466
467    if (p>0 && p<ctx->ga.PopSize)
468      ind += p;
469    else
470      if (p == PGA_TEMP1)
471        ind += (ctx->ga.PopSize);
472      else if (p == PGA_TEMP2)
473          ind += (ctx->ga.PopSize) + 1;
474      else if (p == PGA_TEMP3)
475          ind += (ctx->ga.PopSize) + 2;
476      else
477          PGAError(ctx, "PGAGetIndividual: Invalid value of p:",
478                   PGA_FATAL, PGA_INT, (void *) &p );
479#endif
480
481    PGADebugExited("PGAGetIndividual");
482
483    return(ind);
484}
485
486
487/*I****************************************************************************
488   PGAUpdateAverage - Updates the average fitness statistic for reporting.
489
490   Inputs:
491       ctx - context variable
492       pop - symbolic constant of the population
493
494   Outputs:
495
496   Example:
497
498**************************************************************************I*/
499void PGAUpdateAverage(PGAContext *ctx, int pop)
500{
501    double ThisGensTotal = 0;
502    int p;
503
504    PGADebugEntered("PGAUpdateAverage");
505   
506    for (p = 0; p < ctx->ga.PopSize; p++)
507        if (!PGAGetEvaluationUpToDateFlag(ctx, p, pop))
508            PGAError(ctx, "PGAUpdateOnline: Evaluate function not up to "
509                     "date:", PGA_FATAL, PGA_INT, (void *) &p);
510
511    for (p = 0; p < ctx->ga.PopSize; p++)
512        ThisGensTotal += PGAGetEvaluation(ctx, p, pop);
513   
514    ctx->rep.Average = ThisGensTotal / (double)ctx->ga.PopSize;
515   
516    PGADebugExited("PGAUpdateAverage");
517}
518
519
520/*I****************************************************************************
521  PGAUpdateOnline - Updates the online value based on the results in
522  the new generation
523
524  Inputs:
525     ctx - context variable
526     pop - symbolic constant of the population whose statistics to use
527
528  Outputs:
529     Updates an internal field in the context variable
530
531  Example:
532     PGAContext *ctx;
533     :
534     PGAUpdateOnline(ctx,PGA_NEWPOP);
535
536**************************************************************************I*/
537void PGAUpdateOnline(PGAContext *ctx, int pop)
538{
539     double ThisGensTotal = 0;
540     int p;
541
542    PGADebugEntered("PGAUpdateOnline");
543
544     for (p = 0; p < ctx->ga.PopSize; p++)
545          if (!PGAGetEvaluationUpToDateFlag(ctx, p, pop))
546               PGAError(ctx, "PGAUpdateOnline: Evaluate function not up to "
547                        "date:", PGA_FATAL, PGA_INT, (void *) &p);
548
549     for (p = 0; p < ctx->ga.PopSize; p++)
550          ThisGensTotal += PGAGetEvaluation(ctx, p, pop);
551
552     PGADebugPrint(ctx, PGA_DEBUG_PRINTVAR, "PGAUpdateOnline",
553                   "ThisGensTotal = ", PGA_DOUBLE, (void *) &ThisGensTotal);
554
555     ctx->rep.Online = (ctx->rep.Online * ctx->ga.PopSize * (ctx->ga.iter - 1)
556                        + ThisGensTotal) / ctx->ga.iter / ctx->ga.PopSize;
557
558    PGADebugExited("PGAUpdateOnline");
559
560}
561
562/*I****************************************************************************
563  PGAUpdateOffline - Updates the offline value based on the results in
564  the new generation
565
566  Inputs:
567     ctx - context variable
568     pop - symbolic constant of the population whose statistics to use
569
570  Outputs:
571     Updates an internal field in the context variable
572
573  Example:
574     PGAContext *ctx;
575     :
576     PGAUpdateOffline(ctx,PGA_NEWPOP);
577
578**************************************************************************I*/
579void PGAUpdateOffline(PGAContext *ctx, int pop)
580{
581     int p;
582
583    PGADebugEntered("PGAUpdateOffline");
584
585     for (p = 0; p < ctx->ga.PopSize; p++)
586          if (!PGAGetEvaluationUpToDateFlag(ctx, p, pop))
587               PGAError(ctx, "PGAUpdateOffline: Evaluate function not up to "
588                        "date:", PGA_FATAL, PGA_INT, (void *) &p);
589
590     p = PGAGetBestIndex(ctx, pop);
591
592     ctx->rep.Offline = ((ctx->ga.iter - 1) * ctx->rep.Offline +
593                         PGAGetEvaluation(ctx, p, pop)) / ctx->ga.iter;
594
595    PGADebugExited("PGAUpdateOffline");
596}
597
598/*I****************************************************************************
599  PGAComputeSimilarity - computes the percentage of the population that have
600  the same evaluation function
601
602  Inputs:
603     ctx - context variable
604     pop - symbolic constant of the population whose statistics to use
605
606  Outputs:
607     returns a count of the number of  population members that have the same
608     evaluation function value
609
610  Example:
611     PGAContext *ctx;
612     :
613     PGAComputeSimilarity(ctx,PGA_NEWPOP);
614
615**************************************************************************I*/
616int PGAComputeSimilarity(PGAContext *ctx, PGAIndividual *pop)
617{
618     int max = 0, curr = 1, i;
619     double prev;
620
621    PGADebugEntered("PGAComputeSimilarity");
622
623     for(i=0; i < ctx->ga.PopSize; i++)
624     {
625          ctx->scratch.dblscratch[i] = (pop + i)->evalfunc;
626          ctx->scratch.intscratch[i] = i;
627     }
628
629     PGADblHeapSort(ctx, ctx->scratch.dblscratch, ctx->scratch.intscratch,
630                    ctx->ga.PopSize);
631
632     prev = ctx->scratch.dblscratch[0];
633
634     for(i = 1; i < ctx->ga.PopSize; i++)
635     {
636          if (ctx->scratch.dblscratch[i] == prev)
637               curr++;
638          else
639          {
640               if (curr > max)
641                    max = curr;
642               curr = 1;
643          }
644     }
645
646    PGADebugExited("PGAComputeSimilarity");
647
648     return(100 * max / ctx->ga.PopSize);
649}
Note: See TracBrowser for help on using the repository browser.