void ModNeatExperiment7::createIndividualImage(wxDC &drawContext,shared_ptr<NEAT::GeneticIndividual> individual) { if (lastIndividualSeen!=individual) { screen << "Repopulating substrate\n"; populateSubstrate(individual); lastIndividualSeen = individual; } processEvaluation(individual,&drawContext,userBoardState); }
void ShapesExperiment::processGroup(shared_ptr<NEAT::GeneticGeneration> generation) { //if doing interactive evolution...call processInteractiveEvaluation() and skip rest of this function #ifdef INTERACTIVELYEVOLVINGSHAPES processInteractiveEvaluation(generation->getGenerationNumber()); return; #endif for(int z=0;z< group.size();z++) { shared_ptr<NEAT::GeneticIndividual> individual = group[z]; #if SHAPES_EXPERIMENT_DEBUG cout << "in ShapesExperiment.cpp::processIndividual, processing individual: " << individual << endl; #endif double fitness = 0; fitness = processEvaluation(individual); if(fitness > std::numeric_limits<double>::max()) { cout << "error: the max fitness is greater than the size of the double. " << endl; cout << "max double size is: : " << std::numeric_limits<double>::max() << endl; exit(88); } if (fitness < 0) { cout << "Fitness Less Than Zero!!!, it is: " << fitness << "\n"; exit(10); } #if SHAPES_EXPERIMENT_DEBUG cout << "Individual Evaluation complete!\n"; printf("fitness: %f\n", fitness); #endif cout << "Individual Evaluation complete!\n"; cout << "fitness: " << fitness << endl; individual->reward(fitness); if (false) //to print cppn { printNetworkCPPN(individual); } } }
void ModNeatExperiment7::processGroup(shared_ptr<NEAT::GeneticGeneration> generation) { // FORK a number of processes equal to the number of individuals we are going to process // getGroupSize is the size of ::getGroupCapacity const int groupSize = getGroupSize(); pid_t* pids = new pid_t[groupSize]; for (int i = 0; i < groupSize; ++i) { // increment individual count if the current individual number is smaller than the population size. // if it is not, then it is the first individual of the next population. // this is an ugly workaround since it is not easily possible to get the current individual or generation // from HyperNEAT itself, thus it needs to be managed by ourselves. if(currIndividual == popSize) { // reset individual and increase generation number currIndividual = 1; currGeneration++; } else { // this is just a next individual in the current generation currIndividual++; } screen << "processing generation: " << currGeneration << ", individual: " << currIndividual << ", on thread: " << i << endl; shared_ptr<NEAT::GeneticIndividual> individual = group[i]; // avoid 0 fitness if (individual->getFitness() <= 0) individual->setFitness(0.000001); // spawn child process after 1 sec (webotsrc test) usleep(1000 * 1000); pids[i] = fork(); // child code if (pids[i] == 0) { // code only executed by child process // evaluate individual and get fitness double fitness = processEvaluation(individual, NULL, i); // write fitness to a named textfile stringstream ss; ss << i; string temp_str = "simulation" + ss.str() + ".txt"; // write fitness to textfile ofstream a_file (temp_str.c_str()); a_file << fitness; a_file.close(); exit(0); // exit child process successfully } } // WAIT for each individual process and only when all have exited, continue main process for (int i = 0; i < groupSize; ++i) { int status; while (-1 == waitpid(pids[i], &status, 0)) { if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { screen << "Process " << i << " (pid " << pids[i] << ") failed" << endl; exit(1); } } } // READ back the fitness values and for (int i = 0; i < groupSize; ++i) { // get individual to reward fitness too shared_ptr<NEAT::GeneticIndividual> individual = group[i]; // Opens for reading the file stringstream ss; ss << i; string temp_str = "simulation" + ss.str() + ".txt"; ifstream b_file (temp_str.c_str()); // Reads one string from the file string fitness; b_file >> fitness; b_file.close(); // reward this individual its fitness individual->reward(abs(::atof(fitness.c_str())) + 0.000001); } }