/* Look at all the bugs in the bug_list. For each bug * that has enough health to reproduce, reproduce a new bug. * Put the new bug in the same square and have it head in the * same direction. * * Give both the new bug and the old bug 1/2 the energy of the * old bug. * * Mutate the genes of the new bug as follows. Choose two genes * at random. Increment one of those genes (by one) and decrement * the other gene (by one). * YOU MUST ensure * 1. that no genes ever get smaller than zero * 2. the total of the eight genes is always GENE_TOTAL * * Be sure to put the new bug in the bug_list (no need to update * the world, since you have two bugs in the same square anyway). */ void reproduceBugs(void) { int num_bugs = bug_list.size(); for (int k = 0; k < num_bugs; k += 1) { if (bug_list[k].health > REPRODUCE_HEALTH) { /* Make the new bug. */ Bug b = bug_list[k]; b.health /= 2; b.generation++; b.age = 0; mutateGenes(b.genes); bug_list[k].health /= 2; /* Update global statistics based on the new genes in b */ total_straight += b.genes[0]; total_right += b.genes[1]+b.genes[2]+b.genes[3]; total_left += b.genes[5]+b.genes[6]+b.genes[7]; total_back += b.genes[4]; /* Add b to the end of the global bug list */ bug_list.push_back(b); } } }
/* COMMENTS: <param> * The big if/else statement is to add variety to the mating (if the pop is > 10 then mate with the top 8. pop > 6 mate with top 4, etc..). * This whole function is not taking into account of gender's or position so it will need to be re-written once we have two seperate data structures, * one with males and the other with females. Also will need to take into account of proximity once we get there. * This also removes older animals; Maybe should move that to selection since it really isn't a part of the combination procedure. </param> */ void GA::combination(std::vector<std::shared_ptr<Animal>> &pop, int animalNum, int currentGen){ char sex; GAUtils gu = GAUtils(); if (pop.size() > 1) { sex = gu.randSex(); std::shared_ptr<Animal> mom, dad; int dRand, mRand; if (pop.size() >= 8) { dRand = gu.randIntGen(6); mRand = gu.randIntGen(6); dad = std::move(pop[dRand]); pop.erase(pop.begin() + dRand); mom = std::move(pop[mRand]); pop.erase(pop.begin() + mRand); } else if (pop.size() >= 7) { dRand = gu.randIntGen(5); mRand = gu.randIntGen(5); dad = std::move(pop[dRand]); pop.erase(pop.begin() + dRand); mom = std::move(pop[mRand]); pop.erase(pop.begin() + mRand); } else if (pop.size() >= 6) { dRand = gu.randIntGen(4); mRand = gu.randIntGen(4); dad = std::move(pop[dRand]); pop.erase(pop.begin() + dRand); mom = std::move(pop[mRand]); pop.erase(pop.begin() + mRand); } else if (pop.size() >= 5) { dRand = gu.randIntGen(3); mRand = gu.randIntGen(3); dad = std::move(pop[dRand]); pop.erase(pop.begin() + dRand); mom = std::move(pop[mRand]); pop.erase(pop.begin() + mRand); } else if (pop.size() >= 4) { dRand = gu.randIntGen(2); mRand = gu.randIntGen(2); dad = std::move(pop[dRand]); pop.erase(pop.begin() + dRand); mom = std::move(pop[mRand]); pop.erase(pop.begin() + mRand); } else if (pop.size() >= 3) { dRand = gu.randIntGen(1); mRand = gu.randIntGen(1); dad = std::move(pop[dRand]); pop.erase(pop.begin() + dRand); mom = std::move(pop[mRand]); pop.erase(pop.begin() + mRand); } else { dad = std::move(pop[0]); pop.erase(pop.begin()); mom = std::move(pop[0]); pop.erase(pop.begin()); } int cp = (gu.randIntGen(mom->getGeneSize())); std::vector <float> childGenes; std::vector<float> dadGenes = dad->getGenes(); std::vector<float> momGenes = mom->getGenes(); for (int i = 0; i < dadGenes.size(); i++){ childGenes.push_back((dadGenes[i] + momGenes[i]) / 2.0); } //for (int i = cp; i < mom->getGeneSize(); i++){ // childGenes.push_back(momGenes[i]); //} bool hasMutation = false; if (gu.randIntGen(100) <= 25) { mutateGenes(childGenes); hasMutation = true; } float fn = gu.fitnessSingle(childGenes); std::shared_ptr<Animal> child(new Animal(dad->getName())); std::string cTag; child->setFitness(fn); child->setGenes(childGenes); child->setSex(sex); child->setGeneration(currentGen); child->setTypeID(mom->getTypeID()); child->setPosition(mom->getXPos(), mom->getYPos(), 0); if (hasMutation) cTag.append(mom->getName() + "_" + std::to_string(currentGen) + "_" + std::to_string(animalNum + 1) + "m"); else cTag.append(mom->getName() + "_" + std::to_string(currentGen) + "_" + std::to_string(animalNum + 1)); child->setTag(cTag); combination(pop, animalNum+1, currentGen); pop.push_back(std::move(mom)); pop.push_back(std::move(dad)); pop.push_back(std::move(child)); } }