void BasicProjectMedeaAgentObserver::pickRandomGenome()
{
		if(_wm->_genomesList.size() != 0)
		{
			int randomIndex = rand()%_wm->_genomesList.size();
			std::map<int, std::vector<double> >::iterator it = _wm->_genomesList.begin();
			while (randomIndex !=0 )
			{
				it ++;
				randomIndex --;
			}

			_wm->_currentGenome = (*it).second;
			if ( BasicProjectMedeaSharedData::gDynamicSigma == true )
			{
				mutateWithBouncingBounds(_wm->_sigmaList[(*it).first]);
			}
			else
			{
				mutateWithBouncingBounds(-1.00);
			}

			_wm->setNewGenomeStatus(true);
			gLogFile << "Info(" << gWorld->getIterations() << ") : robot nb." << _wm->_agentId << " take the genome from the robot nb." << (*it).first << std::endl;

			if (_wm->_agentId == 1 && gVerbose) // debug
				std::cout << "  Sigma is " << _wm->_sigmaList[(*it).first] << "." << std::endl;


			_wm->_genomesList.clear();
		}
}
void MedeaSpAgentObserver::pickRandomGenome()
{
	if(_wm->_genomesList.size() != 0)//optional, should always be true : pickRandomGenome should be called only when liste>0
	{
		int randomIndex = rand()%_wm->_genomesList.size();
		std::map<int, std::vector<double> >::iterator it = _wm->_genomesList.begin();
		while (randomIndex !=0 )
		{
			it ++;
			randomIndex --;
		}

		_wm->_currentGenome = (*it).second;
		if ( MedeaSpSharedData::gDynamicSigma == true )
		{
			mutateWithBouncingBounds(_wm->_sigmaList[(*it).first]);
		}
		else
		{
			mutateWithBouncingBounds(-1.00);
		}

		_wm->setNewGenomeStatus(true); 
		_wm->setFatherId((*it).first);

		//gLogFile << gWorld->getIterations() << " : " << _wm->_agentId + 1000 * _wm->getDateOfBirth()  << " take " << _wm->getFatherId()<<std::endl;
		if (_wm->_agentId == 1 && gVerbose) // debug
			std::cout << "  Sigma is " << _wm->_sigmaList[(*it).first] << "." << std::endl;


		_wm->_genomesList.clear();
	}
	//never reached
}
void MedeaSpAgentObserver::elitSelection()
{
	if(_wm->_genomesList.size() != 0)//optional, should always be true : pickRandomGenome should be called only when liste>0
	{
		std::map<int, std::vector<double> > tournamentListGenome;
		std::map<int, double > tournamentListFitness;
		std::cout<<"size???"<<(int)MedeaSpSharedData::gTournamentSize<<std::endl;
		unsigned int aimedSize = std::min((int)MedeaSpSharedData::gTournamentSize,(int)_wm->_genomesList.size());
		//unsigned int aimedSize = std::min(1,(int)_wm->_genomesList.size());
		while ( tournamentListGenome.size() < aimedSize)
		{
			int randomIndex = rand()%_wm->_genomesList.size();
			std::map<int, std::vector<double> >::iterator it = _wm->_genomesList.begin();
			while (randomIndex !=0 )
			{
				it ++;
				randomIndex --;
			}
			tournamentListGenome[(*it).first] = (*it).second;
			tournamentListFitness[(*it).first] = _wm->_fitnessList[(*it).first];
			_wm->_genomesList.erase((*it).first);
		}

		double bestFitness = (*tournamentListFitness.begin()).second;
		int idBest = (*tournamentListFitness.begin()).first;
		for (std::map<int, double>::iterator it = tournamentListFitness.begin(); it != tournamentListFitness.end() ; it++)
		{
			if ( (*it).second > bestFitness )
			{
				bestFitness = (*it).second;
				idBest = (*it).first;
			}
		}
		_wm->_currentGenome = tournamentListGenome[idBest];

		if ( MedeaSpSharedData::gDynamicSigma == true )
		{
			mutateWithBouncingBounds(_wm->_sigmaList[idBest]);
		}
		else
		{
			mutateWithBouncingBounds(-1.00);
		}

		_wm->setNewGenomeStatus(true); 
		_wm->setFatherId(idBest);

		//gLogFile << gWorld->getIterations() << " : " << _wm->_agentId + 1000 * _wm->getDateOfBirth()  << " take " << _wm->getFatherId()<<std::endl;
		if (_wm->_agentId == 1 && gVerbose) // debug
			std::cout << "  Sigma is " << _wm->_sigmaList[idBest] << "." << std::endl;


		_wm->_genomesList.clear();
		_wm->_fitnessList.clear();
	}
}
void StrongCausalityExperimentAgentObserver::step() 
{

	if ( _wm->_age == _lifetimeIterations )
	{			
		// stats for current agent
		_sumOfFitnesses = _sumOfFitnesses + _wm->_fitnessValue;
		
		if ( initPos[_wm->_generation][0] == -1 )  // genome iteration ends? display stats and restart with new genome
		{
			// * Display stats.
			
			//std::cout << _wm->_generation << "," << _wm->_fitnessValue;

			if ( _testIt == 0 )	// reference genome
				std::cout << "# ";
			std::cout << _testIt << "," << _sumOfFitnesses;

			if ( _testIt == 0 )	// reference genome
				std::cout << ",0";
			else
				std::cout << "," << _sigma;
			
			for ( int i = 0 ; i != 18 ; i++ ) // genome
			{
				std::cout << ",";
				std::cout << _wm->_genome[i];
				
			}
			std::cout << std::endl;
			
			reset();
			
			if ( _triesPerSigma == _nbOfTriesPerSigmaValue )
			{			
				if ( _sigma < _sigmaMax )
				{
					_sigma = _sigma * 2;
				}
				else
				{
					std::cout << "end." << std::endl;
					exit(0);
				}
				_triesPerSigma = 0;
			}
			else
				_triesPerSigma++;
			
			mutateWithBouncingBounds();

			_wm->_generation = 0;			
		}
		
		// prepare for new evaluation
		_wm->_generation++;

		_wm->_xReal = initPos[_wm->_generation][0];
		_wm->_yReal = initPos[_wm->_generation][1];
		_wm->_agentAbsoluteOrientation = initPos[_wm->_generation][2];
		_wm->_agentAbsoluteLinearSpeed = 0;
		
		_wm->_fitnessValue = 0;
		_wm->_age = 0; // age<0 means random mouvement until age=0D
		
	}	
	else
	{
		// udpate fitness
		updateFitness();
		_wm->_age++;
	}
}
void MedeaSpAgentObserver::selectRankProp()
{
	if(_wm->_genomesList.size() != 0)
	{
		int idBest = 0;
		if(_wm->_genomesList.size() == 1)
		{
			idBest = (*_wm->_genomesList.begin()).first;
		}
		else
		{
			double minimumExpected = MedeaSpSharedData::gMinimumExpectedValue;
			double maximumExpected = MedeaSpSharedData::gMaximumExpectedValue;

			//reverse the map to sort by fitness. Will put lowest first
			std::multimap<double,int> sortedFitness = flip_map(_wm->_fitnessList);

			std::map<int, double> f;
			int rank = 0;
			for (std::multimap<double, int >::iterator it = sortedFitness.begin(); it != sortedFitness.end() ; it++)
			{
				f[(*it).second] = ( maximumExpected  - (maximumExpected - minimumExpected) * (rank / ( (double)_wm->_fitnessList.size() - 1.0) )) / (double)_wm->_fitnessList.size() ;
				rank ++;
			}

			double sum1 = 0.0;
			for( std::map<int, double>::iterator it = f.begin() ; it != f.end() ; it ++)
			{
				sum1 += f[(*it).first];
			}

			double sum2 = 0.0;
			std::map<int, double> p;

			for( std::map<int, double>::iterator it = f.begin() ; it != f.end() ; it ++)
			{
				if (f[(*it).first] > 0.0)
				{
					sum2 += f[(*it).first];
					p[(*it).first] = sum2/sum1;
				}
			}

			double r = ranf();
			//Proportional selection
			std::map<int, double >::iterator it = p.begin() ;
			while( (r > p[(*it).first]) && (it != p.end())) 
			{
				it ++;
			}
			idBest = (*it).first ;


		_wm->_currentGenome =_wm->_genomesList[idBest];

		if ( MedeaSpSharedData::gDynamicSigma == true )
		{
			mutateWithBouncingBounds(_wm->_sigmaList[idBest]);
		}
		else
		{
			mutateWithBouncingBounds(-1.00);
		}

		_wm->setNewGenomeStatus(true); 
		_wm->setFatherId(idBest);

		//gLogFile << gWorld->getIterations() << " : " << _wm->_agentId + 1000 * _wm->getDateOfBirth()  << " take " << _wm->getFatherId()<<std::endl;
		if (_wm->_agentId == 1 && gVerbose) // debug
			std::cout << "  Sigma is " << _wm->_sigmaList[idBest] << "." << std::endl;


		_wm->_genomesList.clear();
		_wm->_fitnessList.clear();
		}
	}
}
void MedeaSpAgentObserver::selectFitnessProp()
{
	if(_wm->_genomesList.size() != 0)
	{
		double sum1 = 0.0;
		for( std::map<int, std::vector<double> >::iterator it = _wm->_genomesList.begin() ; it != _wm->_genomesList.end() ; it ++)
		{
			sum1 += _wm->_fitnessList[(*it).first];
		}

		int selected = 0;
		//if one has a fitness higher than 0 do the computations for proportional selection
		if (sum1 > 0)
		{
			double sum2 = 0.0;
			std::map<int, double> p;

			for( std::map<int, std::vector<double> >::iterator it = _wm->_genomesList.begin() ; it != _wm->_genomesList.end() ; it ++)
			{
				if (_wm->_fitnessList[(*it).first] > 0.0)
				{
					sum2 += _wm->_fitnessList[(*it).first];
					p[(*it).first] = sum2/sum1;
				}
			}

			double r = ranf();
			//Proportional selection
			std::map<int, double >::iterator it = p.begin() ;
			while( (r > p[(*it).first]) && (it != p.end())) 
			{
				it ++;
			}
			selected = (*it).first ;
			std::cerr<<"okok"<<std::endl;
		}
		else
		{
			int randomIndex = rand()%_wm->_genomesList.size();
			std::map<int, std::vector<double> >::iterator it = _wm->_genomesList.begin();
			while (randomIndex != 0 )
			{
				it ++;
				randomIndex --;
			}
			selected = (*it).first;
		}

		//_currentGenome = _wm->_genomesList[selected];
		int idBest = selected;

		_wm->_currentGenome =_wm->_genomesList[selected];

		if ( MedeaSpSharedData::gDynamicSigma == true )
		{
			mutateWithBouncingBounds(_wm->_sigmaList[idBest]);
		}
		else
		{
			mutateWithBouncingBounds(-1.00);
		}

		_wm->setNewGenomeStatus(true); 
		_wm->setFatherId(idBest);

		//gLogFile << gWorld->getIterations() << " : " << _wm->_agentId + 1000 * _wm->getDateOfBirth()  << " take " << _wm->getFatherId()<<std::endl;
		if (_wm->_agentId == 1 && gVerbose) // debug
			std::cout << "  Sigma is " << _wm->_sigmaList[idBest] << "." << std::endl;


		_wm->_genomesList.clear();
		_wm->_fitnessList.clear();
	}
}