//Does a mutation and calculates fitness private Individual MutateByBitFlip(Individual child, int bitstoflip) { List<int> positions = new List<int>(); for(int i = 0; i < bitstoflip; i++) { int randpos; do { randpos = randomgenerator.Next(child.Chromosome.Length); } while(positions.Contains(randpos)); positions.Add(randpos); } foreach(int pos in positions) { if(child.Chromosome.IsSet(pos)) child.Chromosome.Clear(pos); else child.Chromosome.Set(pos); } int pathscut = 0; child.Fitness = FitnessEvaluation(data.NetworkPaths, child.Chromosome, config.PenaltyCoefficient, out pathscut); child.PathsCut = pathscut; return child; }
public bool Dominates(Individual other) { if(this.pathscut >= other.pathscut && this.chromosome.SetBits < other.chromosome.SetBits) return true; if(this.pathscut > other.pathscut && this.chromosome.SetBits <= other.chromosome.SetBits) return true; return false; }
//Generates a child individual using uniform crossover //DOES NOT SET FITNESS YET, THAT IS DONE AFTER MUTATION private Individual GenerateChildUniform(Individual parentA, Individual parentB) { Individual child = new Individual(); child.Chromosome = new BetterBitArray(parentA.Chromosome.Length); for(int i = 0; i < parentA.Chromosome.Length; i++) { //Either a 1 or 0. If it's one we take the bit from parent A, else we take it from parent B. if(Convert.ToBoolean(randomgenerator.Next(2))) { if(parentA.Chromosome.IsSet(i)) { child.Chromosome.Set(i); } else { child.Chromosome.Clear(i); } } else { if(parentB.Chromosome.IsSet(i)) child.Chromosome.Set(i); else child.Chromosome.Clear(i); } } return child; }
//Generates a child individual using n-point crossover //DOES NOT SET FITNESS YET, THAT IS DONE AFTER MUTATION private Individual GenerateChildNPoint(Individual[] parents, int crossovers) { List<int> positions = new List<int>(); Individual child = new Individual(); child.Chromosome = new BetterBitArray(parents[0].Chromosome.Length); //Get the positions to crossover at for(int i = 0; i < crossovers; i++) { int randpos; do { randpos = randomgenerator.Next(parents[0].Chromosome.Length); } while(positions.Contains(randpos)); positions.Add(randpos); } positions.Sort(); int parentiter = 0; int lastcrossover = 0; //For each position foreach(int point in positions) { //Create a mask BetterBitArray mask = new BetterBitArray(parents[0].Chromosome.Length); //Set the bits that are in the range of this crossover on for the mask. //Ex: if the crossover point is 6 and we are currently at the front // the mask looks like 1111110000... for(int i = lastcrossover; i <= point; i++) { mask.Set(i); } //Clone the parent so we don't write over it. BetterBitArray parent = parents[parentiter].Chromosome; //Or the current child with the masked out part of the parent. child.Chromosome = child.Chromosome.Or(parent.And(mask)); //Switch the parents (done this way because it was originally allowed to have more //than 2 parents. /sigh parentiter *= -1; parentiter += 1; } return child; }
//Distance between a and b using paths cut and routers turned off (chromosome set bits) public double Distance(Individual a, Individual b) { return Math.Sqrt((a.PathsCut - b.PathsCut) * (a.PathsCut - b.PathsCut) + (a.Chromosome.SetBits - b.Chromosome.SetBits) * (a.Chromosome.SetBits - b.Chromosome.SetBits)); }
//Does a mutation and calculates fitness private Individual MutateByBitFlip(Individual child, int bitstoflip) { List<int> positions = new List<int>(); for(int i = 0; i < bitstoflip; i++) { int randpos; do { randpos = randomgenerator.Next(child.Chromosome.Count); } while(positions.Contains(randpos)); positions.Add(randpos); } foreach(int pos in positions) { child.Chromosome.Set(pos, !child.Chromosome.Get(pos)); if(child.Chromosome.Get(pos)) child.BitsSet++; else child.BitsSet--; } child.Fitness = FitnessEvaluation(data.NetworkPaths, child.Chromosome, child.BitsSet, config.PenaltyCoefficient); return child; }
//Generates a child individual using uniform crossover //DOES NOT SET FITNESS YET, THAT IS DONE AFTER MUTATION private Individual GenerateChildUniform(Individual parentA, Individual parentB) { Individual child = new Individual(); child.Chromosome = new BitArray(parentA.Chromosome.Count); child.BitsSet = 0; for(int i = 0; i < parentA.Chromosome.Count; i++) { //Either a 1 or 0. If it's one we take the bit from parent A, else we take it from parent B. if(Convert.ToBoolean(randomgenerator.Next(2))) { child.Chromosome.Set(i, parentA.Chromosome.Get(i)); if(parentA.Chromosome.Get(i)) child.BitsSet++; } else { child.Chromosome.Set(i, parentB.Chromosome.Get(i)); if(parentB.Chromosome.Get(i)) child.BitsSet++; } } return child; }