public static Hunter[] Crossover(Hunter a, Hunter b) { Hunter[] ret = new Hunter[2]; string bDebugStr = b.HumanReadableHunter, aDebugStr = a.HumanReadableHunter; ret[0] = new Hunter().StripChromosomes(); ret[1] = new Hunter().StripChromosomes(); Hunter target = ret[0], notTarget = ret[1], mostChromosomes; Chromosome[] temp = new Chromosome[2];//If a has 7 Chromosomes, and b has 3, //we want to end as soon as either fails //So if a and b both have count 3, a is true, but b is false, so the comparison fails List <int> aCrossed = new List <int>(a.myChromosomes.Count), bCrossed = new List <int>(b.myChromosomes.Count); List <int> mostCrossed; int max = Math.Min(a.myChromosomes.Count, b.myChromosomes.Count), point1 = OptoGlobals.RNG.Next(0, max), point2 = OptoGlobals.RNG.Next(point1, max); Hunter maxHunter = a.myChromosomes.Count == max?b:a; #region CrossoverModeBlock switch (OptoGlobals.CrossoverMode) { case OptoGlobals.CrossoverModes.Uniform: for (int i = 0; i < max; ++i) { //Trying a form of uniform crossover, 2 point //just swapping chromosomes, not crossing over at that level temp = Chromosome.CrossOver(a[i].deepCopy(), b[i].deepCopy()); target.AddChromosome(temp[0]); notTarget.AddChromosome(temp[1]); aCrossed.Add(i); bCrossed.Add(i); if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } } for (int i = max; i < maxHunter.myChromosomes.Count; ++i) { target.AddChromosome(maxHunter[i]); if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } } break; case OptoGlobals.CrossoverModes.TwoPointHunter: for (int i = 0; i < max; ++i) { //Trying a form of uniform crossover, 2 point //just swapping chromosomes, not crossing over at that level //temp = Chromosome.CrossOver(a[i], b[i]); target.AddChromosome(a[i]); notTarget.AddChromosome(b[i]); aCrossed.Add(i); bCrossed.Add(i); if (i == point1 || i == point2) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } } break; case OptoGlobals.CrossoverModes.SinglePointHunter: for (int i = 0; i < max; ++i) { //Trying a form of uniform crossover, 2 point //just swapping chromosomes, not crossing over at that level //temp = Chromosome.CrossOver(a[i], b[i]); target.AddChromosome(a[i]); notTarget.AddChromosome(b[i]); aCrossed.Add(i); bCrossed.Add(i); if (i == point1) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } } break; case OptoGlobals.CrossoverModes.TwoPointChromosome: for (int i = 0; i < max; ++i) { //Trying a form of uniform crossover, 2 point //just swapping chromosomes, not crossing over at that level temp = Chromosome.CrossOver(a[i], b[i]); target.AddChromosome(temp[0]); notTarget.AddChromosome(temp[1]); aCrossed.Add(i); bCrossed.Add(i); if (i == point1 || i == point2) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } } break; case OptoGlobals.CrossoverModes.SinglePointChromosome: for (int i = 0; i < max; ++i) { //Trying a form of uniform crossover, 2 point //just swapping chromosomes, not crossing over at that level temp = Chromosome.CrossOver(a[i], b[i]); target.AddChromosome(temp[0]); notTarget.AddChromosome(temp[1]); aCrossed.Add(i); bCrossed.Add(i); if (i == point1) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } } break; case OptoGlobals.CrossoverModes.RandomHunter: while (aCrossed.Count != a.myChromosomes.Count && bCrossed.Count != b.myChromosomes.Count) { int i = SupportingFunctions.GetUnpickedInt(a.myChromosomes.Count, aCrossed); int j = SupportingFunctions.GetUnpickedInt(b.myChromosomes.Count, bCrossed); if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } //temp = Chromosome.CrossOver(a[i], b[j]); target.AddChromosome(a[i]); notTarget.AddChromosome(b[j]); aCrossed.Add(i); bCrossed.Add(j); } break; case OptoGlobals.CrossoverModes.RandomChromosome: while (aCrossed.Count != a.myChromosomes.Count && bCrossed.Count != b.myChromosomes.Count) { int i = SupportingFunctions.GetUnpickedInt(a.myChromosomes.Count, aCrossed); int j = SupportingFunctions.GetUnpickedInt(b.myChromosomes.Count, bCrossed); if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } temp = Chromosome.CrossOver(a[i], b[j]); target.AddChromosome(temp[0]); notTarget.AddChromosome(temp[1]); aCrossed.Add(i); bCrossed.Add(j); } break; } #endregion if (aCrossed.Count == a.myChromosomes.Count) { mostChromosomes = b; mostCrossed = bCrossed; } else { mostChromosomes = a; mostCrossed = aCrossed; } //Randomly distribute the remaining Chromosomes while (mostCrossed.Count != mostChromosomes.myChromosomes.Count) { if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) { switchTargets(ret[0], ret[1], ref target, ref notTarget); } int i = SupportingFunctions.GetUnpickedInt(mostChromosomes.myChromosomes.Count, mostCrossed); target.AddChromosome(mostChromosomes[i]); mostCrossed.Add(i); } string aOutStr = a.HumanReadableHunter, bOutStr = b.HumanReadableHunter; Debug.Assert(aOutStr == aDebugStr && bOutStr == bDebugStr); ret[0].updateCellNum(); ret[1].updateCellNum(); return(ret); /* Hunter[] ret = new Hunter[2]; * ret[0] = new Hunter().StripChromosomes(); * ret[1] = new Hunter().StripChromosomes(); * Hunter target = ret[0], notTarget = ret[1], mostChromosomes; * Chromosome[] temp = new Chromosome[2]; * int min = Math.Min(a.myChromosomes.Count, b.myChromosomes.Count); * for (int i = 0; i < min; ++i) * { * if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) Hunter.switchTargets(ret[0], ret[1], ref target, ref notTarget); * temp = Chromosome.CrossOver(a[i], b[i]); * target[i] = temp[0]; * notTarget[i] = temp[1]; * } * * int max = Math.Max(a.myChromosomes.Count, b.myChromosomes.Count); * if (max == a.myChromosomes.Count) mostChromosomes = a; * else mostChromosomes = b; * * for (int i = min; i < max; i++) * { * if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) switchTargets(ret[0], ret[1], ref target, ref notTarget); * if (mostChromosomes[i] != null) * target[i] = mostChromosomes[i]; * } * ret[0].updateCellNum(); * ret[1].updateCellNum(); * return ret; */ }
protected Hunter(Chromosome x) : this() { myChromosomes = new List <Chromosome>(); myChromosomes.RemoveAt(0); this.AddChromosome(x); }
public void AddChromosome(Chromosome x) { x.updateCellNum(); myChromosomes.Add(x.deepCopy()); }