/// <summary> /// Generates new students using genetic algorithms. /// See http://cgg.mff.cuni.cz/~pepca/prg022/luner.html for more details. /// </summary> public void DoReproduction() { // Sorts students using bubble-sort with respect to rating int i; int[] ids = new int[students.Length]; for (int j = 0; j < students.Length; j++) { ids[j] = j; } bool swaped = true; while (swaped) { swaped = false; for (i = 0; i < students.Length - 1; i++) { if (students[ids[i]].Rating < students[ids[i + 1]].Rating) { int temp = ids[i]; ids[i] = ids[i + 1]; ids[i + 1] = temp; swaped = true; } } } // First 1/3 mix together for (i = 0; i < students.Length * 2 / 3; i += 2) { // I select two students Log("Students " + ids[i] + " and " + ids[i + 1] + "has two children"); Gens[] gens = Gens.MixGens(students[ids[i]].Gens, students[ids[i + 1]].Gens); students[ids[i]] = new Student(this, gens[0]); students[ids[i + 1]] = new Student(this, gens[1]); } // The rest (2/3) is recreated randomly for (; i < students.Length; i++) { students[ids[i]] = new Student(this); } Log("New students created"); }
/// <summary> /// Generates new Gens for genetic algorithm /// See http://cgg.mff.cuni.cz/~pepca/prg022/luner.html for more details. /// </summary> /// <param name="parent1">Mather's gens</param> /// <param name="parent2">Father's gens</param> /// <returns>Two element array of gens (two children)</returns> static public Gens[] MixGens(Gens parent1, Gens parent2) { Gens[] result = new Gens[2]; int[] dna1, dna2; dna1 = parent1.GetCode(); dna2 = parent2.GetCode(); bool translate; if (Core.rn.Next(100) < 95) { translate = true; } else { translate = false; } for (int j = 0; j < GENS_LENGTH; j++) { // Translation if (translate && Core.rn.Next(2) == 0) { int temp = dna1[j]; dna1[j] = dna2[j]; dna2[j] = temp; } // Random mutation if (Core.rn.Next(100) < 10) { dna1[j] = Core.rn.Next(GENS_MAXS[j]); } if (Core.rn.Next(100) < 10) { dna2[j] = Core.rn.Next(GENS_MAXS[j]); } } result[0] = new Gens(dna1); result[1] = new Gens(dna2); return(result); }