source: trunk/packages/optimizer/src/pgapack/pgapack/source/create.c @ 1271

Last change on this file since 1271 was 1271, checked in by liveletlive, 15 years ago

Changes made to API and pgapack for addition of new stoppage criteria. TIMEElapsed criteria is not yet added.

File size: 34.3 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: create.c: This file contains functions to create and initialize
66*                     data structures and populations.
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  PGACreate - creates an uninitialized context variable.  The Fortran version
76  of this function call contains only the last three arguments
77
78  Category: Generation
79
80  Inputs:
81     argc     - address of the count of the number of command line arguments.
82     argv     - array of command line arguments.
83     datatype - the data type used for the strings.  Must be one of
84                PGA_DATATYPE_BINARY, PGA_DATATYPE_CHARACTER,
85                PGA_DATATYPE_INTEGER, PGA_DATATYPE_REAL, or PGA_DATATYPE_USER
86                to specify binary-valued, character-valued, integer-valued,
87                real-valued, or a user-defined datatype, respectively.
88     len      - the string length (number of genes).
89     maxormin - the direction of optimization. Must be one of PGA_MAXIMIZE or
90                PGA_MINIMIZE for maximization or minimization, respectively.
91
92  Outputs:
93     A pointer to the context variable.
94
95  Example:
96
97     In C:
98     void main(int argc, char **argv) {
99         PGAContext *ctx;
100         :
101         ctx = PGACreate(&argc, argv, PGA_DATATYPE_BINARY, 100, PGA_MAXIMIZE);
102         :
103         //  Set options here
104         :
105         PGASetUp(ctx);
106         :
107         //  Run the GA here
108         :
109         PGADestroy(ctx);
110     }
111
112     In FORTRAN:
113             integer ctx
114             :
115             ctx = PGACreate(PGA_DATATYPE_BINARY, 100, PGA_MAXIMIZE)
116             :
117     c       Set options here
118             :
119             call PGASetUp(ctx)
120             :
121     c       Run the GA here
122             :
123             call PGADestroy(ctx)
124             stop
125             end
126
127****************************************************************************U*/
128PGAContext *PGACreate ( int *argc, char **argv,
129                        int datatype, int len, int maxormin )
130{
131    int i;
132    PGAContext *ctx;
133
134    ctx = (PGAContext *) malloc ( sizeof(PGAContext) );
135
136    /*  We cannot make PGA calls until we sort the FuncNameIndex below,
137     *  so we just manually print the (rather severe) error message.
138     */
139    if( ctx == NULL ) {
140        fprintf(stderr, "PGACreate: No room to allocate ctx\n");
141        exit(-1);
142    }
143
144   
145    /*  We use this (indirectly) in PGAReadCmdLine -- in processing
146     *  -pgahelp and -pgahelp debug.
147     */
148    MPI_Initialized (&ctx->par.MPIAlreadyInit);
149
150    /* Initialize MPI, only if it isn't already running (fortran)  */
151    if (!ctx->par.MPIAlreadyInit)
152         MPI_Init (argc, &argv);
153
154
155#if OPTIMIZE==0
156    /*  Sort the FuncNameIndex.  This allows us to use a binary search
157     *  for finding the function names.
158     */
159    PGASortFuncNameIndex(ctx);
160#endif
161
162    /* Initialize debug flags, then parse command line arguments.  */
163    for (i=0; i<PGA_DEBUG_MAXFLAGS; i++)
164        ctx->debug.PGADebugFlags[i] = PGA_FALSE;
165    PGAReadCmdLine( ctx, argc, argv );
166
167
168    /*  The context variable is now initialized enough to allow this
169     *  call to complete successfully.
170     */
171    PGADebugEntered("PGACreate");
172
173    /* required parameter 1: abstract data type */
174    switch (datatype)
175    {
176    case PGA_DATATYPE_BINARY:
177    case PGA_DATATYPE_INTEGER:
178    case PGA_DATATYPE_REAL:
179    case PGA_DATATYPE_CHARACTER:
180    case PGA_DATATYPE_USER:
181         ctx->ga.datatype  = datatype;
182         break;
183    default:
184         PGAError( ctx, "PGACreate: Invalid value of datatype:",
185                  PGA_FATAL, PGA_INT, (void *) &datatype );
186    };
187
188    /* required parameter 2: string string length */
189    if (len <= 1)
190        PGAError( ctx,  "PGACreate: Invalid value of len:",
191                  PGA_FATAL, PGA_INT, (void *) &len );
192    else
193        ctx->ga.StringLen = len;
194
195
196    /* required parameter 3: optimization direction */
197    switch (maxormin) {
198        case PGA_MAXIMIZE:
199        case PGA_MINIMIZE:
200          ctx->ga.optdir = maxormin;
201          break;
202        default:
203          PGAError( ctx, "PGACreate: Invalid value of optdir:",
204                    PGA_FATAL, PGA_INT, (void *) &maxormin );
205    };
206
207
208    /*  For datatype == PGA_DATATYPE_BINARY, set how many full words
209     *  are used in the packed representation, and how many extra bits
210     *  this leaves us with.  Finally, set how many total words are used;
211     *  if there are no extra bits, this is just the number of full words,
212     *  else, there is one more word used than the number of full words.
213     */
214    switch (datatype) {
215    case PGA_DATATYPE_BINARY:
216        ctx->ga.fw = ctx->ga.StringLen/WL;
217        ctx->ga.eb = ctx->ga.StringLen%WL;
218        if ( ctx->ga.eb == 0 )
219            ctx->ga.tw = ctx->ga.fw;
220        else
221            ctx->ga.tw = ctx->ga.fw+1;
222        break;
223    default:
224        ctx->ga.fw = PGA_UNINITIALIZED_INT;
225        ctx->ga.eb = PGA_UNINITIALIZED_INT;
226        ctx->ga.tw = PGA_UNINITIALIZED_INT;
227        break;
228    }
229
230    /*  Clear all the setting.  Later on, PGASetUp() will be called, and then
231     *  it will notice which setting are uninitialized, and set them to the
232     *  default value.
233     */
234    ctx->ga.PopSize            = PGA_UNINITIALIZED_INT;
235    ctx->ga.TgtFitnessVal          = PGA_UNINITIALIZED_DOUBLE;
236    ctx->ga.FitnessTol             = 0;
237    ctx->ga.TgtFitnessVar          = PGA_UNINITIALIZED_DOUBLE;
238    ctx->ga.VarTol                         = 0;
239    ctx->ga.TgtElapsedTime         = PGA_UNINITIALIZED_DOUBLE;
240    ctx->ga.StoppingRule       = PGA_STOP_MAXITER;
241    ctx->ga.MaxIter            = PGA_UNINITIALIZED_INT;
242    ctx->ga.MaxNoChange        = PGA_UNINITIALIZED_INT;
243    ctx->ga.MaxSimilarity      = PGA_UNINITIALIZED_INT;
244    ctx->ga.NumReplace         = PGA_UNINITIALIZED_INT;
245    ctx->ga.CrossoverType      = PGA_UNINITIALIZED_INT;
246    ctx->ga.SelectType         = PGA_UNINITIALIZED_INT;
247    ctx->ga.FitnessType        = PGA_UNINITIALIZED_INT;
248    ctx->ga.FitnessMinType     = PGA_UNINITIALIZED_INT;
249    ctx->ga.MutationType       = PGA_UNINITIALIZED_INT;
250    ctx->ga.MutateOnlyNoCross  = PGA_UNINITIALIZED_INT;
251    ctx->ga.MutateRealValue    = PGA_UNINITIALIZED_DOUBLE;
252    ctx->ga.MutateIntegerValue = PGA_UNINITIALIZED_INT;
253    ctx->ga.MutateBoundedFlag  = PGA_UNINITIALIZED_INT;
254    ctx->ga.NoDuplicates       = PGA_UNINITIALIZED_INT;
255    ctx->ga.MutationProb       = PGA_UNINITIALIZED_DOUBLE;
256    ctx->ga.CrossoverProb      = PGA_UNINITIALIZED_DOUBLE;
257    ctx->ga.UniformCrossProb   = PGA_UNINITIALIZED_DOUBLE;
258    ctx->ga.PTournamentProb    = PGA_UNINITIALIZED_DOUBLE;
259    ctx->ga.FitnessRankMax     = PGA_UNINITIALIZED_DOUBLE;
260    ctx->ga.FitnessCmaxValue   = PGA_UNINITIALIZED_DOUBLE;
261    ctx->ga.PopReplace         = PGA_UNINITIALIZED_INT;
262    ctx->ga.iter               = 0;
263    ctx->ga.ItersOfSame        = 0;
264    ctx->ga.PercentSame        = 0;
265    ctx->ga.selected           = NULL;
266    ctx->ga.SelectIndex        = 0;
267    ctx->ga.restart            = PGA_UNINITIALIZED_INT;
268    ctx->ga.restartFreq        = PGA_UNINITIALIZED_INT;
269    ctx->ga.restartAlleleProb  = PGA_UNINITIALIZED_DOUBLE;
270
271    /* Operations */
272    ctx->cops.CreateString      = NULL;
273    ctx->cops.Mutation          = NULL;
274    ctx->cops.Crossover         = NULL;
275    ctx->cops.PrintString       = NULL;
276    ctx->cops.CopyString        = NULL;
277    ctx->cops.Duplicate         = NULL;
278    ctx->cops.InitString        = NULL;
279    ctx->cops.BuildDatatype     = NULL;
280    ctx->cops.StopCond           = NULL;
281    ctx->cops.EndOfGen          = NULL;
282
283    ctx->fops.Mutation          = NULL;
284    ctx->fops.Crossover         = NULL;
285    ctx->fops.PrintString       = NULL;
286    ctx->fops.CopyString        = NULL;
287    ctx->fops.Duplicate         = NULL;
288    ctx->fops.InitString        = NULL;
289    ctx->fops.StopCond          = NULL;
290    ctx->fops.EndOfGen          = NULL;
291
292    /* Parallel */
293    ctx->par.NumIslands        = PGA_UNINITIALIZED_INT;
294    ctx->par.NumDemes          = PGA_UNINITIALIZED_INT;
295    ctx->par.DefaultComm       = NULL;
296#ifdef FAKE_MPI
297    ctx->par.MPIStubLibrary    = PGA_TRUE;
298#else
299    ctx->par.MPIStubLibrary    = PGA_FALSE;
300#endif
301
302    /* Reporting */
303    ctx->rep.PrintFreq         = PGA_UNINITIALIZED_INT;
304    ctx->rep.PrintOptions      = 0;
305    ctx->rep.Online            = 0;
306    ctx->rep.Offline           = 0;
307    ctx->rep.Best              = PGA_UNINITIALIZED_DOUBLE;
308    ctx->rep.starttime         = PGA_UNINITIALIZED_INT;
309
310    /* System
311     *
312     *  If ctx->sys.UserFortran is not set to PGA_TRUE in pgacreate_ (the
313     *  fortran stub to PGACreate), the user program is in C.
314     */
315    if (ctx->sys.UserFortran != PGA_TRUE)
316         ctx->sys.UserFortran  = PGA_FALSE;
317    ctx->sys.SetUpCalled       = PGA_FALSE;
318    ctx->sys.PGAMaxInt         = INT_MAX;
319    ctx->sys.PGAMinInt         = INT_MIN;
320    ctx->sys.PGAMaxDouble      = DBL_MAX;
321    ctx->sys.PGAMinDouble      = DBL_MIN;
322
323    /* Debug */
324    /* Set above before parsing command line arguments */
325
326    /* Initialization */
327    ctx->init.RandomInit        = PGA_UNINITIALIZED_INT;
328    ctx->init.BinaryProbability = PGA_UNINITIALIZED_DOUBLE;
329    ctx->init.RealType          = PGA_UNINITIALIZED_INT;
330    ctx->init.IntegerType       = PGA_UNINITIALIZED_INT;
331    ctx->init.CharacterType     = PGA_UNINITIALIZED_INT;
332    ctx->init.RandomSeed        = PGA_UNINITIALIZED_INT;
333
334    /*  Allocate and clear arrays to define the minimum and maximum values
335     *  allowed by integer and real datatypes.
336     */
337    switch (datatype)
338    {
339    case PGA_DATATYPE_INTEGER:
340         ctx->init.IntegerMax = (int *) malloc(len * sizeof(PGAInteger));
341         if (!ctx->init.IntegerMax)
342              PGAError(ctx, "PGACreate: No room to allocate:", PGA_FATAL,
343                       PGA_CHAR, (void *) "ctx->init.IntegerMax");
344         ctx->init.IntegerMin = (int *) malloc(len * sizeof(PGAInteger));
345         if (!ctx->init.IntegerMin)
346              PGAError(ctx, "PGACreate: No room to allocate:", PGA_FATAL,
347                       PGA_CHAR, (void *) "ctx->init.IntegerMin");
348         ctx->init.RealMax = NULL;
349         ctx->init.RealMin = NULL;
350         for (i = 0; i < len; i++)
351         {
352              ctx->init.IntegerMin[i] = PGA_UNINITIALIZED_INT;
353              ctx->init.IntegerMax[i] = PGA_UNINITIALIZED_INT;
354         }
355         break;
356    case PGA_DATATYPE_REAL:
357         ctx->init.RealMax = (PGAReal *) malloc(len * sizeof(PGAReal));
358         if (!ctx->init.RealMax)
359              PGAError(ctx, "PGACreate: No room to allocate:", PGA_FATAL,
360                       PGA_CHAR, (void *) "ctx->init.RealMax");
361         ctx->init.RealMin = (PGAReal *) malloc(len * sizeof(PGAReal));
362         if (!ctx->init.RealMin)
363              PGAError(ctx, "PGACreate: No room to allocate:", PGA_FATAL,
364                       PGA_CHAR, (void *) "ctx->init.RealMin");
365         ctx->init.IntegerMax = NULL;
366         ctx->init.IntegerMin = NULL;
367         for (i = 0; i < len; i++)
368         {
369              ctx->init.RealMin[i] = PGA_UNINITIALIZED_DOUBLE;
370              ctx->init.RealMax[i] = PGA_UNINITIALIZED_DOUBLE;
371         }
372         break;
373    default:
374         ctx->init.RealMax = NULL;
375         ctx->init.RealMin = NULL;
376         ctx->init.IntegerMax = NULL;
377         ctx->init.IntegerMin = NULL;
378         break;
379    }
380
381    PGADebugExited("PGACreate");
382
383    return(ctx);
384}
385
386
387/*U****************************************************************************
388  PGASetUp - set all uninitialized variables to default values and initialize
389  some internal arrays.  Must be called after PGACreate() and before the GA
390  is started.
391
392  Category: Generation
393
394  Inputs:
395     ctx - context variable
396
397  Outputs:
398     Uninitialized values in the context variable are set to defaults, and
399     set values are checked for legality.
400
401  Example:
402     PGAContext *ctx;
403     :
404     PGACreate(ctx, ...);
405     :
406     //  Set options here
407     :
408     PGASetUp(ctx);
409
410****************************************************************************U*/
411void PGASetUp ( PGAContext *ctx )
412{
413    /*  These are for temporary storage of datatype specific functions.
414     *  They allow some (understatement of the yesr!!) cleaning of the
415     *  code below.
416     */
417    void         (*CreateString)(PGAContext *, int, int, int);
418    int          (*Mutation)(PGAContext *, int, int, double);
419    void         (*Crossover)(PGAContext *, int, int, int, int, int, int);
420    void         (*PrintString)(PGAContext *, FILE *, int, int);
421    void         (*CopyString)(PGAContext *, int, int, int, int);
422    int          (*Duplicate)(PGAContext *, int, int, int, int);
423    void         (*InitString)(PGAContext *, int, int);
424    MPI_Datatype (*BuildDatatype)(PGAContext *, int, int);
425    int err=0, i;
426
427    PGADebugEntered("PGASetUp");
428    PGAFailIfSetUp("PGASetUp");
429
430    ctx->sys.SetUpCalled = PGA_TRUE;
431
432    if ( ctx->ga.datatype           == PGA_DATATYPE_BINARY   &&
433         ctx->ga.tw                 == PGA_UNINITIALIZED_INT )
434      PGAError( ctx,
435               "PGASetUp: Binary: Total Words (ctx->ga.tw) == UNINITIALIZED?",
436               PGA_FATAL, PGA_INT, (void *) &ctx->ga.tw );
437
438    if ( ctx->ga.datatype           == PGA_DATATYPE_BINARY  &&
439         ctx->ga.fw                 == PGA_UNINITIALIZED_INT )
440      PGAError( ctx,
441               "PGASetUp: Binary: Full Words (ctx->ga.fw) == UNINITIALIZED?",
442               PGA_FATAL, PGA_INT,  (void *) &ctx->ga.fw );
443
444    if ( ctx->ga.datatype           == PGA_DATATYPE_BINARY  &&
445         ctx->ga.eb                 == PGA_UNINITIALIZED_INT )
446      PGAError( ctx,
447               "PGASetUp: Binary: Empty Bits (ctx->ga.eb) == UNINITIALIZED?",
448               PGA_FATAL, PGA_INT, (void *) &ctx->ga.eb );
449
450    if ( ctx->ga.PopSize            == PGA_UNINITIALIZED_INT)
451      ctx->ga.PopSize                = 100;
452
453    if ( ctx->ga.MaxIter            == PGA_UNINITIALIZED_INT)
454         ctx->ga.MaxIter             = 1000;
455
456    if ( ctx->ga.MaxNoChange        == PGA_UNINITIALIZED_INT)
457         ctx->ga.MaxNoChange         = 100;
458
459    if ( ctx->ga.MaxSimilarity      == PGA_UNINITIALIZED_INT)
460         ctx->ga.MaxSimilarity       = 95;
461
462    if ( ctx->ga.NumReplace         == PGA_UNINITIALIZED_INT)
463         ctx->ga.NumReplace          = (int) ceil(ctx->ga.PopSize * 0.1);
464
465    if ( ctx->ga.NumReplace          > ctx->ga.PopSize)
466         PGAError(ctx, "PGASetUp: NumReplace > PopSize",
467                  PGA_FATAL, PGA_VOID, NULL);
468
469    if ( ctx->ga.CrossoverType      == PGA_UNINITIALIZED_INT)
470         ctx->ga.CrossoverType       = PGA_CROSSOVER_TWOPT;
471
472    if (ctx->ga.CrossoverType       == PGA_CROSSOVER_TWOPT &&
473        ctx->ga.StringLen == 2)
474         PGAError(ctx, "PGASetUp: Invalid Crossover type for string of length "
475                  "2", PGA_FATAL, PGA_INT, (void *) &ctx->ga.CrossoverType);
476
477    if ( ctx->ga.SelectType        == PGA_UNINITIALIZED_INT)
478         ctx->ga.SelectType         = PGA_SELECT_TOURNAMENT;
479
480    if ( ctx->ga.FitnessType       == PGA_UNINITIALIZED_INT)
481         ctx->ga.FitnessType        = PGA_FITNESS_RAW;
482
483    if ( ctx->ga.FitnessMinType    == PGA_UNINITIALIZED_INT)
484         ctx->ga.FitnessMinType     = PGA_FITNESSMIN_CMAX;
485
486    if ( ctx->ga.MutateOnlyNoCross == PGA_UNINITIALIZED_INT)
487         ctx->ga.MutateOnlyNoCross  = PGA_TRUE;
488
489    if ( ctx->ga.MutationProb      == PGA_UNINITIALIZED_DOUBLE)
490         ctx->ga.MutationProb       = 1. / ctx->ga.StringLen;
491
492    if ( ctx->ga.MutationType      == PGA_UNINITIALIZED_INT) {
493        switch (ctx->ga.datatype) {
494        case PGA_DATATYPE_BINARY:
495        case PGA_DATATYPE_CHARACTER:
496        case PGA_DATATYPE_USER:
497             /* leave PGA_UNINITIALIZED_INT for these data types */
498             break;
499        case PGA_DATATYPE_REAL:
500             ctx->ga.MutationType   = PGA_MUTATION_GAUSSIAN;
501             break;
502        case PGA_DATATYPE_INTEGER:
503             switch (ctx->init.IntegerType) {
504                 case PGA_UNINITIALIZED_INT:
505                 case PGA_IINIT_PERMUTE:
506                     ctx->ga.MutationType   = PGA_MUTATION_PERMUTE;
507                     break;
508                 case PGA_IINIT_RANGE:
509                     ctx->ga.MutationType   = PGA_MUTATION_RANGE;
510                     break;
511             }
512             break;
513        default:
514             PGAError( ctx, "PGASetup: Invalid value of ctx->ga.datatype:",
515                       PGA_FATAL, PGA_INT, (void *) &(ctx->ga.datatype) );
516         }
517    }
518
519    if (ctx->ga.MutateRealValue   == PGA_UNINITIALIZED_DOUBLE) {
520        switch (ctx->ga.MutationType) {
521        case PGA_MUTATION_GAUSSIAN:
522            ctx->ga.MutateRealValue   = 0.1;
523            break;
524        case PGA_MUTATION_UNIFORM:
525            ctx->ga.MutateRealValue   = 0.1;
526            break;
527        case PGA_MUTATION_CONSTANT:
528            ctx->ga.MutateRealValue   = 0.01;
529            break;
530        case PGA_MUTATION_RANGE:
531        default:
532            ctx->ga.MutateRealValue   = 0.0;
533        }
534    }
535
536    if ( ctx->ga.MutateIntegerValue == PGA_UNINITIALIZED_INT)
537         ctx->ga.MutateIntegerValue  = 1;
538
539    if ( ctx->ga.MutateBoundedFlag == PGA_UNINITIALIZED_INT)
540         ctx->ga.MutateBoundedFlag  = PGA_FALSE;
541
542    if ( ctx->ga.NoDuplicates      == PGA_UNINITIALIZED_INT)
543         ctx->ga.NoDuplicates       = PGA_FALSE;
544
545    if ( ctx->ga.NoDuplicates && ((ctx->ga.StoppingRule & PGA_STOP_TOOSIMILAR)
546                                   == PGA_STOP_TOOSIMILAR))
547         PGAError(ctx, "PGASetUp: No Duplicates inconsistent with Stopping "
548                  "Rule:", PGA_FATAL, PGA_INT, (void *) &ctx->ga.StoppingRule);
549
550    if ( ctx->ga.CrossoverProb     == PGA_UNINITIALIZED_DOUBLE)
551         ctx->ga.CrossoverProb      = 0.85;
552
553    if ( ctx->ga.UniformCrossProb  == PGA_UNINITIALIZED_DOUBLE)
554         ctx->ga.UniformCrossProb   = 0.6;
555
556    if ( ctx->ga.PTournamentProb   == PGA_UNINITIALIZED_DOUBLE)
557         ctx->ga.PTournamentProb    = 0.6;
558
559    if ( ctx->ga.FitnessRankMax    == PGA_UNINITIALIZED_DOUBLE)
560         ctx->ga.FitnessRankMax     = 1.2;
561
562    if ( ctx->ga.FitnessCmaxValue  == PGA_UNINITIALIZED_DOUBLE)
563         ctx->ga.FitnessCmaxValue   = 1.01;
564
565    if ( ctx->ga.PopReplace        == PGA_UNINITIALIZED_INT)
566         ctx->ga.PopReplace         = PGA_POPREPL_BEST;
567
568    if ( ctx->ga.restart           == PGA_UNINITIALIZED_INT)
569         ctx->ga.restart            = PGA_FALSE;
570
571    if ( ctx->ga.restartFreq       == PGA_UNINITIALIZED_INT)
572         ctx->ga.restartFreq        = 50;
573
574    if ( ctx->ga.restartAlleleProb == PGA_UNINITIALIZED_DOUBLE)
575         ctx->ga.restartAlleleProb = 0.5;
576
577
578/* ops */
579    /*  If no user supplied "done" function, use the built in one.
580     *  No need to check EndOfGen; they only get called if they
581     *  are defined.
582     */
583    if (((void *)ctx->cops.StopCond == (void *)PGADone) ||
584        ((void *)ctx->fops.StopCond == (void *)PGADone))
585        PGAError( ctx,
586                 "PGASetUp: Using PGADone as the user stopping condition will"
587                 " result in an infinite loop!", PGA_FATAL, PGA_VOID, NULL);
588
589    switch (ctx->ga.datatype) {
590    case PGA_DATATYPE_BINARY:
591        CreateString  = PGABinaryCreateString;
592        BuildDatatype = PGABinaryBuildDatatype;
593        Mutation      = PGABinaryMutation;
594
595        switch (ctx->ga.CrossoverType) {
596          case PGA_CROSSOVER_ONEPT:
597            Crossover  = PGABinaryOneptCrossover;
598            break;
599          case PGA_CROSSOVER_TWOPT:
600            Crossover  = PGABinaryTwoptCrossover;
601            break;
602          case PGA_CROSSOVER_UNIFORM:
603            Crossover  = PGABinaryUniformCrossover;
604            break;
605        }
606        PrintString    = PGABinaryPrintString;
607        CopyString     = PGABinaryCopyString;
608        Duplicate      = PGABinaryDuplicate;
609        InitString     = PGABinaryInitString;
610        break;
611      case PGA_DATATYPE_INTEGER:
612        CreateString   = PGAIntegerCreateString;
613        BuildDatatype  = PGAIntegerBuildDatatype;
614        Mutation       = PGAIntegerMutation;
615        switch (ctx->ga.CrossoverType) {
616          case PGA_CROSSOVER_ONEPT:
617            Crossover  = PGAIntegerOneptCrossover;
618            break;
619          case PGA_CROSSOVER_TWOPT:
620            Crossover  = PGAIntegerTwoptCrossover;
621            break;
622          case PGA_CROSSOVER_UNIFORM:
623            Crossover  = PGAIntegerUniformCrossover;
624            break;
625        }
626        PrintString    = PGAIntegerPrintString;
627        CopyString     = PGAIntegerCopyString;
628        Duplicate      = PGAIntegerDuplicate;
629        InitString     = PGAIntegerInitString;
630        break;
631      case PGA_DATATYPE_REAL:
632        CreateString   = PGARealCreateString;
633        BuildDatatype  = PGARealBuildDatatype;
634        Mutation       = PGARealMutation;
635        switch (ctx->ga.CrossoverType) {
636          case PGA_CROSSOVER_ONEPT:
637            Crossover  = PGARealOneptCrossover;
638            break;
639          case PGA_CROSSOVER_TWOPT:
640            Crossover  = PGARealTwoptCrossover;
641            break;
642          case PGA_CROSSOVER_UNIFORM:
643            Crossover  = PGARealUniformCrossover;
644            break;
645        }
646        PrintString    = PGARealPrintString;
647        CopyString     = PGARealCopyString;
648        Duplicate      = PGARealDuplicate;
649        InitString     = PGARealInitString;
650        break;
651      case PGA_DATATYPE_CHARACTER:
652        CreateString   = PGACharacterCreateString;
653        BuildDatatype  = PGACharacterBuildDatatype;
654        Mutation       = PGACharacterMutation;
655        switch (ctx->ga.CrossoverType) {
656          case PGA_CROSSOVER_ONEPT:
657            Crossover  = PGACharacterOneptCrossover;
658            break;
659          case PGA_CROSSOVER_TWOPT:
660            Crossover  = PGACharacterTwoptCrossover;
661            break;
662          case PGA_CROSSOVER_UNIFORM:
663            Crossover  = PGACharacterUniformCrossover;
664            break;
665        }
666        PrintString    = PGACharacterPrintString;
667        CopyString     = PGACharacterCopyString;
668        Duplicate      = PGACharacterDuplicate;
669        InitString     = PGACharacterInitString;
670        break;
671      case PGA_DATATYPE_USER:
672        if (ctx->cops.CreateString == NULL)
673            PGAError( ctx,
674                     "PGASetUp: User datatype needs CreateString function:",
675                     PGA_WARNING, PGA_INT, (void *) &err );
676        if (ctx->cops.Mutation     == NULL)
677            PGAError( ctx,
678                     "PGASetUp: User datatype needs Mutation function:",
679                     PGA_WARNING, PGA_INT, (void *) &err );
680        if (ctx->cops.Crossover    == NULL)
681            PGAError( ctx,
682                     "PGASetUp: User datatype needs Crossover function:",
683                     PGA_WARNING, PGA_INT, (void *) &err );
684        if (ctx->cops.PrintString  == NULL)
685            PGAError( ctx,
686                     "PGASetUp: User datatype needs PrintString function:",
687                     PGA_WARNING, PGA_INT, (void *) &err );
688        if (ctx->cops.Duplicate    == NULL)
689            PGAError( ctx,
690                     "PGASetUp: User datatype needs Duplicate function:",
691                     PGA_WARNING, PGA_INT, (void *) &err );
692        if (ctx->cops.CopyString    == NULL)
693            PGAError( ctx,
694                     "PGASetUp: User datatype needs CopyString function:",
695                     PGA_WARNING, PGA_INT, (void *) &err );
696        if (ctx->cops.BuildDatatype == NULL)
697             PGAError(ctx,
698                      "PGASetUp: User datatype needs BuildDatatype "
699                      "function:", PGA_FATAL, PGA_INT, (void *) &err );
700        break;
701    }
702    if ((ctx->cops.Mutation     == NULL) && (ctx->fops.Mutation    == NULL))
703        ctx->cops.Mutation      = Mutation;
704    if ((ctx->cops.Crossover    == NULL) && (ctx->fops.Crossover   == NULL))
705        ctx->cops.Crossover     = Crossover;
706    if ((ctx->cops.PrintString  == NULL) && (ctx->fops.PrintString == NULL))
707        ctx->cops.PrintString   = PrintString;
708    if ((ctx->cops.Duplicate    == NULL) && (ctx->fops.Duplicate   == NULL))
709        ctx->cops.Duplicate     = Duplicate;
710    if ((ctx->cops.InitString   == NULL) && (ctx->fops.InitString  == NULL))
711        ctx->cops.InitString    = InitString;
712    if (ctx->cops.CreateString  == NULL)
713        ctx->cops.CreateString  = CreateString;
714    if (ctx->cops.CopyString    == NULL)
715        ctx->cops.CopyString    = CopyString;
716    if (ctx->cops.BuildDatatype == NULL)
717        ctx->cops.BuildDatatype = BuildDatatype;
718   
719/* par */
720    if ( ctx->par.NumIslands       == PGA_UNINITIALIZED_INT)
721         ctx->par.NumIslands        = 1;
722    if ( ctx->par.NumDemes         == PGA_UNINITIALIZED_INT)
723         ctx->par.NumDemes          = 1;
724    if ( ctx->par.DefaultComm      == NULL )
725         ctx->par.DefaultComm       = MPI_COMM_WORLD;
726
727   
728
729/* rep */
730    if ( ctx->rep.PrintFreq == PGA_UNINITIALIZED_INT)
731         ctx->rep.PrintFreq  = 10;
732
733/* sys */
734    /* no more sets necessary here. */
735
736/* debug */
737
738/* init */
739    if ( ctx->init.RandomInit == PGA_UNINITIALIZED_INT)
740         ctx->init.RandomInit  = PGA_TRUE;
741
742    if ( ctx->init.BinaryProbability == PGA_UNINITIALIZED_DOUBLE)
743         ctx->init.BinaryProbability  = 0.5;
744
745    if ( ctx->init.RealType == PGA_UNINITIALIZED_INT)
746         ctx->init.RealType  = PGA_RINIT_RANGE;
747    if ( ctx->init.IntegerType == PGA_UNINITIALIZED_INT)
748         ctx->init.IntegerType  = PGA_IINIT_PERMUTE;
749    if ( ctx->init.CharacterType == PGA_UNINITIALIZED_INT)
750         ctx->init.CharacterType = PGA_CINIT_LOWER;
751
752    switch (ctx->ga.datatype)
753    {
754    case PGA_DATATYPE_INTEGER:
755         for (i = 0; i < ctx->ga.StringLen; i++)
756         {
757              if (ctx->init.IntegerMin[i] == PGA_UNINITIALIZED_INT)
758                   ctx->init.IntegerMin[i] = 0;
759              if (ctx->init.IntegerMax[i] == PGA_UNINITIALIZED_INT)
760                   ctx->init.IntegerMax[i] = ctx->ga.StringLen - 1;
761         }
762         break;
763    case PGA_DATATYPE_REAL:
764         for (i = 0; i < ctx->ga.StringLen; i++)
765         {
766              if (ctx->init.RealMin[i] == PGA_UNINITIALIZED_DOUBLE)
767                   ctx->init.RealMin[i] = 0.;
768              if (ctx->init.RealMax[i] == PGA_UNINITIALIZED_DOUBLE)
769                   ctx->init.RealMax[i] = 1.;
770         }
771         break;
772    }
773
774    /* If a seed was not specified, get one from a time of day call */
775    if ( ctx->init.RandomSeed == PGA_UNINITIALIZED_INT)
776         ctx->init.RandomSeed = (int)time(NULL);
777
778    /* seed random number generator with this process' unique seed */
779    ctx->init.RandomSeed += PGAGetRank(ctx, MPI_COMM_WORLD);
780    PGARandom01( ctx, ctx->init.RandomSeed );
781
782    ctx->ga.selected        = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
783    if (ctx->ga.selected == NULL)
784         PGAError(ctx, "PGASetUp: No room to allocate ctx->ga.selected",
785                  PGA_FATAL, PGA_VOID, NULL);
786
787    ctx->ga.sorted          = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
788    if (ctx->ga.sorted == NULL)
789         PGAError(ctx, "PGASetUp: No room to allocate ctx->ga.sorted",
790                  PGA_FATAL, PGA_VOID, NULL);
791
792    ctx->scratch.intscratch = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
793    if (ctx->scratch.intscratch == NULL)
794         PGAError(ctx, "PGASetUp: No room to allocate ctx->scratch.intscratch",
795                  PGA_FATAL, PGA_VOID, NULL);
796
797    ctx->scratch.dblscratch = (double *)malloc(sizeof(double) * ctx->ga.PopSize);
798    if (ctx->scratch.dblscratch == NULL)
799         PGAError(ctx, "PGASetUp: No room to allocate ctx->scratch.dblscratch",
800                  PGA_FATAL, PGA_VOID, NULL);
801
802    PGACreatePop ( ctx , PGA_OLDPOP );
803    PGACreatePop ( ctx , PGA_NEWPOP );
804
805    ctx->rep.starttime = time(NULL);
806
807    PGADebugExited("PGASetUp");
808}
809
810/*U****************************************************************************
811   PGASetRandomInitFlag - A boolean flag to indicate whether to randomly
812   initialize alleles.  Legal values are PGA_TRUE and PGA_FALSE.  Default
813   is PGA_TRUE -- randomly initialize alleles.
814
815   Category: Initialization
816
817   Inputs:
818      ctx  - context variable
819      flag - either PGA_TRUE or PGA_FALSE
820
821   Outputs:
822      None
823
824   Example:
825      Set the initialization routine to initialize all alleles to zero
826
827      PGAContext *ctx;
828      :
829      PGASetRandomInitFlag(ctx,PGA_FALSE);
830
831****************************************************************************U*/
832void PGASetRandomInitFlag(PGAContext *ctx, int RandomBoolean)
833{
834    PGADebugEntered("PGASetRandomInitFlag");
835    PGAFailIfSetUp("PGASetRandomInitFlag");
836
837  switch (RandomBoolean) {
838    case PGA_TRUE:
839    case PGA_FALSE:
840      ctx->init.RandomInit = RandomBoolean;
841      break;
842    default:
843      PGAError(ctx, "PGASetRandomInitFlag: Invalid value of RandomBoolean:",
844               PGA_FATAL, PGA_INT, (void *) &RandomBoolean);
845      break;
846    }
847    PGADebugExited("PGASetRandomInitFlag");
848}
849
850/*U***************************************************************************
851   PGAGetRandomInitFlag - returns true/false to indicate whether or not
852   alleles are randomly initialized.
853
854   Category: Initialization
855
856   Inputs:
857      ctx - context variable
858
859   Outputs:
860      Returns PGA_TRUE if alleles are randomly initialized.
861      Otherwise, returns PGA_FALSE
862
863   Example:
864      PGAContext *ctx;
865      int raninit;
866      :
867      raninit = PGAGetRandomInitFlag(ctx);
868      switch (raninit) {
869      case PGA_TRUE:
870          printf("Population is randomly initialized\n");
871          break;
872      case PGA_FALSE:
873          printf("Population initialized to zero\n");
874          break;
875      }
876
877***************************************************************************U*/
878int PGAGetRandomInitFlag (PGAContext *ctx)
879{
880    PGADebugEntered("PGAGetRandomInitFlag");
881
882    PGAFailIfNotSetUp("PGAGetRandomInitFlag");
883
884    PGADebugExited("PGAGetRandomInitFlag");
885
886    return(ctx->init.RandomInit);
887}
888
889
890/*I****************************************************************************
891  PGACreatePop - allocates a population of individuals and calls
892  PGACreateIndividual to set up each one
893
894  Inputs:
895     ctx - context variable
896     pop - symbolic constant of the population to create
897
898  Outputs:
899     None
900
901  Example:
902     PGAContext *ctx;
903     :
904     PGACreatePop(ctx, PGA_NEWPOP);
905
906****************************************************************************I*/
907void PGACreatePop (PGAContext *ctx, int pop)
908{
909     int p, flag;
910
911    PGADebugEntered("PGACreatePop");
912
913     switch (pop)
914     {
915     case PGA_OLDPOP:
916          ctx->ga.oldpop = (PGAIndividual *)malloc(sizeof(PGAIndividual) *
917                                                   (ctx->ga.PopSize + 2));
918          if (ctx->ga.oldpop == NULL)
919               PGAError(ctx, "PGACreatePop: No room to allocate "
920                        "ctx->ga.oldpop", PGA_FATAL, PGA_VOID, NULL);
921          flag = ctx->init.RandomInit;
922          break;
923     case PGA_NEWPOP:
924          ctx->ga.newpop = (PGAIndividual *)malloc(sizeof(PGAIndividual) *
925                                                   (ctx->ga.PopSize + 2));
926          if (ctx->ga.newpop == NULL)
927               PGAError(ctx, "PGACreatePop: No room to allocate "
928                        "ctx->ga.newpop", PGA_FATAL, PGA_VOID, NULL);
929          flag = PGA_FALSE;
930          break;
931     default:
932          PGAError(ctx, "PGACreatePop: Invalid value of pop:", PGA_FATAL,
933                   PGA_INT, (void *) &pop );
934          break;
935     };
936     for (p = 0; p < ctx->ga.PopSize; p++)
937          PGACreateIndividual (ctx, p, pop, flag);
938     PGACreateIndividual (ctx, PGA_TEMP1, pop, PGA_FALSE);
939     PGACreateIndividual (ctx, PGA_TEMP2, pop, PGA_FALSE);
940
941    PGADebugExited("PGACreatePop");
942}
943
944
945/*I****************************************************************************
946  PGACreateIndividual - initialize to zero various data structures of an
947  individual and call the appropriate function to create and initialize the
948  string for the specific data type
949
950  Inputs:
951     ctx      - context variable
952     p        - string index
953     pop      - symbolic constant of the population string p is in
954     initflag - if the value is PGA_TRUE, the string is randomly initialized.
955                Otherwise it is set to zero.
956
957  Outputs:
958     None
959
960  Example:
961     PGAContext *ctx;
962     int p;
963     :
964     PGACreateIndividual(ctx, p, PGA_NEWPOP, PGA_TRUE);
965
966****************************************************************************I*/
967void PGACreateIndividual (PGAContext *ctx, int p, int pop, int initflag)
968{
969    PGAIndividual *ind = PGAGetIndividual(ctx, p, pop);
970
971    PGADebugEntered("PGACreateIndividual");
972
973    ind->evalfunc     = 0.0;
974    ind->fitness      = 0.0;
975    ind->evaluptodate = PGA_FALSE;
976
977    (*ctx->cops.CreateString)(ctx, p, pop, initflag);
978   
979    PGADebugExited("PGACreateIndividual");
980}
Note: See TracBrowser for help on using the repository browser.