/* * A random index is selected. * The two selected chromosomes cross from this index.For example, * INPUT * firstChromosome=100011000101101001111000001110010 * secondChromosome=111011101101110000100011111011110 * index=9 * * RESULT * firstChromosome=10001100 1101110000100011111011110 * secondChromosome=111011100 101101001111000001110010 * */ private static void CrossingOver(GeneticCreater geneticCreater, int firstChromosome, int secondChromosome) { int willDivideIndex = random.Next(1, geneticCreater.chromosomeGeneSize - 1); if (GeneticCreater.writeActive) { Console.WriteLine("First: " + firstChromosome + " Second: " + secondChromosome + " Index: " + willDivideIndex); } int tempIndexSize = geneticCreater.chromosomeGeneSize - willDivideIndex; List <Bit> tempTrack = new List <Bit>(tempIndexSize); for (int i = willDivideIndex; i < geneticCreater.chromosomeGeneSize; i++) { bool val = geneticCreater.chromosomes[firstChromosome].binaryVal[i].value; geneticCreater.chromosomes[firstChromosome].binaryVal[i].value = geneticCreater.chromosomes[secondChromosome].binaryVal[i].value; geneticCreater.chromosomes[secondChromosome].binaryVal[i].value = val; } string f = Bit.BitsListToString(geneticCreater.chromosomes[firstChromosome].binaryVal); string s = Bit.BitsListToString(geneticCreater.chromosomes[secondChromosome].binaryVal); if (GeneticCreater.writeActive) { Console.WriteLine("first: " + f); Console.WriteLine("second: " + s); } }
// every generation is stored in the generations list private static void AddNewGeneration(List <Generation> generations, GeneticCreater geneticCreater, int index) { Generation generation = new Generation(index); generation.chromosomes = geneticCreater.chromosomes; generation.maxFitnessChoromozomeIndex = geneticCreater.maxFitnessIndex; generation.maxFitnessVal = geneticCreater.maxFitnessVal; generation.sumOfFitness = geneticCreater.sumOfFitness; generations.Add(generation); generation.GenerationWriter(); }
/* * Random values are generated as much as the population size. Chromosomes are matched according to these values. */ private static void TurningWheelRoulette(GeneticCreater geneticCreater) { if (GeneticCreater.writeActive) { Console.WriteLine("\n***********Turning Wheel Roulette***********\n"); } List <double> rndDoubles = GetRandomDoubles(geneticCreater.popopulationSize); List <int> matchList = GetMatchList(geneticCreater.chromosomes, rndDoubles); geneticCreater.chromosomes = chromosomesMatch(geneticCreater.chromosomes, matchList); geneticCreater.chromosomesWriter(false); }
// List<chromosome> -> One Generation public static List <Generation> ProducerGenerations(GeneticCreater geneticCreater) { List <Generation> generations = new List <Generation>(geneticCreater.numberOfGeneration); for (int i = 0; i < geneticCreater.numberOfGeneration; i++) { TurningWheelRoulette(geneticCreater); CrossingOperation(geneticCreater); // Last generation mustn't mutation operation. if (i != (geneticCreater.numberOfGeneration - 1)) { MutationOperation(geneticCreater); } geneticCreater.NewGenerationCalculater(); AddNewGeneration(generations, geneticCreater, i); geneticCreater.chromosomesWriter(true); } geneticCreater.chromosomesWriter(true); return(generations); }
/* * For example, there are 20 chromosomes consisting of 33 bits. In total, 33 * 20 = 660 bits. * 660 random values are generated. Chromosomes in the index smaller than the mutation probability will mutate. * For example, the selected for mutate bit is 51. * 51/33 = 1, which value is the chromosome * 51 mod 33 = 18, this value is the Ch index value. */ private static void MutationOperation(GeneticCreater geneticCreater) { if (GeneticCreater.writeActive) { Console.WriteLine("\n***********Mutation Process***********\n"); } int sumOfBitCount = (geneticCreater.chromosomeGeneSize * geneticCreater.chromosomes.Count) - 1; List <double> doubles = GetRandomDoubles(sumOfBitCount); List <int> mutationIndex = new List <int>(); for (int i = 0; i < doubles.Count; i++) { if (doubles[i] < geneticCreater.mutationVal) { mutationIndex.Add(i); } } foreach (var index in mutationIndex) { int modVal = index % geneticCreater.chromosomeGeneSize; int remaindVal = index / geneticCreater.chromosomeGeneSize; Bit bit; if (Bit.GetRandomBool()) { bit = new Bit('1'); } else { bit = new Bit('0'); } if (GeneticCreater.writeActive) { Console.WriteLine("Mutation Index : {0} \t chromosome : {1} \t Ch Index : {2}", index, remaindVal, modVal); Console.WriteLine("Old Val: {0} \t New Val: {1}\n", Bit.BitToChar(geneticCreater.chromosomes[remaindVal].binaryVal[modVal]), Bit.BitToChar(bit)); } geneticCreater.chromosomes[remaindVal].binaryVal[modVal].value = bit.value; } }
/* * Random values are generated as much as the population size. * The chromosomes in the index, which are less than the possibility of crossing, are suitable for crossing. * The amount of chromosomes selected must be dual. * The chromosomes are crossed from an index randomly selected in order. */ private static void CrossingOperation(GeneticCreater geneticCreater) { if (GeneticCreater.writeActive) { Console.WriteLine("\n***********Crossing Over***********\n"); } List <double> rndDoubles = GetRandomDoubles(geneticCreater.popopulationSize); List <int> crossIndex = new List <int>(); for (int i = 0; i < rndDoubles.Count; i++) { if (rndDoubles[i] < geneticCreater.crossingVal) { crossIndex.Add(i); } } if (CheckCrossingDual(ref crossIndex)) { for (int i = 0; i < crossIndex.Count; i += 2) { CrossingOver(geneticCreater, crossIndex[i], crossIndex[i + 1]); } } }