public CandidateSolution(MealCollection meals, NutritionConstraints nutritionConstraints, List <bool> isSelected) { this.isSelected = new List <bool>(isSelected); Meals = meals; NutritionConstraints = nutritionConstraints; CalcFitness(); }
static void Main(string[] args) { Console.Write("Initialising engine..."); GeneticAlgorithEngine ge = new GeneticAlgorithEngine(INITIALPOPULATIONSIZE, CROSSOVERPERCENTAGE, MUTATIONPERCENTAGE); Console.Write("\nReading data..."); DataReader dataReader = new DataReader(); MealCollection mealCollection = dataReader.GetMealCollectionFromFile(); NutritionConstraints constraints = new NutritionConstraints(PROTEIN, CARBS, FAT, CALORIES, VITAMINA, VITAMINC, CALCIUM, IRON); Console.Write("\nRunning optimalisation..."); MealCollection solution = ge.FindOptimalItems(mealCollection, constraints); WriteSolutionToConsole(solution); }
//generation 0, creates random solution public CandidateSolution(MealCollection mealCollection, NutritionConstraints nutritionConstraints) { NutritionConstraints = nutritionConstraints; Meals = mealCollection; var numMeals = Meals.Count; isSelected = new List <bool>(numMeals); //randomly initilase membership flag for (int i = 0; i < numMeals; i++) { isSelected.Add(Randomizer.GetDoubleFromZeroToOne() >= 0.5); } CalcFitness(); }
private static void WriteSolutionToConsole(MealCollection solution) { Meal totalMeal = new Meal(); Console.WriteLine("\nYour meals:"); foreach (var item in solution.ToList()) { WriteMeal(item); totalMeal.ServingSize += item.ServingSize; totalMeal.Calories += item.Calories; totalMeal.Carbohidrate += item.Carbohidrate; totalMeal.Fat += item.Fat; totalMeal.Protein += item.Protein; totalMeal.Sodium += item.Sodium; totalMeal.VitaminA += item.VitaminA; totalMeal.VitaminC += item.VitaminC; } Console.WriteLine("============================"); Console.WriteLine("Your total daily consumption:"); WriteMeal(totalMeal); Console.ReadLine(); }
public MealCollection FindOptimalItems(MealCollection meals, NutritionConstraints constraints) { currentGeneration = new List <CandidateSolution>(populationSize); for (int i = 0; i < populationSize; i++) { currentGeneration.Add(new CandidateSolution(meals, constraints)); } generationNumber = 1; //main loop while (true) { float bestFitnessScoreThisGeneration = System.Int32.MaxValue; CandidateSolution bestSolutionThisGeneration = null; foreach (var candidate in currentGeneration) { candidate.Repair(); float fitness = candidate.Fitness; //sum up fitness scores for the roulette wheel selection totalFitnessThisGeneration += fitness; totalInverseFitnessThisGeneration += 1 / (double)fitness; if (fitness < bestFitnessScoreThisGeneration) { bestFitnessScoreThisGeneration = fitness; bestSolutionThisGeneration = candidate; } } Debug.WriteLine("Iteration count {0}, best fitness: {1}", generationNumber, bestFitnessScoreAllTime); //compare this generation's best to to the best we had so far if (bestFitnessScoreThisGeneration < bestFitnessScoreAllTime) { //save the best score bestFitnessScoreAllTime = bestFitnessScoreThisGeneration; //and save possible solution bestSolution = bestSolutionThisGeneration.DeepClone(); bestSolutionGenerationNumber = generationNumber; } else { if ((generationNumber - bestSolutionGenerationNumber) > MaxGenerationsWithNoChange) { break; } } List <CandidateSolution> nextGeneration = new List <CandidateSolution>(); while (nextGeneration.Count < populationSize) { //Select two parents(the lower the fitness, the higher the chance of selection) var parent1 = SelectCandidate(); var parent2 = SelectCandidate(); //cross them over to generate two new children CandidateSolution child1, child2; CrossOverParents(parent1, parent2, out child1, out child2); //appy mutation if needed child1.AddPossibleMutation(mutationRate); child2.AddPossibleMutation(mutationRate); //add them to next generation nextGeneration.Add(child1); nextGeneration.Add(child2); } currentGeneration = nextGeneration; generationNumber++; } return(bestSolution.GetSelectedItems()); }