in build/pga/source/create.c [382:779]
void PGASetUp ( PGAContext *ctx )
{
/* These are for temporary storage of datatype specific functions.
* They allow some (understatement of the yesr!!) cleaning of the
* code below.
*/
void (*CreateString)(PGAContext *, int, int, int);
int (*Mutation)(PGAContext *, int, int, double);
void (*Crossover)(PGAContext *, int, int, int, int, int, int);
void (*PrintString)(PGAContext *, FILE *, int, int);
void (*CopyString)(PGAContext *, int, int, int, int);
int (*Duplicate)(PGAContext *, int, int, int, int);
void (*InitString)(PGAContext *, int, int);
MPI_Datatype (*BuildDatatype)(PGAContext *, int, int);
int err=0, i;
PGADebugEntered("PGASetUp");
PGAFailIfSetUp("PGASetUp");
ctx->sys.SetUpCalled = PGA_TRUE;
if ( ctx->ga.datatype == PGA_DATATYPE_BINARY &&
ctx->ga.tw == PGA_UNINITIALIZED_INT )
PGAError( ctx,
"PGASetUp: Binary: Total Words (ctx->ga.tw) == UNINITIALIZED?",
PGA_FATAL, PGA_INT, (void *) &ctx->ga.tw );
if ( ctx->ga.datatype == PGA_DATATYPE_BINARY &&
ctx->ga.fw == PGA_UNINITIALIZED_INT )
PGAError( ctx,
"PGASetUp: Binary: Full Words (ctx->ga.fw) == UNINITIALIZED?",
PGA_FATAL, PGA_INT, (void *) &ctx->ga.fw );
if ( ctx->ga.datatype == PGA_DATATYPE_BINARY &&
ctx->ga.eb == PGA_UNINITIALIZED_INT )
PGAError( ctx,
"PGASetUp: Binary: Empty Bits (ctx->ga.eb) == UNINITIALIZED?",
PGA_FATAL, PGA_INT, (void *) &ctx->ga.eb );
if ( ctx->ga.PopSize == PGA_UNINITIALIZED_INT)
ctx->ga.PopSize = 100;
if ( ctx->ga.MaxIter == PGA_UNINITIALIZED_INT)
ctx->ga.MaxIter = 1000;
if ( ctx->ga.MaxNoChange == PGA_UNINITIALIZED_INT)
ctx->ga.MaxNoChange = 100;
if ( ctx->ga.MaxSimilarity == PGA_UNINITIALIZED_INT)
ctx->ga.MaxSimilarity = 95;
if ( ctx->ga.NumReplace == PGA_UNINITIALIZED_INT)
ctx->ga.NumReplace = (int) ceil(ctx->ga.PopSize * 0.1);
if ( ctx->ga.NumReplace > ctx->ga.PopSize)
PGAError(ctx, "PGASetUp: NumReplace > PopSize",
PGA_FATAL, PGA_VOID, NULL);
if ( ctx->ga.CrossoverType == PGA_UNINITIALIZED_INT)
ctx->ga.CrossoverType = PGA_CROSSOVER_TWOPT;
if (ctx->ga.CrossoverType == PGA_CROSSOVER_TWOPT &&
ctx->ga.StringLen == 2)
PGAError(ctx, "PGASetUp: Invalid Crossover type for string of length "
"2", PGA_FATAL, PGA_INT, (void *) &ctx->ga.CrossoverType);
if ( ctx->ga.SelectType == PGA_UNINITIALIZED_INT)
ctx->ga.SelectType = PGA_SELECT_TOURNAMENT;
if ( ctx->ga.FitnessType == PGA_UNINITIALIZED_INT)
ctx->ga.FitnessType = PGA_FITNESS_RAW;
if ( ctx->ga.FitnessMinType == PGA_UNINITIALIZED_INT)
ctx->ga.FitnessMinType = PGA_FITNESSMIN_CMAX;
if ( ctx->ga.MutateOnlyNoCross == PGA_UNINITIALIZED_INT)
ctx->ga.MutateOnlyNoCross = PGA_TRUE;
if ( ctx->ga.MutationProb == PGA_UNINITIALIZED_DOUBLE)
ctx->ga.MutationProb = 1. / ctx->ga.StringLen;
if ( ctx->ga.MutationType == PGA_UNINITIALIZED_INT) {
switch (ctx->ga.datatype) {
case PGA_DATATYPE_BINARY:
case PGA_DATATYPE_CHARACTER:
case PGA_DATATYPE_USER:
/* leave PGA_UNINITIALIZED_INT for these data types */
break;
case PGA_DATATYPE_REAL:
ctx->ga.MutationType = PGA_MUTATION_GAUSSIAN;
break;
case PGA_DATATYPE_INTEGER:
switch (ctx->init.IntegerType) {
case PGA_UNINITIALIZED_INT:
case PGA_IINIT_PERMUTE:
ctx->ga.MutationType = PGA_MUTATION_PERMUTE;
break;
case PGA_IINIT_RANGE:
ctx->ga.MutationType = PGA_MUTATION_RANGE;
break;
}
break;
default:
PGAError( ctx, "PGASetup: Invalid value of ctx->ga.datatype:",
PGA_FATAL, PGA_INT, (void *) &(ctx->ga.datatype) );
}
}
if (ctx->ga.MutateRealValue == PGA_UNINITIALIZED_DOUBLE) {
switch (ctx->ga.MutationType) {
case PGA_MUTATION_GAUSSIAN:
ctx->ga.MutateRealValue = 0.1;
break;
case PGA_MUTATION_UNIFORM:
ctx->ga.MutateRealValue = 0.1;
break;
case PGA_MUTATION_CONSTANT:
ctx->ga.MutateRealValue = 0.01;
break;
case PGA_MUTATION_RANGE:
default:
ctx->ga.MutateRealValue = 0.0;
}
}
if ( ctx->ga.MutateIntegerValue == PGA_UNINITIALIZED_INT)
ctx->ga.MutateIntegerValue = 1;
if ( ctx->ga.MutateBoundedFlag == PGA_UNINITIALIZED_INT)
ctx->ga.MutateBoundedFlag = PGA_FALSE;
if ( ctx->ga.NoDuplicates == PGA_UNINITIALIZED_INT)
ctx->ga.NoDuplicates = PGA_FALSE;
if ( ctx->ga.NoDuplicates && ((ctx->ga.StoppingRule & PGA_STOP_TOOSIMILAR)
== PGA_STOP_TOOSIMILAR))
PGAError(ctx, "PGASetUp: No Duplicates inconsistent with Stopping "
"Rule:", PGA_FATAL, PGA_INT, (void *) &ctx->ga.StoppingRule);
if ( ctx->ga.CrossoverProb == PGA_UNINITIALIZED_DOUBLE)
ctx->ga.CrossoverProb = 0.85;
if ( ctx->ga.UniformCrossProb == PGA_UNINITIALIZED_DOUBLE)
ctx->ga.UniformCrossProb = 0.6;
if ( ctx->ga.PTournamentProb == PGA_UNINITIALIZED_DOUBLE)
ctx->ga.PTournamentProb = 0.6;
if ( ctx->ga.FitnessRankMax == PGA_UNINITIALIZED_DOUBLE)
ctx->ga.FitnessRankMax = 1.2;
if ( ctx->ga.FitnessCmaxValue == PGA_UNINITIALIZED_DOUBLE)
ctx->ga.FitnessCmaxValue = 1.01;
if ( ctx->ga.PopReplace == PGA_UNINITIALIZED_INT)
ctx->ga.PopReplace = PGA_POPREPL_BEST;
if ( ctx->ga.restart == PGA_UNINITIALIZED_INT)
ctx->ga.restart = PGA_FALSE;
if ( ctx->ga.restartFreq == PGA_UNINITIALIZED_INT)
ctx->ga.restartFreq = 50;
if ( ctx->ga.restartAlleleProb == PGA_UNINITIALIZED_DOUBLE)
ctx->ga.restartAlleleProb = 0.5;
/* ops */
/* If no user supplied "done" function, use the built in one.
* No need to check EndOfGen; they only get called if they
* are defined.
*/
if (((void *)ctx->cops.StopCond == (void *)PGADone) ||
((void *)ctx->fops.StopCond == (void *)PGADone))
PGAError( ctx,
"PGASetUp: Using PGADone as the user stopping condition will"
" result in an infinite loop!", PGA_FATAL, PGA_VOID, NULL);
switch (ctx->ga.datatype) {
case PGA_DATATYPE_BINARY:
CreateString = PGABinaryCreateString;
BuildDatatype = PGABinaryBuildDatatype;
Mutation = PGABinaryMutation;
switch (ctx->ga.CrossoverType) {
case PGA_CROSSOVER_ONEPT:
Crossover = PGABinaryOneptCrossover;
break;
case PGA_CROSSOVER_TWOPT:
Crossover = PGABinaryTwoptCrossover;
break;
case PGA_CROSSOVER_UNIFORM:
Crossover = PGABinaryUniformCrossover;
break;
}
PrintString = PGABinaryPrintString;
CopyString = PGABinaryCopyString;
Duplicate = PGABinaryDuplicate;
InitString = PGABinaryInitString;
break;
case PGA_DATATYPE_INTEGER:
CreateString = PGAIntegerCreateString;
BuildDatatype = PGAIntegerBuildDatatype;
Mutation = PGAIntegerMutation;
switch (ctx->ga.CrossoverType) {
case PGA_CROSSOVER_ONEPT:
Crossover = PGAIntegerOneptCrossover;
break;
case PGA_CROSSOVER_TWOPT:
Crossover = PGAIntegerTwoptCrossover;
break;
case PGA_CROSSOVER_UNIFORM:
Crossover = PGAIntegerUniformCrossover;
break;
}
PrintString = PGAIntegerPrintString;
CopyString = PGAIntegerCopyString;
Duplicate = PGAIntegerDuplicate;
InitString = PGAIntegerInitString;
break;
case PGA_DATATYPE_REAL:
CreateString = PGARealCreateString;
BuildDatatype = PGARealBuildDatatype;
Mutation = PGARealMutation;
switch (ctx->ga.CrossoverType) {
case PGA_CROSSOVER_ONEPT:
Crossover = PGARealOneptCrossover;
break;
case PGA_CROSSOVER_TWOPT:
Crossover = PGARealTwoptCrossover;
break;
case PGA_CROSSOVER_UNIFORM:
Crossover = PGARealUniformCrossover;
break;
}
PrintString = PGARealPrintString;
CopyString = PGARealCopyString;
Duplicate = PGARealDuplicate;
InitString = PGARealInitString;
break;
case PGA_DATATYPE_CHARACTER:
CreateString = PGACharacterCreateString;
BuildDatatype = PGACharacterBuildDatatype;
Mutation = PGACharacterMutation;
switch (ctx->ga.CrossoverType) {
case PGA_CROSSOVER_ONEPT:
Crossover = PGACharacterOneptCrossover;
break;
case PGA_CROSSOVER_TWOPT:
Crossover = PGACharacterTwoptCrossover;
break;
case PGA_CROSSOVER_UNIFORM:
Crossover = PGACharacterUniformCrossover;
break;
}
PrintString = PGACharacterPrintString;
CopyString = PGACharacterCopyString;
Duplicate = PGACharacterDuplicate;
InitString = PGACharacterInitString;
break;
case PGA_DATATYPE_USER:
if (ctx->cops.CreateString == NULL)
PGAError( ctx,
"PGASetUp: User datatype needs CreateString function:",
PGA_WARNING, PGA_INT, (void *) &err );
if (ctx->cops.Mutation == NULL)
PGAError( ctx,
"PGASetUp: User datatype needs Mutation function:",
PGA_WARNING, PGA_INT, (void *) &err );
if (ctx->cops.Crossover == NULL)
PGAError( ctx,
"PGASetUp: User datatype needs Crossover function:",
PGA_WARNING, PGA_INT, (void *) &err );
if (ctx->cops.PrintString == NULL)
PGAError( ctx,
"PGASetUp: User datatype needs PrintString function:",
PGA_WARNING, PGA_INT, (void *) &err );
if (ctx->cops.Duplicate == NULL)
PGAError( ctx,
"PGASetUp: User datatype needs Duplicate function:",
PGA_WARNING, PGA_INT, (void *) &err );
if (ctx->cops.CopyString == NULL)
PGAError( ctx,
"PGASetUp: User datatype needs CopyString function:",
PGA_WARNING, PGA_INT, (void *) &err );
if (ctx->cops.BuildDatatype == NULL)
PGAError(ctx,
"PGASetUp: User datatype needs BuildDatatype "
"function:", PGA_FATAL, PGA_INT, (void *) &err );
break;
}
if ((ctx->cops.Mutation == NULL) && (ctx->fops.Mutation == NULL))
ctx->cops.Mutation = Mutation;
if ((ctx->cops.Crossover == NULL) && (ctx->fops.Crossover == NULL))
ctx->cops.Crossover = Crossover;
if ((ctx->cops.PrintString == NULL) && (ctx->fops.PrintString == NULL))
ctx->cops.PrintString = PrintString;
if ((ctx->cops.Duplicate == NULL) && (ctx->fops.Duplicate == NULL))
ctx->cops.Duplicate = Duplicate;
if ((ctx->cops.InitString == NULL) && (ctx->fops.InitString == NULL))
ctx->cops.InitString = InitString;
if (ctx->cops.CreateString == NULL)
ctx->cops.CreateString = CreateString;
if (ctx->cops.CopyString == NULL)
ctx->cops.CopyString = CopyString;
if (ctx->cops.BuildDatatype == NULL)
ctx->cops.BuildDatatype = BuildDatatype;
/* par */
if ( ctx->par.NumIslands == PGA_UNINITIALIZED_INT)
ctx->par.NumIslands = 1;
if ( ctx->par.NumDemes == PGA_UNINITIALIZED_INT)
ctx->par.NumDemes = 1;
if ( ctx->par.DefaultComm == NULL )
ctx->par.DefaultComm = MPI_COMM_WORLD;
/* rep */
if ( ctx->rep.PrintFreq == PGA_UNINITIALIZED_INT)
ctx->rep.PrintFreq = 10;
/* sys */
/* no more sets necessary here. */
/* debug */
/* init */
if ( ctx->init.RandomInit == PGA_UNINITIALIZED_INT)
ctx->init.RandomInit = PGA_TRUE;
if ( ctx->init.BinaryProbability == PGA_UNINITIALIZED_DOUBLE)
ctx->init.BinaryProbability = 0.5;
if ( ctx->init.RealType == PGA_UNINITIALIZED_INT)
ctx->init.RealType = PGA_RINIT_RANGE;
if ( ctx->init.IntegerType == PGA_UNINITIALIZED_INT)
ctx->init.IntegerType = PGA_IINIT_PERMUTE;
if ( ctx->init.CharacterType == PGA_UNINITIALIZED_INT)
ctx->init.CharacterType = PGA_CINIT_LOWER;
switch (ctx->ga.datatype)
{
case PGA_DATATYPE_INTEGER:
for (i = 0; i < ctx->ga.StringLen; i++)
{
if (ctx->init.IntegerMin[i] == PGA_UNINITIALIZED_INT)
ctx->init.IntegerMin[i] = 0;
if (ctx->init.IntegerMax[i] == PGA_UNINITIALIZED_INT)
ctx->init.IntegerMax[i] = ctx->ga.StringLen - 1;
}
break;
case PGA_DATATYPE_REAL:
for (i = 0; i < ctx->ga.StringLen; i++)
{
if (ctx->init.RealMin[i] == PGA_UNINITIALIZED_DOUBLE)
ctx->init.RealMin[i] = 0.;
if (ctx->init.RealMax[i] == PGA_UNINITIALIZED_DOUBLE)
ctx->init.RealMax[i] = 1.;
}
break;
}
/* If a seed was not specified, get one from a time of day call */
if ( ctx->init.RandomSeed == PGA_UNINITIALIZED_INT)
ctx->init.RandomSeed = (int)time(NULL);
/* seed random number generator with this process' unique seed */
ctx->init.RandomSeed += PGAGetRank(ctx, MPI_COMM_WORLD);
PGARandom01( ctx, ctx->init.RandomSeed );
ctx->ga.selected = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
if (ctx->ga.selected == NULL)
PGAError(ctx, "PGASetUp: No room to allocate ctx->ga.selected",
PGA_FATAL, PGA_VOID, NULL);
ctx->ga.sorted = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
if (ctx->ga.sorted == NULL)
PGAError(ctx, "PGASetUp: No room to allocate ctx->ga.sorted",
PGA_FATAL, PGA_VOID, NULL);
ctx->scratch.intscratch = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
if (ctx->scratch.intscratch == NULL)
PGAError(ctx, "PGASetUp: No room to allocate ctx->scratch.intscratch",
PGA_FATAL, PGA_VOID, NULL);
ctx->scratch.dblscratch = (double *)malloc(sizeof(double) * ctx->ga.PopSize);
if (ctx->scratch.dblscratch == NULL)
PGAError(ctx, "PGASetUp: No room to allocate ctx->scratch.dblscratch",
PGA_FATAL, PGA_VOID, NULL);
PGACreatePop ( ctx , PGA_OLDPOP );
PGACreatePop ( ctx , PGA_NEWPOP );
ctx->rep.starttime = time(NULL);
PGADebugExited("PGASetUp");
}