Ejemplo n.º 1
0
/* 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);
        }
    }	
}
Ejemplo n.º 2
0
/* 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));
	}



}