48 unsigned long long rdtsc(){
50 __asm__ __volatile__ (
"rdtsc" :
"=a" (lo),
"=d" (hi));
51 return ((
unsigned long long)hi << 32) | lo;
56 NeuroEvolution::NeuroEvolution(std::string suff, std::string config, std::string path) :
70 std::string configPath = resourcePath + config;
73 myconfigdataaa.readFile(configPath);
74 populationSize=myconfigdataaa.getintvalue(
"populationSize");
75 numberOfElementsToMutate=myconfigdataaa.getintvalue(
"numberOfElementsToMutate");
76 numberOfChildren=myconfigdataaa.getintvalue(
"numberOfChildren");
77 numberOfTestsBetweenGenerations=myconfigdataaa.getintvalue(
"numberOfTestsBetweenGenerations");
78 numberOfSubtests=myconfigdataaa.getintvalue(
"numberOfSubtests");
79 numberOfControllers=myconfigdataaa.getintvalue(
"numberOfControllers");
80 leniencyCoef=myconfigdataaa.getDoubleValue(
"leniencyCoef");
81 coevolution=myconfigdataaa.getintvalue(
"coevolution");
82 seeded = myconfigdataaa.getintvalue(
"startSeed");
84 bool learning = myconfigdataaa.getintvalue(
"learning");
86 if (populationSize < numberOfElementsToMutate + numberOfChildren)
88 throw std::invalid_argument(
"Population will grow with given parameters");
94 for(
int j=0;j<numberOfControllers;j++)
96 cout<<
"creating Populations"<<endl;
103 for(
int i = 0; i < numberOfControllers; i++)
107 ss<< resourcePath <<
"logs/bestParameters-"<<this->suffix<<
"-"<<i<<
".nnw";
108 seededPop->loadFromFile(ss.str().c_str());
113 evolutionLog.open((resourcePath +
"logs/evolution"+suffix+
".csv").c_str(),ios::out);
114 if (!evolutionLog.is_open())
116 throw std::runtime_error(
"Logs does not exist. Please create a logs folder in your build directory or update your cmake file");
121 NeuroEvolution::~NeuroEvolution()
125 for(std::size_t i = 0; i < populations.size(); i++)
127 delete populations[i];
133 void NeuroEvolution::mutateEveryController()
135 for(std::size_t i=0;i<populations.size();i++)
137 populations.at(i)->mutate(&eng,numberOfElementsToMutate);
141 void NeuroEvolution::combineAndMutate()
143 for(std::size_t i=0;i<populations.size();i++)
145 populations.at(i)->combineAndMutate(&eng, numberOfElementsToMutate, numberOfChildren);
152 double aveScore1 = 0.0;
153 double aveScore2 = 0.0;
156 double maxScore1,maxScore2;
158 for(std::size_t i=0;i<scoresOfTheGeneration.size();i++)
160 aveScore1+=scoresOfTheGeneration[i][0];
161 aveScore2+=scoresOfTheGeneration[i][1];
163 aveScore1 /= scoresOfTheGeneration.size();
164 aveScore2 /= scoresOfTheGeneration.size();
167 for(std::size_t i=0;i<populations.size();i++)
169 populations.at(i)->orderPopulation();
172 evolutionLog<<generationNumber*numberOfTestsBetweenGenerations<<
","<<aveScore1<<
","<<aveScore2<<
",";
173 evolutionLog<<populations.at(0)->getMember(0)->maxScore<<
","<<populations.at(0)->getMember(0)->maxScore1<<
","<<populations.at(0)->getMember(0)->maxScore2<<endl;
178 ofstream logfileLeader;
179 for(std::size_t i=0;i<populations.size();i++)
182 ss <<
resourcePath <<
"logs/bestParameters-"<<suffix<<
"-"<<i<<
".nnw";
183 populations[i]->getMember(0)->saveToFile(ss.str().c_str());
187 double diffclock(clock_t clock1,clock_t clock2)
189 double diffticks=clock1-clock2;
190 double diffms=(diffticks*10)/CLOCKS_PER_SEC;
194 vector <NeuroEvoMember *> NeuroEvolution::nextSetOfControllers()
198 testsToDo=numberOfTestsBetweenGenerations;
200 testsToDo=populationSize;
202 if(currentTest == testsToDo)
205 if (numberOfChildren == 0)
207 mutateEveryController();
213 cout<<
"mutated the populations"<<endl;
214 this->scoresOfTheGeneration.clear();
219 currentTest=populationSize - numberOfElementsToMutate - numberOfChildren;
222 selectedControllers.clear();
223 for(std::size_t i=0;i<populations.size();i++)
227 selectedOne=rand()%populationSize;
229 selectedOne=currentTest;
232 selectedControllers.push_back(populations.at(i)->getMember(selectedOne));
236 if (subTests == numberOfSubtests)
243 return selectedControllers;
246 void NeuroEvolution::updateScores(vector <double> multiscore)
248 if(multiscore.size()==2)
249 this->scoresOfTheGeneration.push_back(multiscore);
251 multiscore.push_back(-1.0);
252 double score=1.0* multiscore[0] - 0.0 * multiscore[1];
253 for(std::size_t oneElem=0;oneElem<selectedControllers.size();oneElem++)
255 NeuroEvoMember * controllerPointer=selectedControllers.at(oneElem);
257 controllerPointer->pastScores.push_back(score);
258 double prevScore=controllerPointer->maxScore;
261 double newScore= leniencyCoef * prevScore + (1.0 - leniencyCoef) * score;
262 controllerPointer->maxScore=newScore;
266 controllerPointer->maxScore=score;
267 controllerPointer->maxScore1=multiscore[0];
268 controllerPointer->maxScore2=multiscore[1];
274 payloadLog.open((
resourcePath +
"logs/scores.csv").c_str(),ios::app);
275 payloadLog<<multiscore[0]<<
","<<multiscore[1]<<endl;
Convenience function for combining strings with ints, mostly for naming structures.
void orderAllPopulations()
A class to read a learning configuration from a .ini file.
A series of functions to assist with file input/output.
static std::string getResourcePath(std::string relPath)
unsigned long long rdtsc()
Rand seeding simular to the evolution and terrain classes.
Top level class for NeuroEvolution.