public void ReSearch(Bee bee, double demandPower) { //Dimension var d = this.Count; //Random k var k = Rand.Next(0, d); //Random number between -1 and 1 var rand = Rand.NextDouble() * Math.Pow((-1), Rand.Next(0, 2)); //Copy self as a newBee var newBee = this.Copy(); //Get the k-th honey var honeyK = this[k]; //Try to set the honeyK's count to a new count newBee[k].SetCount((int)Math.Round(honeyK.Count + rand * (honeyK.Count - bee[k].Count))); //If the newBee's fitness is better than self var newFitness = newBee.Fitness(demandPower); FitnessLast = this.Fitness(demandPower); if (newFitness > FitnessLast) { //Use the newBee's count this[k].SetCount(newBee[k].Count); FitnessLast = newFitness; } //Research count++ else { ReSearchCount++; } }
public static double GetLoadRate(this Bee bee, double demandPower) { var totalPower = bee.GetTotalPower(); if (demandPower > totalPower) { return(0); } return(demandPower / totalPower); }
public static Bee Generate() { Init(); var workerBee = new Bee(); foreach (var gene in HoneyLib) { workerBee.Add(gene.NextRandom()); } return(workerBee); }
public Bee Copy() { var workerBee = new Bee { FitnessLast = this.FitnessLast }; foreach (var h in this) { workerBee.Add(h.Copy()); } return(workerBee); }
public static double Fitness(this Bee bee, double demandPower) { if (bee.GetTotalPower() < demandPower) { return(0); } var loadRate = bee.GetLoadRate(demandPower); var averageCost = bee.GetAverageCost(demandPower); var averageCo2 = bee.GetAverageCO2(demandPower); var fitness = loadRate + 1 / averageCost + 1 / averageCo2; return(fitness); }
public static double GetAverageCO2(this Bee bee, double demandPower) { var totalPower = bee.GetTotalPower(); if (demandPower > totalPower) { return(double.PositiveInfinity); } var totalCo2 = 0.0; foreach (var gene in bee) { totalCo2 += gene.CO2 * gene.Power * gene.Count; } return(totalCo2 / totalPower); }
public static double GetTotalPower(this Bee bee) { return(bee.Select(x => x.Power * x.Count).Sum()); }
static void Main(string[] args) { var stopWatch = new Stopwatch(); stopWatch.Start(); var maxGeneration = 2000; var generation = 0; var bestFitness = 0.0; Bee bestBee = null; var populationSizeEmployee = 800; var populationSizeOnlooker = 200; var demandPower = 10000; //Init employee bee population var populationEmployeeBee = PopulationGenerator.Generate(populationSizeEmployee).ToList(); //Onlooker bee collection var populationOnlookerBee = new List <Bee>(); while (generation < maxGeneration) { //For each employee bee foreach (var b in populationEmployeeBee) { //Grab a random other employee and perform a close search var k = Rand.Next(0, populationSizeEmployee); var beeK = populationEmployeeBee[k]; //Check if this bee has exceed search limit //If so this function will turn this bee into a scout bee, //which is, to generate a new bee. if (!b.IsReSearchLimitExceed()) { //If not, perform a close search b.ReSearch(beeK, demandPower); } } //Clear onlooker bee's collection populationOnlookerBee.Clear(); //Get bees from employee collcetion using Roulette selection foreach (var _ in Enumerable.Range(0, populationSizeOnlooker)) { populationOnlookerBee.Add(populationEmployeeBee.RouletteSelect().Copy()); } //For each onlooker bee, perform a close search foreach (var b in populationOnlookerBee) { //Grab a random bee from onlooker bee's collection var k = Rand.Next(0, populationSizeOnlooker); var beeK = populationOnlookerBee[k]; //Perform close search b.ReSearch(beeK, demandPower); } //Get the best one, for now populationOnlookerBee = populationOnlookerBee.OrderBy(x => x.FitnessLast).ToList(); var lastBee = populationOnlookerBee.Last(); //Save the best one if (lastBee.GetTotalPower() >= demandPower) { var fitness = lastBee.FitnessLast; if (fitness > bestFitness) { bestFitness = fitness; bestBee = lastBee.Copy(); } } Console.WriteLine(bestBee); Console.WriteLine($"Best fitness: {bestBee.Fitness(demandPower)}"); Console.WriteLine($"Best Total Power: {bestBee.GetTotalPower()}"); Console.WriteLine($"Best LoadRate: {bestBee.GetLoadRate(demandPower)}"); Console.WriteLine($"Best Cost: {bestBee.GetAverageCost(demandPower)}"); Console.WriteLine($"Best CO2: {bestBee.GetAverageCO2(demandPower)}"); Console.WriteLine($"Gen: {generation}"); Console.WriteLine($"========================="); //This the known best solution. if (Math.Abs(bestFitness - 1.1054208443867) < 0.0001) { break; } generation++; } stopWatch.Stop(); Console.WriteLine($"Execution Time:{stopWatch.Elapsed.TotalSeconds}"); Console.ReadKey(); }