NEAT::GeneticPopulation * ImageExperiment::createInitialPopulation(
        int populationSize)
    {
        cout << "Creating Image Experiment initial population..." << endl;
        GeneticPopulation *population = new GeneticPopulation();
        vector<GeneticNodeGene> genes;

        genes.push_back(GeneticNodeGene("Bias", "NetworkSensor",     0, false));
        genes.push_back(GeneticNodeGene("X",    "NetworkSensor",     0, false));
        genes.push_back(GeneticNodeGene("Y",    "NetworkSensor",     0, false));
        //genes.push_back(GeneticNodeGene("Gauss","HiddenNode",      0.5, false, ACTIVATION_FUNCTION_GAUSSIAN));
        genes.push_back(GeneticNodeGene("XOUT", "NetworkOutputNode", 1, false, ACTIVATION_FUNCTION_SIGMOID));
        genes.push_back(GeneticNodeGene("YOUT", "NetworkOutputNode", 1, false, ACTIVATION_FUNCTION_SIGMOID));

        for (int a=0;a<populationSize;a++)
        {
            shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes,true,1.0));

            for (int b=0;b<0;b++)
            {
                individual->testMutate();
            }

            population->addIndividual(individual);
        }

        cout << "Finished creating population\n";
        return population;
    }
NEAT::GeneticPopulation* AtariNoGeomNoiseExperiment::createInitialPopulation(int populationSize) {
    GeneticPopulation *population = new GeneticPopulation();
    vector<GeneticNodeGene> genes;

    for (int y=0; y<substrate_height; y++) {
        for (int x=0; x<substrate_width; x++) {
            Node node(x, y, 0);
            genes.push_back(GeneticNodeGene(nameLookup[node],"NetworkSensor",0,false));
        }
    }

    // Output Layer
    for (int i=0; i<numActions; i++) {
        Node node(i, 0, 2);
        genes.push_back(GeneticNodeGene(nameLookup[node],"NetworkOutputNode",1,false,
                                        ACTIVATION_FUNCTION_SIGMOID));
    }

    // Bias node
    genes.push_back(GeneticNodeGene("Bias","NetworkSensor",0,false));

    for (int a=0; a<populationSize; a++) {
        shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes,true,1.0));
        for (int b=0; b<10; b++) {
            individual->testMutate();
        }
        population->addIndividual(individual);
    }

    cout << "Finished creating population\n";
    return population;
}
    NEAT::GeneticPopulation* XorExperiment::createInitialPopulation(int populationSize)
    {
        //Make stdout unbuffered.  cliche needs that.
        //setvbuf (stdout, NULL, _IONBF, 0);

        GeneticPopulation *population = new GeneticPopulation();
        vector<GeneticNodeGene> genes;

        genes.push_back(GeneticNodeGene("Bias","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("X1","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("X2","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Output","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));

        for (int a=0;a<populationSize;a++)
        {
            shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes,true,1.0));

            for (int b=0;b<0;b++)
            {
                individual->testMutate();
            }

            population->addIndividual(individual);
        }

        cout << "Finished creating population\n";
        return population;
    }
    NEAT::GeneticPopulation* AtariPixelExperiment::createInitialPopulation(int populationSize) {
        GeneticPopulation *population = new GeneticPopulation();
        vector<GeneticNodeGene> genes;

        // Input Nodes
        genes.push_back(GeneticNodeGene("Bias","NetworkSensor",0,false)); // TODO: Check if this helps or not
        genes.push_back(GeneticNodeGene("X1","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Y1","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("X2","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Y2","NetworkSensor",0,false));

        // Output Nodes
        for (int i=0; i<numColors; ++i) {
            genes.push_back(GeneticNodeGene("Output_Input" + boost::lexical_cast<std::string>(i) +
                                            "_Processing",
                                            "NetworkOutputNode",1,false,
                                            ACTIVATION_FUNCTION_SIGMOID));
        }
        genes.push_back(GeneticNodeGene("Output_Processing_Output","NetworkOutputNode",1,false,
                                        ACTIVATION_FUNCTION_SIGMOID));

        for (int a=0; a<populationSize; a++) {
            shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes,true,1.0));
            for (int b=0;b<10;b++) {
                individual->testMutate();
            }
            population->addIndividual(individual);
        }

        cout << "Finished creating population\n";
        return population;
    }
  GeneticPopulation* ModNeatExperiment7::createInitialPopulation(int populationSize) {
  	GeneticPopulation *population = new GeneticPopulation();
  	vector<GeneticNodeGene> genes;

  	// Set-up the CCPPN which encodes the substrate weights

  	////// CCPPN encoding a 3 layered sandwich substrate's weights
  	// Configuration of the CCPPN's Input layer
  	genes.push_back(GeneticNodeGene("X1", "NetworkSensor", 0, false)); // position on the X axis in the substrate's link start layers
  	genes.push_back(GeneticNodeGene("Y1", "NetworkSensor", 0, false)); // position on the Y axis in the substrate's link start layers
  	genes.push_back(GeneticNodeGene("Z1", "NetworkSensor", 0, false)); // position on the Z axis in the substrate's link start layers

  	genes.push_back(GeneticNodeGene("X2", "NetworkSensor", 0, false)); // position on the X axis in the substrate's link end layers
  	genes.push_back(GeneticNodeGene("Y2", "NetworkSensor", 0, false)); // position on the Y axis in the substrate's link end layers
  	genes.push_back(GeneticNodeGene("Z2", "NetworkSensor", 0, false)); // position on the Z axis in the substrate's link end layers
    
    #ifdef USE_BIASES
  	 genes.push_back(GeneticNodeGene("Bias", "NetworkSensor", 0, false)); // bias for the CPPN
    #endif // USE_BIASES

    #ifdef USE_DELTAS
  	 genes.push_back(GeneticNodeGene("DeltaX", "NetworkSensor", 0, false)); // offset between the two nodes on the X axis
  	 genes.push_back(GeneticNodeGene("DeltaY", "NetworkSensor", 0, false)); // offset between the two nodes on the Y axis
  	 genes.push_back(GeneticNodeGene("DeltaZ", "NetworkSensor", 0, false)); // offset between the two nodes on the Z axis
    #endif // USE_DELTAS

    #ifdef MODULAR_HNEAT
    	screen << "Laying out a heterogeneous controller CPPN" << endl;
    	genes.push_back(GeneticNodeGene("T1", "NetworkSensor", 0, false)); // position in the body
    	genes.push_back(GeneticNodeGene("T2", "NetworkSensor", 0, false)); // offset between the two nodes on the Z axis
      #ifdef USE_DELTAS
  	   genes.push_back(GeneticNodeGene("DeltaT", "NetworkSensor", 0, false)); // offset between the two nodes on the Z axis
      #endif  // USE_DELTAS
    #endif  // MODULAR_HNEAT

    #ifndef MODULAR_HNEAT
  	 screen << "Laying out a homogeneous controller CPPN" << endl;
    #endif

  	// Configuration of the CCPPN's Output layer
  	genes.push_back(GeneticNodeGene("Output", "NetworkOutputNode", 1, false, ACTIVATION_FUNCTION_SIGMOID)); // weight for link between layers A and B

    #ifdef USE_BIASES
  	 genes.push_back(GeneticNodeGene("Bias_out", "NetworkOutputNode", 1, false, ACTIVATION_FUNCTION_SIGMOID)); // bias for the second sandwich layer
    #endif // USE_BIASES

  	// Create the initial population
  	for (int a = 0; a < populationSize; a++) {
  		shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes, true, 1.0));

  		for (int b = 0; b < 0; b++) {
  			individual->testMutate();
  		}

  		population->addIndividual(individual);
  	}

  	screen << "Finished creating population\n";

    // store population and individual size
    popSize = population->getIndividualCount();
    // screen << "\n individual count: " << popSize << "\n";

  	return population;
  }
    bool GeneticIndividual::mutateAddNode(int fromNodeID,int toNodeID)
    {
        if (fromNodeID>=0&&fromNodeID==toNodeID)
        {
            throw CREATE_LOCATEDEXCEPTION_INFO("Error: Tried to create a node within a loop connection");
        }

        GeneticLinkGene *randomLink;

        bool allowAddNodeToRecurrentConnection
            = (
            Globals::getSingleton()->getParameterValue("AllowAddNodeToRecurrentConnection")>
            Globals::getSingleton()->getRandom().getRandomDouble()
            );

        int chances=0;
        //cout << __FILE__ << ": Trying to add a node\n";


        int tmpFromNodeID,tmpToNodeID;

		int randomLinkIndex;

        while (true)
        {
            chances++;
			//cout << "Trying to add node...\n";
            if (chances>=200000)
            {
                //cout << "Blown second chance limit.  Giving up\n";
                return false;
            }
            if (chances>=100000)
            {
				randomLinkIndex = (randomLinkIndex+1)%links.size();
				//cout << "Blown chance limit.  incrementing over all possible links\n";
            }
			else
			{
				//This loop ensures that you don't get a recurrent or loop connection when you add complexity.
				randomLinkIndex = Globals::getSingleton()->getRandom().getRandomInt(int(links.size()));
			}

            if (fromNodeID>=0)
            {
                randomLink = getLink(fromNodeID,toNodeID);

                tmpFromNodeID = fromNodeID;
                tmpToNodeID = toNodeID;
            }
            else
            {
                randomLink = &links[randomLinkIndex];

                tmpFromNodeID = randomLink->getFromNodeID();
                tmpToNodeID = randomLink->getToNodeID();
				
				//cout << "IDs: " << tmpFromNodeID << " , " << tmpToNodeID << endl;
            }

            if (tmpFromNodeID==tmpToNodeID)
            {
                //loop link, try again
				//cout << "Loop link, ignore\n";
                continue;
            }

            GeneticNodeGene *fromNode=NULL,*toNode=NULL;

            for (int a=0;a<(int)nodes.size();a++)
            {
                //This loop goes through and gets the sum of the two nodes' drawing positions for averaging.
                if (nodes[a].getID()==tmpFromNodeID)
                    fromNode = &nodes[a];

                if (nodes[a].getID()==tmpToNodeID)
                    toNode = &nodes[a];
            }

            if (!fromNode->isEnabled() || !toNode->isEnabled())
            {
                //Disabled nodes, don't add anything.
				//cout << "One of the nodes is disabled...\n";
                continue;
            }

            if (fromNode->getDrawingPosition()>=toNode->getDrawingPosition())
            {
                //Recurrent connection.
				//cout << "Recurrent connection.  Ignoring\n";
                if (!allowAddNodeToRecurrentConnection)
                    continue;
            }

            if(fromNode->isTopologyFrozen() && toNode->isTopologyFrozen())
            {
				//cout << "Topology frozen on both nodes.  Ignoring\n";
                //Don't add links between two frozen topology nodes
                continue;
            }

            double newPosition = (fromNode->getDrawingPosition()+toNode->getDrawingPosition())/2.0;

            randomLink->setAge(0);
            randomLink->setWeight(randomLink->getWeight()/2.0);

            bool randomActivation=false;

            if (Globals::getSingleton()->getParameterValue("ExtraActivationFunctions")>Globals::getSingleton()->getRandom().getRandomDouble())
                randomActivation=true;

            GeneticNodeGene newNode = GeneticNodeGene("","HiddenNode",newPosition,randomActivation);

            GeneticLinkGene sourceLink = GeneticLinkGene(randomLink->getFromNodeID(),newNode.getID(),1.0);
            GeneticLinkGene destLink = GeneticLinkGene(newNode.getID(),randomLink->getToNodeID(),randomLink->getWeight()/2.0);

            addNode(newNode);
            addLink(sourceLink);
            addLink(destLink);
            if (Globals::getSingleton()->getParameterValue("AddBiasToHiddenNodes")>Globals::getSingleton()->getRandom().getRandomDouble())
            {
                int biasNodeID=-1;
                for (int a=0;a<(int)nodes.size();a++)
                {
                    if (nodes[a].getName()==string("Bias"))
                    {
                        biasNodeID=(int)a;
                        break;
                    }
                }

                if (biasNodeID==-1)
                {
                    throw CREATE_LOCATEDEXCEPTION_INFO("Error, tried to add link from bias node when biad node didn't exist!");
                }

                if (randomLink->getFromNodeID()==biasNodeID)
                {
                    //Oops, the from link was already the bias node, don't bother
                }
                else
                {
                    GeneticLinkGene biasLink = GeneticLinkGene(biasNodeID,newNode.getID(),0.0);
                    addLink(biasLink);
                }
            }
            return true;
        }
    }
    NEAT::GeneticPopulation* AtariFTNeatExperiment::createInitialPopulation(int populationSize) {
        GeneticPopulation *population = new GeneticPopulation();
        vector<GeneticNodeGene> genes;
        vector<GeneticLinkGene> links;

        clock_t start = clock();
        vector<int> inputNodeIndexes;
        vector<int> hiddenNodeIndexes;
        vector<int> outputNodeIndexes;
        int nodeCounter = 0;
        // One input layer for each object class and an extra for the self object
        for (int i=0; i<=numObjClasses; ++i) {
            for (int y=0; y<substrate_height; y++) {
                for (int x=0; x<substrate_width; x++) {
                    int xmod = substrate_width*i+x; 
                    Node node(xmod, y, 0);
                    genes.push_back(GeneticNodeGene(nameLookup[node],"NetworkSensor",0,false));
                    inputNodeIndexes.push_back(nodeCounter);
                    nodeCounter++;
                }
            }
        }

        // Processing Layer
        for (int y=0; y<substrate_height; y++) {
            for (int x=0; x<substrate_width; x++) {
                Node node(x, y, 1);
                genes.push_back(GeneticNodeGene(nameLookup[node],"NetworkOutputNode",1,false,
                                            ACTIVATION_FUNCTION_SIGMOID));
                hiddenNodeIndexes.push_back(nodeCounter);
                nodeCounter++;
            }
        }

        // Output Layer
        for (int i=0; i<numActions; i++) {
            Node node(i, 0, 2);
            genes.push_back(GeneticNodeGene(nameLookup[node],"NetworkOutputNode",1,false,
                                            ACTIVATION_FUNCTION_SIGMOID));
            outputNodeIndexes.push_back(nodeCounter);
            nodeCounter++;
        }

        // Bias node
        // genes.push_back(GeneticNodeGene("Bias","NetworkSensor",0,false));
        // inputNodeIndexes.push_back(nodeCounter);
        // nodeCounter++;

        clock_t end = clock();
        cout << "Created " << nodeCounter << " nodes in " << float(end-start)/CLOCKS_PER_SEC << " seconds." << endl;

        start = clock();
        // [Links] Input --> Processing 
        for (int z=0; z<inputNodeIndexes.size(); z++) {
            for (int q=0; q<hiddenNodeIndexes.size(); q++) {
                int fromNodeIndex = inputNodeIndexes[z];
                int toNodeIndex   = hiddenNodeIndexes[q];
                links.push_back(GeneticLinkGene(genes[fromNodeIndex].getID(),genes[toNodeIndex].getID()));
            }
        }

        // [Links] Processing --> Output 
        for (int z=0; z<hiddenNodeIndexes.size(); z++) {
            for (int q=0; q<outputNodeIndexes.size(); q++) {
                int fromNodeIndex = hiddenNodeIndexes[z];
                int toNodeIndex   = outputNodeIndexes[q];
                links.push_back(GeneticLinkGene(genes[fromNodeIndex].getID(),genes[toNodeIndex].getID()));
            }
        }
        end = clock();
        cout << "Created " << links.size() << " links in " << float(end-start)/CLOCKS_PER_SEC << " seconds." << endl;

        for (int a=0; a<populationSize; a++) {
            shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes,links));
            for (int b=0;b<10;b++) {
                individual->testMutate();
            }
            population->addIndividual(individual);
        }

        cout << "Finished creating population\n";
        return population;
    }
    NEAT::GeneticPopulation* CoCheckersExperiment::createInitialPopulation(int populationSize)
    {
        GeneticPopulation *population = new GeneticPopulation(
            shared_ptr<CoCheckersExperiment>((CoCheckersExperiment*)this->clone())
        );
        vector<GeneticNodeGene> genes;

        genes.push_back(GeneticNodeGene("Bias","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("X1","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Y1","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("X2","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Y2","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("DeltaX","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("DeltaY","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Output_ab","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
        genes.push_back(GeneticNodeGene("Output_bc","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
        genes.push_back(GeneticNodeGene("Output_ac","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
#if CHECKERS_EXPERIMENT_ENABLE_BIASES
        genes.push_back(GeneticNodeGene("Bias_b","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
        genes.push_back(GeneticNodeGene("Bias_c","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
#endif

        for (int a=0;a<populationSize;a++)
        {
            shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes,true,1.0));

            for (int b=0;b<0;b++)
            {
                individual->testMutate();
            }

            population->addIndividual(individual);
        }

        shared_ptr<NEAT::CoEvoGeneticGeneration> coEvoGeneration =
            static_pointer_cast<NEAT::CoEvoGeneticGeneration>(population->getGeneration());

        //Create the tests
        for (int a=0;a<(population->getIndividualCount()/10);a++)
        {
            shared_ptr<NEAT::GeneticIndividual> individual(new GeneticIndividual(genes,true,1.0));

            //This function clones the individual to make a test
            coEvoGeneration->addTest(individual);
        }

        coEvoGeneration->bootstrap();

        cout << "Finished creating population\n";
        return population;
    }