Ejemplo n.º 1
0
bool
  Layer3::deregisterIndividualCallBack (L_Data_CallBack * c, eibaddr_t src,
					eibaddr_t dest)
{
  unsigned i;
  for (i = 0; i < individual (); i++)
    if (individual[i].cb == c && individual[i].src == src
	&& individual[i].dest == dest)
      {
	individual[i] = individual[individual () - 1];
	individual.resize (individual () - 1);
	TRACEPRINTF (t, 3, this, "deregisterIndividual %08X = 1", c);
	for (i = 0; i < individual (); i++)
	  {
	    if (individual[i].dest == dest)
	      return 1;
	  }
	if (dest)
          for (i = 0; i < layer2 (); i++)
	    layer2[i].l2->removeAddress (dest);
	return 1;
      }
  TRACEPRINTF (t, 3, this, "deregisterIndividual %08X = 0", c);
  return 0;
}
Ejemplo n.º 2
0
// Calculate the population's diversity score.  The matrix is triangular and
// we don't have to calculate the diagonals.  This assumes that div(i,j) is
// the same as div(j,i) (for our purposes this will always be true, but it is
// possible for someone to override some of the individuals in the population
// and not others).
//   For now we keep twice as many diversity numbers as we need.  We need only
// n*(n-1)/2, but I can't seem to figure out an efficient way to map i,j to the
// reduced n*(n-1)/2 set (remember that the diagonals are always 0.0).
//   The diversity of the entire population is just the average of all the
// individual diversities.  So if every individual is completely different from
// all of the others, the population diversity is > 0.  If they are all the
// same, the diversity is 0.0.  We don't count the diagonals for the population
// diversity measure.  0 means minimal diversity means all the same.
void
GAPopulation::diversity(GABoolean flag) const {
  if(divved == gaTrue && flag != gaTrue) return;
  GAPopulation* This = (GAPopulation*)this;

  if(n > 1) {
    if(This->indDiv == 0) This->indDiv = new float[N*N];

    This->popDiv = 0.0;
    for(unsigned int i=0; i<n; i++){
      This->indDiv[i*n+i] = 0.0;
      for(unsigned int j=i+1; j<n; j++){
	This->indDiv[j*n+i] = This->indDiv[i*n+j] =
	  individual(i).compare(individual(j));
	This->popDiv += indDiv[i*n+j];
      }
    }
    This->popDiv /= n*(n-1)/2;
  }
  else {
    This->popDiv = 0.0;
  }

  This->divved = gaTrue;
}
    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;
    }
Ejemplo n.º 4
0
bool
  Layer3::registerIndividualCallBack (L_Data_CallBack * c,
				      Individual_Lock lock, eibaddr_t src,
				      eibaddr_t dest)
{
  unsigned i;
  TRACEPRINTF (t, 3, this, "registerIndividual %08X %d", c, lock);
  if (mode == 1)
    return 0;
  for (i = 0; i < individual (); i++)
    if (lock == Individual_Lock_Connection &&
	individual[i].src == src &&
	individual[i].lock == Individual_Lock_Connection)
      {
	TRACEPRINTF (t, 3, this, "registerIndividual locked %04X %04X",
		     individual[i].src, individual[i].dest);
	return 0;
      }

  for (i = 0; i < individual (); i++)
    {
      if (individual[i].dest == dest)
	break;
    }
  if (i == individual () && dest)
    if (!layer2->addAddress (dest))
      return 0;
  individual.resize (individual () + 1);
  individual[individual () - 1].cb = c;
  individual[individual () - 1].dest = dest;
  individual[individual () - 1].src = src;
  individual[individual () - 1].lock = lock;
  TRACEPRINTF (t, 3, this, "registerIndividual %08X = 1", c);
  return 1;
}
Ejemplo n.º 5
0
	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;
    }
Ejemplo n.º 6
0
    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;
    }
Ejemplo n.º 7
0
bool
Layer3::registerBusmonitor (L_Busmonitor_CallBack * c)
{
  TRACEPRINTF (t, 3, this, "registerBusmontior %08X", c);
  if (individual ())
    return 0;
  if (group ())
    return 0;
  if (broadcast ())
    return 0;
  if (mode == 0)
    {
      layer2->Close ();
      if (!layer2->enterBusmonitor ())
	{
	  layer2->Open ();
	  return 0;
	}
    }
  mode = 1;
  busmonitor.resize (busmonitor () + 1);
  busmonitor[busmonitor () - 1].cb = c;
  TRACEPRINTF (t, 3, this, "registerBusmontior %08X = 1", c);
  return 1;
}
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* 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;
    }
Ejemplo n.º 10
0
individual individualsFactory::createNeuralIndividual()
{
  return individual(
      new neuralIndividualStrategy(
          nn->getTopology(), distribution
      )
  );
}
Ejemplo n.º 11
0
individual individualsFactory::createIndividual()
{
  switch(individualStrategyId)
  {
    case neuralIndividual:
      return createNeuralIndividual();
    default:
      return individual(NULL);
  }
}
Ejemplo n.º 12
0
void MOGA::elitism()
{
	// Compute all rank and crowding.
	compute_ranking();

	// Erase all individuals that are in the bottom.
	population_.resize( num_individuals_, individual( this ) );

	// Re-Compute all rank and crowding.
	compute_ranking();
}
Ejemplo n.º 13
0
// Восстановление поколения по выходному вектору
ErrCode Crossover::get_Individuals_from_DataOut(Individuals& individuals, DataOut& dataOut)
{
	Individuals::iterator itIndividual;
	for (int i = 0; i < dataOut.nCrossedIndividual; ++i)
	{
		/*
		Strings individualExpressions;
		get_individualExpressions(individualExpressions, i * nParent);
		
		std::string expression;
		get_expression(expression, individualExpressions);
		*/
		Individual individual("", dataOut.c11s[i], dataOut.c01s[i], dataOut.ratings[i]);
		add_Individual_to_Individuals(individuals, individual, nMax_Individual_Out);
	}
	return 0;
}
Ejemplo n.º 14
0
Layer3::~Layer3 ()
{
  TRACEPRINTF (t, 3, this, "Close");
  Stop ();
  if (mode)
    layer2->leaveBusmonitor ();
  else
    layer2->Close ();
  while (vbusmonitor ())
    deregisterVBusmonitor (vbusmonitor[0].cb);
  while (group ())
    deregisterGroupCallBack (group[0].cb, group[0].dest);
  while (individual ())
    deregisterIndividualCallBack (individual[0].cb, individual[0].src,
				  individual[0].dest);
  delete layer2;
}
Ejemplo n.º 15
0
individual individualsFactory::createIndividual(individual *p1, individual *p2)
{
  individual offspring(NULL);

  switch(individualStrategyId)
  {
    case neuralIndividual:
      offspring = createNeuralIndividual();
      break;
    default:
      offspring = individual(NULL);
      break;
  }

  p1->cross(p2->getSolution(), &offspring);

  return offspring;
}
Ejemplo n.º 16
0
/**
 * Asexual reproduction:
 * 
 * I just randomly chose features of one or the other parent by a probabillity proportional
 * to the parents fitness function
 * 
 * The combination strategy is used in the make offspring method to create a child.
 */
individual individual::combine1(individual indiv){
	//individual child(indiv.getFeatureVector());
	std::vector<float> fv;
	std::vector<float> indivFV(indiv.getFeatureVector());
	
	std::uniform_real_distribution<> dint(0,1);
	
	float O1 = this->getObjectiveFunction();
	float O2 = indiv.getObjectiveFunction();
	
	float fittnessBias = O1>O2 ? 0.75 : 0.25;
	
	for(unsigned int i=0;i<ndim;i++){
		indivFV.at(i) = dint(this->rngEngine)<fittnessBias ? (this->featureVector).at(i) : (indiv.getFeatureVector()).at(i);
	}
	
	
	return individual(fv);
}
Ejemplo n.º 17
0
/**
 * Creates an individual from a splitted line that is taken from
 * a .dose file. If the iid and fid cannot be parsed they will be
 * set to '-'.
 *
 * @param splitted_line A line that has been splitted on ' '.
 *
 * @return The individual with all its doses that is represented
 *         by the line.
 */
static Individual
create_individual(const std::vector<std::string> &splitted_line)
{
    std::string header = splitted_line[ 0 ];
    unsigned int sepStart = header.find( "->" );
    
    std::string fid = "-";
    std::string iid = "-";
    if( sepStart != std::string::npos )
    {
        fid = header.substr( 0, sepStart );
        iid = header.substr( sepStart + 2, header.size( ) - sepStart );
    }

    Individual individual( fid, iid );
    for(unsigned int i = 2; i < splitted_line.size( ); i++) // Ignore iid->fid and 'DOSE'
    {
        float dose = strtod( splitted_line[ i ].c_str( ), NULL );
        individual.add_dose( fixed( dose ) );
    }
    
    return individual;
}
Ejemplo n.º 18
0
void
Layer3::Run (pth_sem_t * stop1)
{
  pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1);
  unsigned i;

  while (pth_event_status (stop) != PTH_STATUS_OCCURRED)
    {
      LPDU *l = layer2->Get_L_Data (stop);
      if (!l)
	continue;
      if (l->getType () == L_Busmonitor)
	{
	  L_Busmonitor_PDU *l1, *l2;
	  l1 = (L_Busmonitor_PDU *) l;

	  TRACEPRINTF (t, 3, this, "Recv %s", l1->Decode ()());
	  for (i = 0; i < busmonitor (); i++)
	    {
	      l2 = new L_Busmonitor_PDU (*l1);
	      busmonitor[i].cb->Get_L_Busmonitor (l2);
	    }
	  for (i = 0; i < vbusmonitor (); i++)
	    {
	      l2 = new L_Busmonitor_PDU (*l1);
	      vbusmonitor[i].cb->Get_L_Busmonitor (l2);
	    }
	}
      if (l->getType () == L_Data)
	{
	  L_Data_PDU *l1;
	  l1 = (L_Data_PDU *) l;
	  if (l1->repeated)
	    {
	      CArray d1 = l1->ToPacket ();
	      for (i = 0; i < ignore (); i++)
		if (d1 == ignore[i].data)
		  {
		    TRACEPRINTF (t, 3, this, "Repeated discareded");
		    goto wt;
		  }
	    }
	  l1->repeated = 1;
	  ignore.resize (ignore () + 1);
	  ignore[ignore () - 1].data = l1->ToPacket ();
	  ignore[ignore () - 1].end = getTime () + 1000000;
	  l1->repeated = 0;

	  if (l1->AddrType == IndividualAddress
	      && l1->dest == layer2->getDefaultAddr ())
	    l1->dest = 0;
	  TRACEPRINTF (t, 3, this, "Recv %s", l1->Decode ()());

	  if (l1->AddrType == GroupAddress && l1->dest == 0)
	    {
	      for (i = 0; i < broadcast (); i++)
		broadcast[i].cb->Get_L_Data (new L_Data_PDU (*l1));
	    }
	  if (l1->AddrType == GroupAddress && l1->dest != 0)
	    {
	      for (i = 0; i < group (); i++)
		if (group[i].dest == l1->dest || group[i].dest == 0)
		  group[i].cb->Get_L_Data (new L_Data_PDU (*l1));
	    }
	  if (l1->AddrType == IndividualAddress)
	    {
	      for (i = 0; i < individual (); i++)
		if (individual[i].dest == l1->dest
		    || individual[i].dest == 0)
		  if (individual[i].src == l1->source
		      || individual[i].src == 0)
		    individual[i].cb->Get_L_Data (new L_Data_PDU (*l1));
	    }
	}
    redel:
      for (i = 0; i < ignore (); i++)
	if (ignore[i].end < getTime ())
	  {
	    ignore.deletepart (i, 1);
	    goto redel;
	  }
    wt:
      delete l;

    }
  pth_event_free (stop, PTH_FREE_THIS);
}
Ejemplo n.º 19
0
  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;
  }
Ejemplo n.º 20
0
void
Layer3::Run (pth_sem_t * stop1)
{
  pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1);
  unsigned i;

  running = true;
  for (i = 0; i < layer2 (); i++)
    layer2[i].Start ();

  TRACEPRINTF (t, 3, this, "L3 started");
  while (pth_event_status (stop) != PTH_STATUS_OCCURRED)
    {
      pth_event_t bufev = pth_event (PTH_EVENT_SEM, &bufsem);
      pth_event_concat (bufev, stop, NULL);
      pth_wait (bufev);
      pth_event_isolate (bufev);

      if (pth_event_status (bufev) != PTH_STATUS_OCCURRED)
        {
          pth_event_free (bufev, PTH_FREE_THIS);
          continue;
        }
      pth_event_free (bufev, PTH_FREE_THIS);

      pth_sem_dec (&bufsem);
      LPDU *l = buf.get ();
      if (!l)
	continue;
      if (l->getType () == L_Busmonitor)
	{
	  L_Busmonitor_PDU *l1, *l2;
	  l1 = (L_Busmonitor_PDU *) l;

	  TRACEPRINTF (t, 3, this, "Recv %s", l1->Decode ()());
	  for (i = 0; i < busmonitor (); i++)
	    {
	      l2 = new L_Busmonitor_PDU (*l1);
	      busmonitor[i].cb->Send_L_Busmonitor (l2);
	    }
	  for (i = 0; i < vbusmonitor (); i++)
	    {
	      l2 = new L_Busmonitor_PDU (*l1);
	      vbusmonitor[i].cb->Send_L_Busmonitor (l2);
	    }
	}
      if (l->getType () == L_Data)
	{
	  L_Data_PDU *l1;
	  l1 = (L_Data_PDU *) l;
	  if (l1->repeated)
	    {
	      CArray d1 = l1->ToPacket ();
	      for (i = 0; i < ignore (); i++)
		if (d1 == ignore[i].data)
		  {
		    TRACEPRINTF (t, 3, this, "Repeated discareded");
		    goto wt;
		  }
	    }
	  l1->repeated = 1;
	  ignore.resize (ignore () + 1);
	  ignore[ignore () - 1].data = l1->ToPacket ();
	  ignore[ignore () - 1].end = getTime () + 1000000;
	  l1->repeated = 0;

	  if (l1->AddrType == IndividualAddress
	      && l1->dest == defaultAddr)
	    l1->dest = 0;
	  TRACEPRINTF (t, 3, this, "Recv %s", l1->Decode ()());

	  if (l1->AddrType == GroupAddress && l1->dest == 0)
	    {
	      for (i = 0; i < broadcast (); i++)
		broadcast[i].cb->Send_L_Data (new L_Data_PDU (*l1));
	    }
	  if (l1->AddrType == GroupAddress && l1->dest != 0)
	    {
	      for (i = 0; i < group (); i++)
                {
                  Group_Info &grp = group[i];
		  if (grp.dest == l1->dest || grp.dest == 0)
		    grp.cb->Send_L_Data (new L_Data_PDU (*l1));
                }
	    }
	  if (l1->AddrType == IndividualAddress)
	    {
	      for (i = 0; i < individual (); i++)
                {
                  Individual_Info &indiv = individual[i];
		  if (indiv.dest == l1->dest || indiv.dest == 0)
		    if (indiv.src == l1->source || indiv.src == 0)
		      indiv.cb->Send_L_Data (new L_Data_PDU (*l1));
	        }
	    }

          // finally, send to all (other(?)) L2 interfaces
          // TODO: filter by addresses
          send_L_Data(l1);
	}
      // ignore[] is ordered, any timed-out items are at the front
      for (i = 0; i < ignore (); i++)
	if (ignore[i].end >= getTime ())
          break;
      if (i)
        ignore.deletepart (0, i);
    wt:
      delete l;

    }
  TRACEPRINTF (t, 3, this, "L3 stopping");

  running = false;
  for (i = 0; i < layer2 (); i++)
    layer2[i].Stop ();

  pth_event_free (stop, PTH_FREE_THIS);
}
    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;
    }