public Individual(double fitness, BetterBitArray chromosome) { this.fitness = fitness; this.chromosome = chromosome; this.paretofrontrank = 1; crowdingdistance = 1000000.0; }
//Runs the algoritm for number of iterations public override void Run(Configuration config) { log = new RandomLogSpecification(data.DataFileName, config.RandomSeed, config.NumberOfRuns, config.PenaltyCoefficient); solution = new SolutionSpecification(); BetterBitArray routerswitches = new BetterBitArray((int)data.RouterCount); double highestfitness = 0.0; BetterBitArray best = new BetterBitArray((int)data.RouterCount); for(int i = 0; i < config.NumberOfRuns; i++) { routerswitches = new BetterBitArray((int)data.RouterCount); int numbertoswitch = randomgenerator.Next((int)data.RouterCount); for(int j = 0; j < numbertoswitch; j++) { int switching; while(routerswitches.IsSet(switching = randomgenerator.Next((int)data.RouterCount)) == true); routerswitches.Set(switching); } int pathscut = 0; double fitness = FitnessEvaluation(data.NetworkPaths, routerswitches, config.PenaltyCoefficient, out pathscut); if(fitness > highestfitness) { ((RandomLogSpecification)log).AddEvaluation(i, fitness); highestfitness = fitness; best = routerswitches; } } solution.RoutersTurnedOff = ExtensionMethods.ConvertBitArrayToOffRouterNumbers(best, data.HostCount); }
//Evaluates fitness by looking at the amount of routers switched. public override double FitnessEvaluation(List<Path> paths, BetterBitArray routerswitches, double penaltycoefficient, out int pathscut) { double fitness = 100.0 * (((double)routerswitches.SetBits / (double)routerswitches.Length) * -1.0 + 1.0); fitness -= penaltycoefficient * PenaltyFunction(paths, routerswitches, out pathscut); fitnessevaluations++; return fitness; }
public Individual() { fitness = 0.0; pathscut = 0; chromosome = new BetterBitArray(1); paretofrontrank = 1; crowdingdistance = 1000000.0; }
//numberofhosts is so we can translate the paths to be based off 0 not //numberofhosts. public Path(List<int> nodes, int numberofrouters, int numberofhosts) { this.pathnodes = new BetterBitArray(numberofrouters); this.hostnumber = nodes[0]; nodes.Remove(nodes[0]); foreach(int node in nodes) { this.pathnodes.Set(node - numberofhosts); } }
public static List<int> ConvertBitArrayToOffRouterNumbers(BetterBitArray ba, uint hostoffset) { List<int> routers = new List<int>(); for(int i = 0; i < ba.Length; i++) { if(ba.IsSet(i)) routers.Add((int)(i + hostoffset)); } return routers; }
public BetterBitArray Not() { BetterBitArray newba = new BetterBitArray(); newba.bitholder = new int[bitholder.Length]; for(int i = 0; i < bitholder.Length; i++) { newba.bitholder[i] = ~bitholder[i]; } return newba; }
public bool IsEqualTo(BetterBitArray right) { if(this.Length != right.Length) throw new Exception("Trying to compare bit arrays of different sizes!"); for(int i = 0; i < bitholder.Length; i++) { if(right.bitholder[i] != bitholder[i]) return false; } return true; }
public BetterBitArray Or(BetterBitArray rightside) { if(rightside.bitholder.Length != bitholder.Length) throw new Exception("Trying to or 2 different sized bit arrays!"); BetterBitArray newba = new BetterBitArray(); newba.bitholder = new int[bitholder.Length]; for(int i = 0; i < bitholder.Length; i++) { newba.bitholder[i] = bitholder[i] | rightside.bitholder[i]; } return newba; }
public BetterBitArray And(BetterBitArray rightside) { if(rightside.bitholder.Length != bitholder.Length) throw new Exception("Trying to and 2 different sized bit arrays!"); BetterBitArray newba = new BetterBitArray(); newba.bitholder = new int[bitholder.Length]; newba.Length = rightside.Length; newba.SetBits = 0; for(int i = 0; i < bitholder.Length; i++) { newba.bitholder[i] = bitholder[i] & rightside.bitholder[i]; newba.SetBits += SparseBitcount(newba.bitholder[i]); } return newba; }
//Evalueates penalty by the amount of paths cut. public override double PenaltyFunction(List<Path> paths, BetterBitArray routerswitches, out int pathscut) { //When all paths are cut, penaltycoeff = 0.0 //When 0 paths are cut, penaltycoeff = 1.0 double penaltycoeff = 1.0; pathscut = 0; foreach(Path p in paths) { if(IsPathCut(p.PathNodesInBits, routerswitches)) { penaltycoeff -= 1.0 / (double)paths.Count; pathscut++; } } return penaltycoeff; }
//Evaluates penalty by the amount of paths cut. public override double PenaltyFunction(List<Path> paths, BetterBitArray routerswitches, out int pathscut) { //When all paths are cut, penaltycoeff = 0.0 //When 0 paths are cut, penaltycoeff = 1.0 double penaltycoeff = 1.0; pathscut = 0; foreach(Path p in paths) { Stopwatch pathcuttime = Stopwatch.StartNew(); if(IsPathCut(p.PathNodesInBits, routerswitches)) { penaltycoeff -= 1.0 / (double)paths.Count; pathscut++; } pathcuttime.Stop(); //Console.WriteLine("Checking path cut time(ms): " + pathcuttime.Elapsed.TotalMilliseconds); } return penaltycoeff; }
//Uses a bit mask to see if a path is cut by switching routers (on bits) in roterswitches off. protected bool IsPathCut(BetterBitArray path, BetterBitArray routerswitches) { return (path.IsNotEqualTo(path.And(routerswitches.Not()))); }
public abstract double PenaltyFunction(List<Path> paths, BetterBitArray routerswitches, out int pathscut);
public abstract double FitnessEvaluation(List<Path> paths, BetterBitArray routerswitches, double penaltycoefficient, out int pathscut);
public Path() { this.pathnodes = new BetterBitArray(0); }
public BetterBitArray Xor(BetterBitArray rightside) { if(rightside.bitholder.Length != bitholder.Length) throw new Exception("Trying to xor 2 different sized bit arrays!"); BetterBitArray newba = new BetterBitArray(); newba.bitholder = new int[bitholder.Length]; newba.Length = rightside.Length; newba.SetBits = 0; //To take care of bits that exist > Length of the wanted bit array BetterBitArray unwantedmask = new BetterBitArray(newba.Length); for(int a = 0; a < unwantedmask.Length; a++) unwantedmask.Set(a); for(int i = 0; i < bitholder.Length; i++) { newba.bitholder[i] = bitholder[i] ^ rightside.bitholder[i]; newba.SetBits += SparseBitcount(newba.bitholder[i]); } newba = newba.And(unwantedmask); return newba; }
public BetterBitArray Not() { BetterBitArray newba = new BetterBitArray(); newba.bitholder = new int[bitholder.Length]; newba.Length = Length; for(int i = 0; i < bitholder.Length; i++) { newba.bitholder[i] = ~bitholder[i]; } //To take care of bits that exist > Length of the wanted bit array BetterBitArray unwantedmask = new BetterBitArray(newba.Length); for(int a = 0; a < unwantedmask.Length; a++) unwantedmask.Set(a); newba = newba.And(unwantedmask); newba.SetBits = Length - SetBits; return newba; }
//Uniform random initialization of population private List<Individual> InitUniformRandomPopulation(int number, int numberrouters) { List<Individual> population = new List<Individual>(); for(int i = 0; i < number; i++) { BetterBitArray individual = new BetterBitArray(numberrouters); int numbertoswitch = randomgenerator.Next(numberrouters); for(int j = 0; j < numbertoswitch; j++) { int switching; while(individual.IsSet(switching = randomgenerator.Next(numberrouters)) == true); individual.Set(switching); } int pathscut = 0; double fitness = FitnessEvaluation(data.NetworkPaths, individual, config.PenaltyCoefficient, out pathscut); population.Add(new Individual(fitness, pathscut, individual)); } return population; }
//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; }
//Uniform random initialization of population private List<Individual> InitUniformRandomPopulation(int number, int numberrouters) { double timedoingfitness = 0.0; //double timegenerating = 0.0; List<Individual> population = new List<Individual>(); for(int i = 0; i < number; i++) { BetterBitArray individual = new BetterBitArray(numberrouters); int numbertoswitch = randomgenerator.Next(numberrouters); for(int j = 0; j < numbertoswitch; j++) { int switching; while(individual.IsSet(switching = randomgenerator.Next(numberrouters)) == true); individual.Set(switching); } Stopwatch fitnesstime = Stopwatch.StartNew(); int pathscut = 0; double fitness = FitnessEvaluation(data.NetworkPaths, individual, config.PenaltyCoefficient, out pathscut); fitnesstime.Stop(); Console.WriteLine("Fitness time: " + fitnesstime.Elapsed.TotalMilliseconds); timedoingfitness += fitnesstime.Elapsed.TotalMilliseconds; population.Add(new Individual(fitness, pathscut, individual)); } Console.WriteLine("Fitness time(ms): " + timedoingfitness / 1000.0); return population; }