// Return 0 if everything is OK, non-zero if error. If we did not set anything // then we return non-zero (this is not an error, but we indicate that we did // not do anything). // The set method must set both the GA's parameter and the value in the // parameter list (kind of stupid to maintain two copies of the same data, but // oh well). The call to set on params is redundant for the times when this // method is called *after* the parameter list has been updated, but it is // necessary when this method is called directly by the user. int GAGeneticAlgorithm::setptr(const char* name, const void* value){ int status=1; params.set(name, value); // redundant for some cases, but not others if(strcmp(name, gaNnBestGenomes) == 0 || strcmp(name, gaSNnBestGenomes) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif nBestGenomes(*((int*)value)); status = 0; } else if(strcmp(name, gaNpopulationSize) == 0 || strcmp(name, gaSNpopulationSize) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif populationSize(*((int*)value)); status = 0; } else if(strcmp(name, gaNminimaxi) == 0 || strcmp(name, gaSNminimaxi) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif minimaxi(*((int*)value)); status = 0; } else if(strcmp(name, gaNnGenerations) == 0 || strcmp(name, gaSNnGenerations) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif nGenerations(*((int*)value)); status = 0; } else if(strcmp(name, gaNpConvergence) == 0 || strcmp(name, gaSNpConvergence) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((float*)value) << "'\n"; #endif pConvergence(*((float*)value)); status = 0; } else if(strcmp(name, gaNnConvergence) == 0 || strcmp(name, gaSNnConvergence) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif nConvergence(*((int*)value)); status = 0; } else if(strcmp(name, gaNpCrossover) == 0 || strcmp(name, gaSNpCrossover) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((float*)value) << "'\n"; #endif pCrossover(*((float*)value)); status = 0; } else if(strcmp(name, gaNpMutation) == 0 || strcmp(name, gaSNpMutation) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((float*)value) << "'\n"; #endif pMutation(*((float*)value)); status = 0; } else if(strcmp(name,gaNscoreFrequency) == 0 || strcmp(name,gaSNscoreFrequency) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif stats.scoreFrequency(*((int*)value)); status = 0; } else if(strcmp(name,gaNflushFrequency) == 0 || strcmp(name,gaSNflushFrequency) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif stats.flushFrequency(*((int*)value)); status = 0; } else if(strcmp(name,gaNrecordDiversity) == 0 || strcmp(name,gaSNrecordDiversity) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif stats.recordDiversity(*((int*)value) ? gaTrue : gaFalse); status = 0; } else if(strcmp(name,gaNselectScores) == 0 || strcmp(name,gaSNselectScores)==0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << *((int*)value) << "'\n"; #endif stats.selectScores(*((int*)value)); status = 0; } else if(strcmp(name,gaNscoreFilename) == 0 || strcmp(name,gaSNscoreFilename) == 0){ #ifdef GA_DEBUG cerr << "GAGeneticAlgorithm::setptr\n setting '" << name << "' to '" << ((char*)value) << "'\n"; #endif char tmpname[64]; memcpy(tmpname, value, strlen((char*)value)+1); stats.scoreFilename(tmpname); status = 0; } return status; }
int main (int argc, char **argv) { try { //Parser exceptions printf("Constructing parser...\n"); TCLAP::CmdLine cmd("Simulator - simulates test system database files",' ',"0"); TCLAP::ValueArg<std::string> filename("f","filename","Database file name",false,"sys.db","string"); TCLAP::ValueArg<double> fieldStrength("","fieldStrength","Target simulation field strength",false,0.1,"double"); TCLAP::ValueArg<int> numGens("","numGens","Number of iterations to simulate",false,300,"int"); TCLAP::ValueArg<double> alpha("","alpha","Weight of squared error to spacing relaxation",false,0.99,"double"); TCLAP::ValueArg<int> populationSize("","populationSize","Size of test population (genetic algorithm only)",false,100,"int"); TCLAP::ValueArg<int> maxStepTime("","maxStepTime","Maximum time (MS) to search for a better next-state (simulated annealing only)",false,1000,"int"); TCLAP::ValueArg<double> mutationRate("","mutationRate","Sigma of normal mutation (genetic algorithm only)",false,0.1,"double"); TCLAP::ValueArg<double> startingTemperature("","startTemp","Starting normal temperature (simulated annealing only)",false,1,"double"); TCLAP::ValueArg<double> endingTemperature("","endTemp","Ending normal temperature (simulated annealing only)",false,0,"double"); cmd.add(filename); cmd.add(fieldStrength); cmd.add(numGens); cmd.add(alpha); cmd.add(populationSize); cmd.add(maxStepTime); cmd.add(mutationRate); cmd.add(startingTemperature); cmd.add(endingTemperature); //Add XOR switches TCLAP::SwitchArg annealSwitch("","anneal","Use simulated annealing algorithm",false); TCLAP::SwitchArg geneticSwitch("","genetic","Use genetic optimization algorithm",false); std::vector<TCLAP::Arg*> xorlist; xorlist.push_back(&annealSwitch); xorlist.push_back(&geneticSwitch); cmd.xorAdd(xorlist); //Parse arguments printf("Parsing options...\n"); cmd.parse(argc,argv); //Retrieve options std::string filename_v = filename.getValue(); double fieldStrength_v = fieldStrength.getValue(); int numGens_v = numGens.getValue(); double alpha_v = alpha.getValue(); int populationSize_v = populationSize.getValue(); int maxStepTime_v = maxStepTime.getValue(); double mutationRate_v = mutationRate.getValue(); double startingTemperature_v = startingTemperature.getValue(); double endingTemperature_v = endingTemperature.getValue(); //Load lamina and source from the database Database db(filename_v); if (!db.getTotalParticlesInDB() || db.getMaxGenerationNumber()) { printf("Database is empty or already simulated.\n"); return 0; } Lamina lamina = db.getLaminaParticlesForGeneration(0); Source source = db.getSourceParticles(); //Create the appropriate simulator Simulation* s = nullptr; if (annealSwitch.getValue()) { s = new AnnealingSimulation(lamina,source,fieldStrength_v,numGens_v,alpha_v,maxStepTime_v,startingTemperature_v, endingTemperature_v); } else if (geneticSwitch.getValue()) { s = new GeneticAlgorithm(lamina,source,fieldStrength_v,numGens_v,alpha_v,populationSize_v,mutationRate_v); } else { printf("Should have selected an operation mode...\n"); return 0; } //Step the simulator and save out the generations while (s->step()) { int generationNumber = s->getGeneration(); double currentEnergy = s->finalEnergy(); printf("Simulating generation %d, energy = %f\n",generationNumber,currentEnergy); db.insertLaminaParticles(s->getLamina(),generationNumber); } //Print some final statistics printf("\nStarting Energy: %f\n",s->startingEnergy()); printf("Final Energy: %f\n",s->finalEnergy()); //Save out the fitness log db.insertFitnessLog(s->getFitnessLog()); //End printf("Process completed.\n"); delete s; } catch (TCLAP::ArgException &e) { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; return 1; } return 0; }