protected override IList <IChromosome> PerformCross(IList <IChromosome> parents) { ExpressionChromosome parent1 = parents[0] as ExpressionChromosome; ExpressionChromosome parent2 = parents[1] as ExpressionChromosome; int index1 = (int)Math.Floor(RandomizationProvider.Current.GetDouble() * parent1.Length); int index2 = (int)Math.Floor(RandomizationProvider.Current.GetDouble() * parent2.Length); Gene[] subtree1 = GetSubtree(parent1.GetGenes(), index1); Gene[] subtree2 = GetSubtree(parent2.GetGenes(), index2); // Copy subtree2 to parent1 at index1. ExpressionChromosome child1 = parent1.CreateNew() as ExpressionChromosome; Gene[] result = GetNewGenes(parent1.GetGenes(), index1, subtree1, subtree2); child1.SetGenes(result); // Copy subtree1 to parent2 at index2. ExpressionChromosome child2 = parent2.CreateNew() as ExpressionChromosome; result = GetNewGenes(parent2.GetGenes(), index2, subtree2, subtree1); child2.SetGenes(result); List <IChromosome> childs = new List <IChromosome>(); if (child1.Length < maxLength) { childs.Add(child1); } if (child2.Length < maxLength) { childs.Add(child2); } return(childs); }
public double Evaluate(IChromosome chromosome) { ExpressionChromosome ch = chromosome as ExpressionChromosome; if (ch == null) { throw new ArgumentException("Chromosome type is not ExpressionChromosome"); } double fitness = 0; foreach (InputFunction func in data) { double result = ch.Evaluate(func.Parameters); fitness += Math.Abs(result - func.Result); } if (double.IsNaN(fitness)) { return(-1000); } return(fitness * -1); }
static void Main(string[] args) { string s1 = "c-5*(a*(b+5)-1)/c+(a*b/c)"; string s2 = "a*b*c+(a/2)*b-(c/(b+9))"; int variableNumber = 3; string prefix1 = PrefixHelper.InfixToPrefix(s1); string prefix2 = PrefixHelper.InfixToPrefix(s2); List <InputFunction> data = new List <InputFunction>(); int sampleDataSize = 20; using (StreamWriter sw = new StreamWriter("InputData.txt")) { for (int i = 0; i < sampleDataSize; i++) { sw.Write("("); double[] values = new double[variableNumber]; for (int j = 0; j < variableNumber; j++) { values[j] = RandomizationProvider.Current.GetDouble(-10, 10); sw.Write(values[j]); if (j < variableNumber - 1) { sw.Write(','); } } sw.Write(")("); double result1 = PrefixHelper.EvaluatePrefix(prefix1, values); double result2 = PrefixHelper.EvaluatePrefix(prefix2, values); sw.WriteLine($"{result1},{result2})"); InputFunction input = new InputFunction(result1, values); data.Add(input); } } #region old sample data // Sample data for 5A-7B //List<InputFunction> data = new List<InputFunction>() //{ // new InputFunction(-15, 4,5), // new InputFunction(-2,1,1), // new InputFunction(8,-4,-4), // new InputFunction(-31,-2,3) //}; //int funcLength = 2; // Sample data for 5A-7B-4C+2D //List<InputFunction> data = new List<InputFunction>() //{ // new InputFunction(11, 4,5,-5,3), // new InputFunction(12,1,1,0,7), // new InputFunction(0,-4,-4,3,2), // new InputFunction(-9,-2,3,-7,-3) //}; //int funcLength = 4; // Sample data for 5A-7B-4C+2D+0E+1F+9G //List<InputFunction> data = new List<InputFunction>() //{ // new InputFunction(152,4,5,-5,3,8,6,15), // new InputFunction(221,1,1,0,7,-25,-7,24), // new InputFunction(-269,-4,-4,3,2,-1,55,-36), // new InputFunction(384,-2,3,-7,-3,0,-12,45) //}; //int funcLength = 7; // Custom data input //Console.WriteLine("Enter function length:"); //int funcLength = int.Parse(Console.ReadLine()); //int[] parameters = new int[funcLength]; //while (true) //{ // for (int i = 0; i < funcLength; i++) // { // Console.WriteLine("Enter #{0} param:", i); // parameters[i] = int.Parse(Console.ReadLine()); // } // Console.WriteLine("Enter result:"); // int result = int.Parse(Console.ReadLine()); // data.Add(new InputFunction(result, parameters)); // Console.WriteLine("press enter to continue, or write 'done' to start the ga"); // string input = Console.ReadLine(); // if (input == "done") // break; //} #endregion int maxLength = 6 + 5 * variableNumber; IChromosome chromosome = new ExpressionChromosome(variableNumber, maxLength); IPopulation population = new Population(8500, 10000, chromosome); population.GenerationStrategy = new PerformanceGenerationStrategy(); IFitness fitness = new ExpressionFitness(data.ToArray()); ISelection selection = new EliteSelection(); ICrossover crossover = new ExpressionCrossover(maxLength); IMutation mutation = new ExpressionMutation(variableNumber); GeneticAlgorithm ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation); ga.Termination = new ExpressionTermination(200); ga.MutationProbability = .5f; double latestFitness = double.MinValue; ga.GenerationRan += (sender, e) => { Console.Title = ga.TimeEvolving.ToString(); //Console.Title = ga.Population.CurrentGeneration.Chromosomes.Count.ToString(); ExpressionChromosome bestChromosome = ga.BestChromosome as ExpressionChromosome; double bestFitness = bestChromosome.Fitness.Value; if (bestFitness != latestFitness) { latestFitness = bestFitness; Console.WriteLine("\n--------\n"); Console.WriteLine("Generation: {0}", ga.Population.GenerationsNumber); //Console.WriteLine("Time: {0}", ga.TimeEvolving); Console.WriteLine("Fitness: {0}", bestFitness.ToString("0.00")); Console.WriteLine("Best: {0}", bestChromosome.ToString()); } }; ga.Start(); Console.WriteLine("\nTime: {0}", ga.TimeEvolving); double sum = 0; double[] diffs = new double[sampleDataSize]; for (int i = 0; i < sampleDataSize; i++) { double resultActual = PrefixHelper.EvaluatePrefix(prefix1, data[i].Parameters); double resultOur = PrefixHelper.EvaluatePrefix(ga.BestChromosome.GetGenes(), data[i].Parameters); double diff = Math.Abs(resultActual - resultOur); Console.WriteLine($"Actual: {resultActual.ToString("0.00")} | Our: {resultOur.ToString("0.00")} | Diff: {diff.ToString("0.00")}"); sum += diff; diffs[i] = diff; } double avgDiff = sum / sampleDataSize; Console.WriteLine($"Average diff: {avgDiff.ToString("0.00")} | Median: {GetMedian(diffs).ToString("0.00")}"); Console.WriteLine("\n ---- New Samples ---- \n"); for (int i = 0; i < sampleDataSize; i++) { double[] values = new double[variableNumber]; for (int j = 0; j < variableNumber; j++) { values[j] = RandomizationProvider.Current.GetDouble(-10, 10); } double result = PrefixHelper.EvaluatePrefix(prefix1, values); double our = PrefixHelper.EvaluatePrefix(ga.BestChromosome.GetGenes(), values); double diff = Math.Abs(result - our); Console.WriteLine($"Actual: {result.ToString("0.00")} | Our: {our.ToString("0.00")} | Diff: {diff.ToString("0.00")}"); sum += diff; diffs[i] = diff; } avgDiff = sum / sampleDataSize; Console.WriteLine($"Average diff: {avgDiff.ToString("0.00")} | Median: {GetMedian(diffs).ToString("0.00")}"); Console.ReadKey(); }