/*!
 *  \brief Construct a GA Generational evolver.
 *  \param inEvalOp Evaluation operator.
 *  \param inInitSize Number of bits in the GA bit strings.
 */
Beagle::MPI::GA::EvolverBitString::EvolverBitString(MPI::EvaluationOp::Handle inEvalOp, unsigned int inInitSize)
    : Beagle::MPI::Evolver(inEvalOp)
{
    addOperator(inEvalOp);
    addOperator(new Beagle::GA::InitBitStrOp(inInitSize));
    addOperator(new Beagle::GA::CrossoverOnePointBitStrOp);
    addOperator(new Beagle::GA::CrossoverTwoPointsBitStrOp);
    addOperator(new Beagle::GA::CrossoverUniformBitStrOp);
    addOperator(new Beagle::GA::MutationFlipBitStrOp);

    addBootStrapOp("IfThenElseOp");
    IfThenElseOp::Handle lITE = castHandleT<IfThenElseOp>(getBootStrapSet().back());
    lITE->setConditionTag("ms.restart.file");
    lITE->setConditionValue("");
    lITE->insertPositiveOp("GA-InitBitStrOp", getOperatorMap());
    lITE->insertPositiveOp(inEvalOp->getName(), getOperatorMap());
    lITE->insertPositiveOp("StatsCalcFitnessSimpleOp", getOperatorMap());
    lITE->insertNegativeOp("MilestoneReadOp", getOperatorMap());
    addBootStrapOp("TermMaxGenOp");
    addBootStrapOp("MilestoneWriteOp");

    addMainLoopOp("SelectTournamentOp");
    addMainLoopOp("GA-CrossoverOnePointBitStrOp");
    addMainLoopOp("GA-MutationFlipBitStrOp");
    addMainLoopOp(inEvalOp->getName());
    addMainLoopOp("MigrationRandomRingOp");
    addMainLoopOp("StatsCalcFitnessSimpleOp");
    addMainLoopOp("TermMaxGenOp");
    addMainLoopOp("MilestoneWriteOp");
}
/*!
 *  \brief Construct a GA Generational evolver.
 *  \param inEvalOp Evaluation operator.
 *  \param inInitSize Size of the GA bit strings.
 *  \deprecated Use EvolverBitString(EvaluationOp::Handle,unsigned int) constructor instead.
 *  \throw Beagle::RunTimeException If init size vector has more than one value.
 */
Beagle::MPI::GA::EvolverBitString::EvolverBitString(EvaluationOp::Handle inEvalOp, UIntArray inInitSize) : Beagle::MPI::Evolver(inEvalOp)
{
    addOperator(inEvalOp);
    if(inInitSize.size()==0) addOperator(new Beagle::GA::InitBitStrOp(0));
    else if(inInitSize.size()==1) addOperator(new Beagle::GA::InitBitStrOp(inInitSize[0]));
    else {
        std::ostringstream lOSS;
        lOSS << "Initialization of bit string individuals with more than one bit string ";
        lOSS << "is no more valid. You should use individuals made of one bit string, or ";
        lOSS << "define your own bit string initialization operator.";
        throw Beagle_RunTimeExceptionM(lOSS.str());
    }
    addOperator(new Beagle::GA::CrossoverOnePointBitStrOp);
    addOperator(new Beagle::GA::CrossoverTwoPointsBitStrOp);
    addOperator(new Beagle::GA::CrossoverUniformBitStrOp);
    addOperator(new Beagle::GA::MutationFlipBitStrOp);

    addBootStrapOp("IfThenElseOp");
    IfThenElseOp::Handle lITE = castHandleT<IfThenElseOp>(getBootStrapSet().back());
    lITE->setConditionTag("ms.restart.file");
    lITE->setConditionValue("");
    lITE->insertPositiveOp("GA-InitBitStrOp", getOperatorMap());
    lITE->insertPositiveOp(inEvalOp->getName(), getOperatorMap());
    lITE->insertPositiveOp("StatsCalcFitnessSimpleOp", getOperatorMap());
    lITE->insertNegativeOp("MilestoneReadOp", getOperatorMap());
    addBootStrapOp("TermMaxGenOp");
    addBootStrapOp("MilestoneWriteOp");

    addMainLoopOp("SelectTournamentOp");
    addMainLoopOp("GA-CrossoverOnePointBitStrOp");
    addMainLoopOp("GA-MutationFlipBitStrOp");
    addMainLoopOp(inEvalOp->getName());
    addMainLoopOp("MigrationRandomRingOp");
    addMainLoopOp("StatsCalcFitnessSimpleOp");
    addMainLoopOp("TermMaxGenOp");
    addMainLoopOp("MilestoneWriteOp");
}