void FastLayeredNetwork<Type>::setLink(const Node &fromNodeIndex,const Node &toNodeIndex,Type weight) { if(toNodeIndex.z>=(int)layers.size() || fromNodeIndex.z>=(int)layers.size()) { throw CREATE_LOCATEDEXCEPTION_INFO("OOPS"); } NetworkLayer<Type> &toLayer = layers[toNodeIndex.z]; for(int a=0;a<(int)toLayer.fromLayers.size();a++) { if(toLayer.fromLayers[a] != fromNodeIndex.z) { //Not the source layer we are looking for continue; } NetworkLayer<Type> &fromLayer = layers[toLayer.fromLayers[a]]; int fromNodeArrayIndex = fromNodeIndex.y*fromLayer.nodeStride + fromNodeIndex.x; int toNodeArrayIndex = toNodeIndex.y*toLayer.nodeStride + toNodeIndex.x; if(fromNodeArrayIndex>(int)fromLayer.nodeValues.size() || toNodeArrayIndex>(int)toLayer.nodeValues.size()) { throw CREATE_LOCATEDEXCEPTION_INFO("OOPS"); } toLayer.fromWeights[a][toNodeArrayIndex*toLayer.nodeValues.size()+fromNodeArrayIndex] = weight; return; } throw CREATE_LOCATEDEXCEPTION_INFO("OOPS"); }
void ExperimentRun::setupExperiment(int _experimentType, string _outputFileName) { experimentType = _experimentType; outputFileName = _outputFileName; cout << "SETTING UP EXPERIMENT TYPE: " << experimentType << endl; switch (experimentType) { case EXPERIMENT_RCQUADRATOT: experiments.push_back(shared_ptr<Experiment>(new RCQuadratotExperiment(""))); break; default: cout << string("ERROR: Unknown Experiment Type!\n"); throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: Unknown Experiment Type!"); } for (int a=1;a<NUM_THREADS;a++) { if(totalSubExperiments > 1) { cerr << "ERROR: cannot have a hybrid experiment with multiple treads!\n"; exit(1); } experiments.push_back(shared_ptr<Experiment>(experiments[0]->clone())); } }
Globals::Globals(string fileName) : nodeCounter(0), linkCounter(0), speciesCounter(0) { cout << "Populating sigmoid table..."; for (int a=0; a<6001; a++) { signedSigmoidTable[a] = ((1 / (1+exp(-((a-3000)/1000.0)))) - 0.5)*2.0; unsignedSigmoidTable[a] = 1 / (1+exp(-((a-3000)/1000.0))); } cout << "done!\n"; cout << "Loading Parameter data from " << fileName << endl; if (fileName==string("")) { return; } ifstream infile; infile.open(fileName.c_str()); if (infile.is_open()==false) { throw CREATE_LOCATEDEXCEPTION_INFO(string("COULD NOT OPEN GLOBALS .dat FILE: ")+fileName); } string line="test"; istringstream instream; while (getline(infile,line)) { #if DEBUG_NEAT_GLOBALS cout << "LINE: " << line << endl; #endif #ifdef linux if (int(line[line.size()-1])==13) //DOS line breaks line.erase(line.begin()+(int(line.size())-1)); #endif if (line[0]==';') //comment { continue; } if (line.size()==0) { continue; } istringstream input(line); string parameterName; double value=0.0; input >> parameterName >> value; parameters.insert(parameterName,value); } cacheParameters(); initRandom(); }
void FastLayeredNetwork<Type>::setValue(const Node &nodeIndex,Type newValue) { if(nodeIndex.z>=(int)layers.size()) { throw CREATE_LOCATEDEXCEPTION_INFO("OOPS"); } NetworkLayer<Type> &layer = layers[nodeIndex.z]; int nodeArrayIndex = nodeIndex.y*layer.nodeStride + nodeIndex.x; if(nodeArrayIndex>(int)layer.nodeValues.size()) { throw CREATE_LOCATEDEXCEPTION_INFO("OOPS"); } layer.nodeValues[nodeArrayIndex] = newValue; }
Type GPUANN<Type>::getValue(const Node &nodeIndex) { if(nodeIndex.z>=(int)layers.size()) { throw CREATE_LOCATEDEXCEPTION_INFO("OOPS"); } NetworkLayer<Type> &layer = layers[nodeIndex.z]; int nodeArrayIndex = nodeIndex.y*layer.nodeStride + nodeIndex.x; if(nodeArrayIndex>(int)layer.nodeValues.size()) { throw CREATE_LOCATEDEXCEPTION_INFO("OOPS"); } return layer.nodeValues[nodeArrayIndex]; }
GeneticPopulation::GeneticPopulation(string fileName) : onGeneration(-1) { TiXmlDocument doc(fileName); bool loadStatus; if (iends_with(fileName,".gz")) { loadStatus = doc.LoadFileGZ(); } else { loadStatus = doc.LoadFile(); } if (!loadStatus) { throw CREATE_LOCATEDEXCEPTION_INFO("Error trying to load the XML file!"); } TiXmlElement *root; root = doc.FirstChildElement(); { TiXmlElement *generationElement = root->FirstChildElement("GeneticGeneration"); while (generationElement) { generations.push_back(shared_ptr<GeneticGeneration>(new GeneticGeneration(generationElement))); generationElement = generationElement->NextSiblingElement("GeneticGeneration"); onGeneration++; } } if (onGeneration<0) { throw CREATE_LOCATEDEXCEPTION_INFO("Tried to load a population with no generations!"); } adjustFitness(); }
const GeneticLinkGene *GeneticIndividual::getLink(int fromNodeID,int toNodeID) const { for (int a=0;a<(int)links.size();a++) { if (links[a].getFromNodeID()==fromNodeID&&links[a].getToNodeID()==toNodeID) return &links[a]; } throw CREATE_LOCATEDEXCEPTION_INFO("Tried to get a link which doesn't exist!"); }
vector<shared_ptr<GeneticIndividual> >::iterator GeneticPopulation::getIndividualIterator(int a, int generation) { if (generation == -1) generation = int(generations.size() - 1); //onGeneration); if (generation >= int(generations.size()) || a >= generations[generation]->getIndividualCount()) { throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: Generation out of range!\n"); } return generations[generation]->getIndividualIterator(a); }
RelativePosition RoombotBuildPlan::getMinimalPosition() const { if(positions.size() == 0) throw CREATE_LOCATEDEXCEPTION_INFO ("Can not get minimal position in empty buildplan"); RelativePosition result = positions.at(0); for(size_t i=1; i<positions.size(); i++){ if(positions.at(i) < result){ result = positions.at(i); } } return result; }
int Random::getRandomWithinRange(int min,int max) { int randNum = min + (intGen()%( (max-min) + 1)); #if DEBUG_RANDOM if(randNum<min || randNum>max) { throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: Random number out of range!"); } #endif return randNum; }
double Random::getRandomDouble(double low,double high) { double randNum = realGen()*(high-low) + low; #if DEBUG_RANDOM if(randNum<low || randNum>=high) { throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: Random number out of range!"); } #endif return randNum; }
int Random::getRandomInt(int limit) { int randNum = intGen()%limit; #if DEBUG_RANDOM if(randNum<0 || randNum>=limit) { throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: Random number out of range!"); } #endif return randNum; }
double Random::getRandomDouble() { double randNum = realGen(); #if DEBUG_RANDOM if(randNum<0.0 || randNum>=1.0) { throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: Random number out of range!"); } #endif return realGen(); }
Node * RoombotModule::getNode(Field * field, std::string name) const { int fieldCount = field->getCount(); Node * node; Field * nameField; if (fieldCount == -1) throw CREATE_LOCATEDEXCEPTION_INFO("Field is not a multi-field."); for (int i = 0; i < fieldCount; i++) { node = field->getMFNode(i); nameField = node->getField("name"); if (nameField != NULL) { if (nameField->getSFString().compare(name) == 0) { return node; } } } throw CREATE_LOCATEDEXCEPTION_INFO("Field: " + name + " not found."); }
void GeneticGeneration::cleanup() { if (!sortedByFitness) { throw CREATE_LOCATEDEXCEPTION_INFO("You aren't supposed to acll this until you sort by fitness!"); } while (individuals.size()>1) { //cout << "CLEANING UP!\n"; //Never delete the generation champion (remember that they are sorted by fitness at this point). individuals.erase(individuals.begin()+1); } }
void ExperimentRun::setupExperimentInProgressUseDat(string _datFile, string populationFileName,string _outputFileName) { outputFileName = _outputFileName; //datFile = _datFile; PRINT(populationFileName); { TiXmlDocument doc(populationFileName); bool loadStatus; if (iends_with(populationFileName,".gz")) { loadStatus = doc.LoadFileGZ(); } else { loadStatus = doc.LoadFile(); } if (!loadStatus) { cerr << "Error trying to load the XML file!" << endl; throw CREATE_LOCATEDEXCEPTION_INFO("Error trying to load the XML file!"); } TiXmlElement *element = doc.FirstChildElement(); NEAT::Globals* globals = NEAT::Globals::init(element); (void) globals; //to get rid of unused variable warning NEAT::Globals::getSingleton()->overrideParametersFromFile(_datFile); NEAT::Globals::getSingleton()->setOutputFilePrefix(outputFileName); //set the name of the outputPrefixFile //Destroy the document } int experimentType = int(NEAT::Globals::getSingleton()->getParameterValue("ExperimentType")+0.001); cout << "Loading Experiment: " << experimentType << endl; setupExperiment(experimentType,_outputFileName); cout << "Experiment set up. Creating population...\n"; createPopulation(populationFileName); cout << "Population Created\n"; }
Globals::Globals(TiXmlElement *root) : nodeCounter(-1), linkCounter(-1), speciesCounter(-1) { cout << "Populating sigmoid table..."; for (int a=0; a<6001; a++) { signedSigmoidTable[a] = ((1 / (1+exp(-((a-3000)/1000.0)))) - 0.5)*2.0; unsignedSigmoidTable[a] = 1 / (1+exp(-((a-3000)/1000.0))); } cout << "done!\n"; TiXmlAttribute *firstAttribute = root->FirstAttribute(); while (firstAttribute) { if (iequals(firstAttribute->Name(),"NodeCounter")) { nodeCounter = firstAttribute->IntValue(); } else if (iequals(firstAttribute->Name(),"LinkCounter")) { linkCounter = firstAttribute->IntValue(); } else if (iequals(firstAttribute->Name(),"SpeciesCounter")) { speciesCounter = firstAttribute->IntValue(); } else { addParameter( firstAttribute->Name() , firstAttribute->DoubleValue()); } firstAttribute = firstAttribute->Next(); } if (nodeCounter==-1 || linkCounter==-1 || speciesCounter==-1) { throw CREATE_LOCATEDEXCEPTION_INFO("MALFORMED XML!"); } cacheParameters(); initRandom(); }
FastLayeredNetwork<Type>::FastLayeredNetwork(const vector<NetworkLayer<Type> > &_layers) : Network<Type>(), layers(_layers) { //Perform a sanity check on the layers for(size_t toLayer=0;toLayer<layers.size();toLayer++) { for(int a=0;a<(int)layers[toLayer].fromLayers.size();a++) { size_t fromLayer = layers[toLayer].fromLayers[a]; if(fromLayer>=toLayer) { throw CREATE_LOCATEDEXCEPTION_INFO("Network is not feed-forward!"); } } } }
void GeneticIndividual::addNode(GeneticNodeGene node) { int nodeID = node.getID(); for (int a=0;a<(int)nodes.size();a++) { int curID = nodes[a].getID(); if (curID==nodeID) { throw CREATE_LOCATEDEXCEPTION_INFO("Oops, tried to add a node when it already existed!"); } else if (curID>nodeID) { nodes.insert(nodes.begin()+a,node); return; } } nodes.push_back(node); }
shared_ptr<GeneticIndividual> GeneticPopulation::getIndividual(int a, int generation) { #ifdef DEBUG_GENPOP cout << a << ',' << generations.size() << endl; #endif if (generation == -1) { #ifdef DEBUG_GENPOP cout << "NO GEN GIVEN: USING onGeneration\n"; #endif generation = int(generations.size() - 1); //onGeneration); } if (generation >= int(generations.size()) || a >= generations[generation]->getIndividualCount()) { cout << "GET_INDIVIDUAL: GENERATION OUT OF RANGE!\n"; throw CREATE_LOCATEDEXCEPTION_INFO("GET_INDIVIDUAL: GENERATION OUT OF RANGE!\n"); } #ifdef DEBUG_GENPOP cout << "return" << endl; #endif return generations[generation]->getIndividual(a); }
void GeneticIndividual::addLink(GeneticLinkGene link) { int linkID = link.getID(); for (int a=0;a<(int)links.size();a++) { int curID = links[a].getID(); if (curID==linkID) { throw CREATE_LOCATEDEXCEPTION_INFO("Oops, tried to add a link when it already existed!"); } else if (curID>linkID) { links.insert(links.begin()+a,link); return; } } links.push_back(link); }
void ExperimentRun::start() { if(true) {//NEAT::Globals::getSingleton()->getParameterValue("MultiObjective") > 0.5) { boost::filesystem::remove(outputFileName); boost::filesystem::remove(outputFileName+string(".gz")); } cout << "Experiment started\n"; #ifndef _DEBUG try { #endif int maxGenerations = int(NEAT::Globals::getSingleton()->getParameterValue("MaxGenerations")); started=running=true; clock_t start,current,reference; start = clock(); reference = clock(); //resuming an old experiment, want to produce next gen right away because last one already evaluated if ((population->getGenerationCount()-1) > 0) { mutex::scoped_lock scoped_lock(*populationMutex); cout << "PRODUCING NEXT GENERATION\n"; produceNextGeneration(); cout << "DONE PRODUCING\n"; } int startGen = population->getGenerationCount()-1; for (int generations=(population->getGenerationCount()-1);generations<maxGenerations;generations++) { current = clock(); double time = (double(current)-double(reference))/CLOCKS_PER_SEC; if(time >= 3600.0 ) { //if at least an hour elapsed double elapsed = (double(current)-double(start))/CLOCKS_PER_SEC; printf("TIME_STATS: best fitness = %5.5f, generation = %d, elapsed time = %5.5f s\n", population->getBestAllTimeIndividual()->getFitness(), generations - 1,elapsed); reference = clock(); } if (generations>startGen) { mutex::scoped_lock scoped_lock(*populationMutex); //set IDs before reproducing so maintain ancestry -- NO LONGER NEEDED SINCE IDs will have been set in finishEvaluations //population->getGeneration()->setIDs(); cout << "PRODUCING NEXT GENERATION\n"; produceNextGeneration(); cout << "DONE PRODUCING\n"; // cout << "DUMPING REPRODUCED FROM PREVIOUS GENERATION\n"; // population->dumpReproducedFromPreviousGeneration(outputFileName/*+string(".backup.xml")*/,true,true); // cout << "DONE DUMPING\n"; } if (experiments[0]->performUserEvaluations()) { #ifdef HCUBE_NOGUI throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: TRIED TO USE INTERACTIVE EVOLUTION WITH NO GUI!"); #else frame->getUserEvaluationFrame()->updateEvaluationPanels(); running=false; while (!running) { boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC); xt.sec += 1; boost::thread::sleep(xt); // Sleep for 1/2 second //cout << "Sleeping while user evaluates!\n"; } #endif } else { while (!running) { boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC); xt.sec += 1; boost::thread::sleep(xt); // Sleep for 1/2 second } evaluatePopulation(); } cout << "Finishing evaluations\n"; finishEvaluations(); cout << "Evaluations Finished\n"; } //if want to dump all will be taken care of from finishEvaluations now for all gens //cout << "DUMPING ALL INDIVIDUALS FROM FINAL GENERATION\n"; //population->getGeneration()->setIDs(); //population->dump(outputFileName/*+string(".backup.xml")*/,true,true); //cout << "DONE DUMPING\n"; cout << "Experiment finished\n"; //cout << "Saving Dump..."; //population->dump(outputFileName,true,false); //cout << "Done!\n"; if(true) {//NEAT::Globals::getSingleton()->getParameterValue("MultiObjective") > 0.5) { //need to combine files into one //TiXmlDocument doc(); TiXmlElement *root = new TiXmlElement("Genetics"); NEAT::Globals::getSingleton()->dump(root); /* stringstream ss; //root->Print(ss,0); ss << root; string s = ss.str(); */ cout << "Merging Output Files..."; TiXmlPrinter rootPrinter; root->Accept( &rootPrinter ); string s = rootPrinter.CStr(); ofstream out( outputFileName.c_str() ); string lastGenFileName = outputFileName + string(".lastgen.xml"); ofstream out2( lastGenFileName.c_str() ); out << s.substr(0, s.length() - 3) << ">" <<endl; out2 << s.substr(0, s.length() - 3) << ">" <<endl; int maxGenerations = int(NEAT::Globals::getSingleton()->getParameterValue("MaxGenerations")); for(int i=0; i<maxGenerations; i++) { stringstream ss; ss << i; TiXmlDocument doc( outputFileName + string("-") + ss.str() + string(".backup.xml.gz") ); doc.LoadFileGZ(); TiXmlPrinter printer; doc.Accept(&printer); out << printer.CStr() << endl; if( i == (maxGenerations - 1)) out2 << printer.CStr() << endl; } out << "</Genetics>" << endl; out2 << "</Genetics>" << endl; out.close(); out2.close(); cout << "Done!\n"; cout << "Compressing Merged File..."; stringstream ss; ss << "gzip " << outputFileName; std::system(ss.str().c_str()); stringstream ssLastGen; ssLastGen << "gzip " << lastGenFileName; std::system(ssLastGen.str().c_str()); cout << "Done!\n"; cout << "Deleting backup files..."; for(int i=0; i<maxGenerations; i++) { stringstream ss2; ss2 << outputFileName << "-" << i << ".backup.xml.gz"; boost::filesystem::remove(ss2.str()); } boost::filesystem::remove(outputFileName + string("-root.backup.xml")); cout << "Done!\n"; } else { cout << "Saving best individuals..."; string bestFileName = outputFileName.substr(0,outputFileName.length()-4)+string("_best.xml"); population->dumpBest(bestFileName,true,true); cout << "Done!\n"; cout << "Deleting backup file..."; boost::filesystem::remove(outputFileName+string(".backup.xml")); cout << "Done!\n"; } #ifndef _DEBUG } catch (const std::exception &ex) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE(ex.what()); } catch (...) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE("AN UNKNOWN EXCEPTION HAS BEEN THROWN!"); } #endif }
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; } }
void EvaluationSet::run() { #ifndef _DEBUG try #endif { //Process individuals sequentially running=true; vector<shared_ptr<NEAT::GeneticIndividual> >::iterator tmpIterator; tmpIterator = individualIterator; for (int a=0;a<individualCount;a++,tmpIterator++) { while (!running) { boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC_); xt.sec += 1; boost::thread::sleep(xt); // Sleep for 1 second } experiment->addIndividualToGroup(*tmpIterator); if (experiment->getGroupSize()==experiment->getGroupCapacity()) { //cout << "Processing group...\n"; experiment->processGroup(generation); //cout << "Done Processing group\n"; experiment->clearGroup(); } } if (experiment->getGroupSize()>0) { //Oops, maybe you specified a bad # of threads? throw CREATE_LOCATEDEXCEPTION_INFO("Error, individuals were left over after run finished!"); } finished=true; } #ifndef _DEBUG catch (string s) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE(s); } catch (const char *s) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE(s); } catch (const std::exception &ex) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE(ex.what()); } catch (...) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE("An unknown exception has occured!"); } #endif }
void EvaluationSet::run() { #ifndef _DEBUG try #endif { //Process individuals sequentially running=true; vector<shared_ptr<NEAT::GeneticIndividual> >::iterator tmpIterator; tmpIterator = individualIterator; for (int a=0;a<individualCount;a++,tmpIterator++) { while (!running) { boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC); //(nac: changed for latest version of boost) xt.sec += 1; cout << "jmc: used1!\n"; exit(3); boost::thread::sleep(xt); // Sleep for 1 second } experiment->addIndividualToGroup(*tmpIterator); if (experiment->getGroupSize()==experiment->getGroupCapacity()) { //cout << "Processing group...\n"; experiment->processGroup(generation); //cout << "Done Processing group\n"; experiment->clearGroup(); } } if (experiment->getGroupSize()>0) { //Oops, maybe you specified a bad # of threads? throw CREATE_LOCATEDEXCEPTION_INFO("Error, individuals were left over after run finished! Do you have the c++ flag -DINTERACTIVELYEVOLVINGSHAPES set? Did you set getGroupCapacity to return the pop size in HCUBE_Experiment.h? or there may have been a bad (or negative, or zero) fitness value for an organism?"); } finished=true; } #ifndef _DEBUG catch (string s) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE(s); } catch (const char *s) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE(s); } catch (const std::exception &ex) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE(ex.what()); } catch (...) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE("An unknown exception has occured!"); } #endif }
void ExperimentRun::setupExperimentInProgress( string populationFileName, string _outputFileName ) { outputFileName = _outputFileName; { TiXmlDocument *doc = new TiXmlDocument(populationFileName); cout << "Loading population\n"; bool loadStatus; if (iends_with(populationFileName,".gz")) { loadStatus = doc->LoadFileGZ(); } else { loadStatus = doc->LoadFile(); } if (!loadStatus) { throw CREATE_LOCATEDEXCEPTION_INFO("Error trying to load the XML file!"); } TiXmlElement *element = doc->FirstChildElement(); NEAT::Globals* globals = NEAT::Globals::init(element); //Destroy the document delete doc; cout << "Population loaded\n"; } int experimentType = int(NEAT::Globals::getSingleton()->getParameterValue("ExperimentType")+0.001); NEAT::Globals::getSingleton()->seedRandom((unsigned int)(NEAT::Globals::getSingleton()->getParameterValue("ActualRandomSeed")+0.001)); cout << "Loading Experiment: " << experimentType << endl; setupExperiment(experimentType,_outputFileName); cout << "Experiment set up. Creating population...\n"; createPopulation(populationFileName); cout << "Population Created\n"; /*cout << "Cleaning up old generations\n"; population->cleanupOld(population->getGenerationCount()-1); cout << "Done cleaning\n";*/ }
void GeneticPopulation::produceNextGeneration() { cout << "In produce next generation loop...\n"; //This clears the link history so future links with the same toNode and fromNode will have different IDs Globals::getSingleton()->clearNodeHistory(); Globals::getSingleton()->clearLinkHistory(); int numParents = int(generations[generations.size() - 1/*onGeneration*/]->getIndividualCount()); //check that no org has fitness <= zero for (int a = 0; a < numParents; a++) { PRINT(generations[generations.size() - 1/*onGeneration*/]->getIndividual(a)->getFitness()); if (generations[generations.size() - 1/*onGeneration*/]->getIndividual(a)->getFitness() < 1e-6) { throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: Fitness must be a positive number!\n"); } } double totalFitness = 0; //get sum of adjusted fitness for all species together for (int a = 0; a < (int) species.size(); a++) { totalFitness += species[a]->getAdjustedFitness(); } int totalOffspring = 0; //give each species a fitness proportional to its adjusted fitness for (int a = 0; a < (int) species.size(); a++) { double adjustedFitness = species[a]->getAdjustedFitness(); int offspring = int(adjustedFitness / totalFitness * numParents); totalOffspring += offspring; species[a]->setOffspringCount(offspring); } //cout << "Pausing\n"; //int result = system("PAUSE"); //(void) result; //Some offspring were truncated. Give these N offspring to the species that had the best N individuals while (totalOffspring < numParents) { for (int a = 0; totalOffspring < numParents && a < generations[generations.size() - 1/*onGeneration*/]->getIndividualCount(); a++) { shared_ptr<GeneticIndividual> ind = generations[generations.size() - 1/*onGeneration*/]->getIndividual(a); shared_ptr<GeneticSpecies> gs = getSpecies(ind->getSpeciesID()); gs->setOffspringCount(gs->getOffspringCount() + 1); totalOffspring++; /* //Try to give 2 offspring to the very best individual if it only has one offspring. //This fixes the problem where the best indiviudal sits in his own species //and duplicates every generation. if(a==0&&gs->getOffspringCount()==1&&totalOffspring<numParents) { gs->setOffspringCount(gs->getOffspringCount()+1); totalOffspring++; }*/ } } //report stats on species for (int a = 0; a < (int) species.size(); a++) { cout << "Species ID: " << species[a]->getID() << " Age: " << species[a]->getAge() << " last improv. age: " << species[a]->getAgeOfLastImprovement() << " Fitness: " << species[a]->getFitness() << "*" << species[a]->getMultiplier() << "=" << species[a]->getAdjustedFitness() << " Size: " << int(species[a]->getIndividualCount()) << " Offspring: " << int(species[a]->getOffspringCount()) << endl; } //jmc: This is the new generation container vector<shared_ptr<GeneticIndividual> > babies; double totalIndividualFitness = 0; //jmc: clear the flag of whether they have reproduced (I think that is what that flag does.) for (int a = 0; a < (int) species.size(); a++) { species[a]->setReproduced(false); } int smallestSpeciesSizeWithElitism = int(Globals::getSingleton()->getParameterValue("SmallestSpeciesSizeWithElitism")); static double mutateSpeciesChampionProbability = Globals::getSingleton()->getParameterValue("MutateSpeciesChampionProbability"); double ForceCopyGenerationChampionParamVal = Globals::getSingleton()->getParameterValue("ForceCopyGenerationChampion"); bool forceCopyGenerationChampion = (ForceCopyGenerationChampionParamVal > Globals::getSingleton()->getRandom().getRandomDouble()); //getRandom between but not including 0 and 1 (Avida RNG and NEAT) for (int a = 0; a < generations[generations.size() - 1/*onGeneration*/]->getIndividualCount(); a++) //Go through and add the species champions (including ties for champ, which jmc added) { shared_ptr<GeneticIndividual> ind = generations[generations.size() - 1/*onGeneration*/]->getIndividual(a); shared_ptr<GeneticSpecies> species = getSpecies(ind->getSpeciesID()); // if (!species->isReproduced()) //original code assumed it would only store the champ of each species, so if this flag works. but it doesn't work to preserve ties for champ. if (!species->isReproduced() //jmc: if the species has not been checked yet to determine the fitness of its champ || ind->getFitness() == species->getBestIndividual()->getFitness()) //or if the fitness of this org equals the species champ { species->setReproduced(true); //This is the first and best organism of this species to be added, so it's the species champion //of this generation if (ind->getFitness() > species->getBestIndividual()->getFitness()) { //We have a new all-time species champion! species->setBestIndividual(ind); cout << "Species " << species->getID() << " has a new champ with fitness " << species->getBestIndividual()->getFitness() << endl; } if ((a == 0 && forceCopyGenerationChampion) || (species->getOffspringCount() >= smallestSpeciesSizeWithElitism)) { //Copy species champion. bool mutateChampion; if (Globals::getSingleton()->getRandom().getRandomDouble() < mutateSpeciesChampionProbability) mutateChampion = true; else { mutateChampion = false; } babies.push_back(shared_ptr<GeneticIndividual>(new GeneticIndividual(ind, mutateChampion, babies.size()))); species->decrementOffspringCount(); } if (a == 0) { species->updateAgeOfLastImprovement(); } } totalIndividualFitness += ind->getFitness(); } double averageFitness = totalIndividualFitness / generations[generations.size() - 1/*onGeneration*/]->getIndividualCount(); cout << "Generation " << int(onGeneration) << ": " << "overall_average = " << averageFitness << endl; #ifdef PRINT_GENETIC_PERTUBATION_INFO //print the gen number to this file ofstream mutationEffects_file; mutationEffects_file.open("mutationEffects.txt", ios::app); mutationEffects_file << "\nGeneration " << int(onGeneration + 1) << ": " << endl; //plus 1 cause we print this line to the file before this gens data mutationEffects_file.close(); ofstream mutationAndCrossoverEffects_file; mutationAndCrossoverEffects_file.open("mutationAndCrossoverEffects.txt", ios::app); mutationAndCrossoverEffects_file << "\nGeneration " << int(onGeneration + 1) << ": " << endl; //plus 1 cause we print this line to the file before this gens data mutationAndCrossoverEffects_file.close(); ofstream crossoverEffects_file; crossoverEffects_file.open("crossoverEffects.txt", ios::app); crossoverEffects_file << "\nGeneration " << int(onGeneration + 1) << ": " << endl; //plus 1 cause we print this line to the file before this gens data crossoverEffects_file.close(); #endif cout << "Champion fitness: " << generations[generations.size() - 1/*onGeneration*/]->getIndividual(0)->getFitness() << endl; if (generations[generations.size() - 1/*onGeneration*/]->getIndividual(0)->getUserData()) { cout << "Champion data: " << generations[generations.size() - 1/*onGeneration*/]->getIndividual(0)->getUserData()->summaryToString() << endl; } cout << "# of Species: " << int(species.size()) << endl; cout << "compat threshold: " << Globals::getSingleton()->getParameterValue("CompatibilityThreshold") << endl; for (int a = 0; a < (int) species.size(); a++) { //cout << "jmc: Making babies for species" << a << endl; species[a]->makeBabies(babies); } //cout << "jmc: done making babies\n"; if ((int) babies.size() != generations[generations.size() - 1/*onGeneration*/]->getIndividualCount()) { cout << "Population size changed! (or there may have been a bad (or negative, or zero) fitness value for an organism?)\n"; throw CREATE_LOCATEDEXCEPTION_INFO("Population size changed!"); } cout << "Making new generation\n"; shared_ptr<GeneticGeneration> newGeneration(generations[generations.size() - 1/*onGeneration*/]->produceNextGeneration(babies, onGeneration + 1)); //cout << "Done Making new generation!\n"; /*for(int a=0;a<4;a++) { for(int b=0;b<4;b++) { cout << babies[a]->getCompatibility(babies[b]) << '\t'; } cout << endl; }*/ generations.push_back(newGeneration); onGeneration++; }
void ExperimentRun::start() { cout << "Experiment started\n"; #ifndef DEBUG_EXPRUN try { #endif int maxGenerations = int(NEAT::Globals::getSingleton()->getParameterValue("MaxGenerations")); started=running=true; for (int generations=(population->getGenerationCount()-1);generations<GET_PARAMETER("MaxGenerations");generations++) { cout << "CURRENT SUBEXPERIMENT: " << currentSubExperiment << " Generation:" << generations << endl; if (generations>0) { // TODO: replace OR with experiments[currentSubExperiment].getExperimentName() == "HYBRID" if(experiments[currentSubExperiment]->getExperimentName() == "HYBRID" && switchSubExperiment(generations)) // if((experimentType == EXPERIMENT_LEGSWING_HYBRID || experimentType == EXPERIMENT_BITMIRRORING_HYBRID || experimentType == EXPERIMENT_TARGETWEIGHTS_HYBRID) && switchSubExperiment(generations)) { cout << "\n\n" << "************************\n" << "Switching SubExperiment: Hyper -> FT\n" << "************************\n\n"; // copy population from (currentSubExperiment-1)%totalSubExperiments to currentSubExperiment using HyperNEAT to P-NEAT converter population = shared_ptr<NEAT::GeneticPopulation>(experiments[currentSubExperiment]->createInitialPopulation(population, experiments[(currentSubExperiment + 1) % totalSubExperiments])); //TODO: check that this copying works //THESE CAN COME OUT when Hyper -> NEAT works cout << "changing the following three parameter settings from the HyperNEAT settings of:" << endl; cout << "MutateAddNodeProbability: " << NEAT::Globals::getSingleton()->getParameterValue("MutateAddNodeProbability") << endl; cout << "MutateAddLinkProbability: " << NEAT::Globals::getSingleton()->getParameterValue("MutateAddLinkProbability") << endl; cout << "MutateDemolishLinkProbability: " << NEAT::Globals::getSingleton()->getParameterValue("MutateDemolishLinkProbability") << endl; NEAT::Globals::getSingleton()->setParameterValue("MutateAddNodeProbability",0.0); NEAT::Globals::getSingleton()->setParameterValue("MutateAddLinkProbability",0.0); NEAT::Globals::getSingleton()->setParameterValue("MutateDemolishLinkProbability",0.0); cout << endl << "to the FT-NEAT values of: " << endl; cout << "MutateAddNodeProbability: " << NEAT::Globals::getSingleton()->getParameterValue("MutateAddNodeProbability") << endl; cout << "MutateAddLinkProbability: " << NEAT::Globals::getSingleton()->getParameterValue("MutateAddLinkProbability") << endl; cout << "MutateDemolishLinkProbability: " << NEAT::Globals::getSingleton()->getParameterValue("MutateDemolishLinkProbability") << endl << endl; if(experiments[currentSubExperiment]->getHybrid_FTMutateOnlyProbability() != -1.0) NEAT::Globals::getSingleton()->setParameterValue("MutateOnlyProbability", experiments[currentSubExperiment]->getHybrid_FTMutateOnlyProbability()); if(experiments[currentSubExperiment]->getHybrid_FTMutateLinkProbability() != -1.0) NEAT::Globals::getSingleton()->setParameterValue("MutateLinkProbability", experiments[currentSubExperiment]->getHybrid_FTMutateLinkProbability()); //THESE CAN COME OUT ONCE THIS WORKS cout << "MutateOnlyProbability" << NEAT::Globals::getSingleton()->getParameterValue("MutateOnlyProbability") << endl; cout << "MutateLinkProbability" << NEAT::Globals::getSingleton()->getParameterValue("MutateLinkProbability") << endl; } else { mutex::scoped_lock scoped_lock(*populationMutex); cout << "\nPRODUCING NEXT GENERATION\n"; produceNextGeneration(); } } if (experiments[currentSubExperiment]->performUserEvaluations()) { throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: TRIED TO USE INTERACTIVE EVOLUTION WITH NO GUI!"); } else { while (!running) { boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC_); xt.sec += 1; // boost::thread::sleep(xt); // Sleep for 1/2 second usleep(500000); } #ifdef INTERACTIVELYEVOLVINGSHAPES stringstream genNum; genNum << setw(5) << std::setfill('0') << generations; population->dumpLast(outputFileName +"_"+ genNum.str()+".xml",true,false); //print out xml file each generation #endif cout << "about to evaluatePopulation\n"; evaluatePopulation(); } #ifdef DEBUG_EXPRUN cout << "Finishing evaluations\n"; #endif finishEvaluations(); experimentRunPrintToGenChampFile(); #ifdef DEBUG_EXPRUN cout << "Evaluations Finished\n"; #endif } cout << "Experiment finished\n"; cout << "Saving Dump..."; population->dump(outputFileName+string("_pop.xml"),true,false); cout << "Done!\n"; cout << "Saving best individuals..."; string bestFileName = outputFileName.substr(0,outputFileName.length()-4)+string("_best.xml"); population->dumpBest(bestFileName,true,true); cout << "Done!\n"; cout << "Skippped deleting backup files because of problem with boost!"; //cout << "Deleting backup file..."; //boost::filesystem::remove(outputFileName+string(".backup.xml.gz")); //cout << "Done!\n"; #ifndef DEBUG_EXPRUN } catch (const std::exception &ex) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE(ex.what()); } catch (...) { cout << "CAUGHT ERROR AT " << __FILE__ << " : " << __LINE__ << endl; CREATE_PAUSE("AN UNKNOWN EXCEPTION HAS BEEN THROWN!"); } #endif }
void ExperimentRun::setupExperiment( int _experimentType, string _outputFileName ) { experimentType = _experimentType; outputFileName = _outputFileName; cout << "SETTING UP EXPERIMENT TYPE: " << experimentType << endl; cout << "Using output file: " << outputFileName << endl; string experimentName = outputFileName.substr(0, outputFileName.find(".")); switch (experimentType) { case EXPERIMENT_TIC_TAC_TOE: experiments.push_back(shared_ptr<Experiment>(new TicTacToeExperiment(""))); break; case EXPERIMENT_TIC_TAC_TOE_GAME: experiments.push_back(shared_ptr<Experiment>(new TicTacToeGameExperiment(""))); break; case EXPERIMENT_TIC_TAC_TOE_NO_GEOM_GAME: experiments.push_back(shared_ptr<Experiment>(new TicTacToeGameNoGeomExperiment(""))); break; case EXPERIMENT_XOR: experiments.push_back(shared_ptr<Experiment>(new XorExperiment(""))); break; case EXPERIMENT_FIND_POINT_EXPERIMENT: experiments.push_back(shared_ptr<Experiment>(new FindPointExperiment(""))); break; case EXPERIMENT_FIND_CLUSTER_EXPERIMENT: experiments.push_back(shared_ptr<Experiment>(new FindClusterExperiment(""))); break; case EXPERIMENT_FIND_CLUSTER_NO_GEOM_EXPERIMENT: experiments.push_back(shared_ptr<Experiment>(new FindClusterNoGeomExperiment(""))); break; case EXPERIMENT_CHECKERS: experiments.push_back(shared_ptr<Experiment>(new CheckersExperiment(""))); break; case EXPERIMENT_CHECKERS_NO_GEOM: experiments.push_back(shared_ptr<Experiment>(new CheckersExperimentNoGeom(""))); break; case EXPERIMENT_CHECKERS_ORIGINAL_FOGEL: experiments.push_back(shared_ptr<Experiment>(new CheckersExperimentOriginalFogel(""))); break; case EXPERIMENT_EVOLVE_MORPH_TRIMESH: experiments.push_back(shared_ptr<Experiment>(new EvolveMorphTrimeshExperiment(experimentName))); break; default: cout << string("ERROR: Unknown Experiment Type!\n"); throw CREATE_LOCATEDEXCEPTION_INFO("ERROR: Unknown Experiment Type!"); } for (int a=1;a<NUM_THREADS;a++) { experiments.push_back(shared_ptr<Experiment>(experiments[0]->clone())); } }
ModularNetwork GeneticIndividual::spawnPhenotypeStack() const { vector<NetworkNode *> networkNodes; for (int a=0;a<(int)nodes.size();a++) { if (!nodes[a].isEnabled()) continue; NetworkNode *networkNode; if (nodes[a].getType()==string("NetworkSensor")) networkNode = new NetworkNode(nodes[a].getName(),false,nodes[a].getActivationFunction()); else networkNode = new NetworkNode(nodes[a].getName(),true,nodes[a].getActivationFunction()); networkNodes.push_back(networkNode); } double linkGeneMinimumWeightForPhentoype = Globals::getSingleton()->getParameterValue("LinkGeneMinimumWeightForPhentoype"); vector<NetworkLink *> networkLinks; for (int a=0;a<(int)links.size();a++) { const GeneticLinkGene *linkGene = &links[a]; if (!linkGene->isEnabled()||( fabs(linkGene->getWeight())<linkGeneMinimumWeightForPhentoype )) continue; NetworkNode *fromNode=NULL; NetworkNode *toNode=NULL; bool create=true; int fromNodeIndex=-1,toNodeIndex=-1; for (int b=0;b<(int)nodes.size();b++) { //this holds because there's a match between genotype indicies and phenotype indicies if (nodes[b].getID()==links[a].getFromNodeID()) { fromNode = networkNodes[b]; fromNodeIndex = (int)b; } if (nodes[b].getID()==links[a].getToNodeID()) { toNode = networkNodes[b]; toNodeIndex = (int)b; } if (fromNode!=NULL&&toNode!=NULL) break; if ((b+1) == (int)nodes.size()) //couldn't find a nodeID. Node must have been disabled { create=false; break; } } if (fromNodeIndex==-1 || toNodeIndex==-1) { throw CREATE_LOCATEDEXCEPTION_INFO("ERROR!"); } if (create) networkLinks.push_back( new NetworkLink( fromNode, toNode, nodes[fromNodeIndex].getDrawingPosition()<nodes[toNodeIndex].getDrawingPosition(), links[a].getWeight() ) ); } ModularNetwork network(networkNodes,networkLinks); while (!networkNodes.empty()) { delete networkNodes[0]; networkNodes.erase(networkNodes.begin()); } while (!networkLinks.empty()) { delete networkLinks[0]; networkLinks.erase(networkLinks.begin()); } return network; }