public void SelectChromosomes_Generation_ChromosomesZeroFitness() { var target = new RankSelection(); var c1 = Substitute.ForPartsOf <ChromosomeBase>(2); c1.Fitness = 0; var c2 = Substitute.ForPartsOf <ChromosomeBase>(2); c2.Fitness = 0; var c3 = Substitute.ForPartsOf <ChromosomeBase>(2); c3.Fitness = 0; var c4 = Substitute.ForPartsOf <ChromosomeBase>(2); c4.Fitness = 0; var generation = new Generation(1, new List <IChromosome>() { c1, c2, c3, c4 }); var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); }
public void TestMethod() { var arr1 = new double[] { 10, 3, 18, -1, 20, 10, 3 }.ToList(); var arr2 = new double[] { 15, 7, 0, 10, 25, 9 }.ToList(); RankSelection rs = new RankSelection(); var fstSelectionNumber = rs.AddSelection(arr1); var scndSelectionNumber = rs.AddSelection(arr2); }
public void SelectChromosomes_NullGeneration_Exception() { var target = new RankSelection(); var actual = Assert.Catch <ArgumentNullException>(() => { target.SelectChromosomes(2, null); }); Assert.AreEqual("generation", actual.ParamName); }
public void SelectChromosomes_InvalidNumber_Exception() { var target = new RankSelection(); Assert.Catch <ArgumentOutOfRangeException>(() => { target.SelectChromosomes(-1, null); }, "The number of selected chromosomes should be at least 2."); Assert.Catch <ArgumentOutOfRangeException>(() => { target.SelectChromosomes(0, null); }, "The number of selected chromosomes should be at least 2."); Assert.Catch <ArgumentOutOfRangeException>(() => { target.SelectChromosomes(1, null); }, "The number of selected chromosomes should be at least 2."); }
public void SelectChromosomes_NullFitness_Exception() { var target = new RankSelection(); var generation = new Generation(1, new List <IChromosome> { new TspChromosome(10), new TspChromosome(10), new TspChromosome(10), new TspChromosome(10), new TspChromosome(10) }); var actual = Assert.Catch <SelectionException>(() => { target.SelectChromosomes(2, generation); }); Assert.AreEqual("RankSelection: There are chromosomes with null fitness.", actual.Message); }
public override double GetCoef() { var xRanged = new RankSelection(); xRanged.AddSelection(x); var yRanged = new RankSelection(); yRanged.AddSelection(y); double coef = 0; List <PointD> unionSeriaSortedByX = xRanged.ranks.Zip(yRanged.ranks.ToList(), (x, y) => new PointD(x, y)).OrderBy(p => p.X).ToList(); List <double> rx = unionSeriaSortedByX.Select(p => p.X).ToList(); List <double> ry = unionSeriaSortedByX.Select(p => p.Y).ToList(); unionSeriaSortedByX.Select(p => p.X).ToList(); double S = 0; for (int i = 0; i < N - 1; i++) { for (int j = i + 1; j < N; j++) { if (rx[i] != rx[j]) { S += ry[j].CompareTo(ry[i]); } } } var C = xRanged.Ranks.Where(r => r.Count > 1).Sum(xr => xr.Count * (xr.Count - 1)) / 2; var D = yRanged.Ranks.Where(r => r.Count > 1).Sum(yr => yr.Count * (yr.Count - 1)) / 2; coef = S / Math.Sqrt((0.5 * N * (N - 1) - C) * (0.5 * N * (N - 1) - D)); return(coef); }
public override double GetCoef() { var xRanged = new RankSelection(); xRanged.AddSelection(x); var yRanged = new RankSelection(); yRanged.AddSelection(y); double coef = 0; double rangedSum = 0; for (int i = 0; i < N; i++) { double xiRank = xRanged.Selection.Where(itm => itm.value == x[i]).First().rank; double yiRank = yRanged.Selection.Where(itm => itm.value == y[i]).First().rank; rangedSum += (xiRank - yiRank) * (xiRank - yiRank); } if (xRanged.Ranks.Where(r => r.Items.Count > 1).Count() == 0 && yRanged.Ranks.Where(r => r.Items.Count > 1).Count() == 0) { coef = 1 - (6 * rangedSum) / (N * (N * N - 1)); } else { var A = xRanged.Ranks.Where(r => r.Items.Count > 1).Sum(x => x.Count * x.Count * x.Count - x.Count) / 12; var B = yRanged.Ranks.Where(r => r.Items.Count > 1).Sum(y => y.Count * y.Count * y.Count - y.Count) / 12; double NsExp = N * (N * N - 1) / 6; double top = NsExp - rangedSum - A - B; double bottom = Math.Sqrt((NsExp - 2 * A) * (NsExp - 2 * B)); coef = top / bottom; } return(coef); }
public void RankSelection_IgnoreSomeOfPopulation(int chromosomesToIgnore) { var selection = new RankSelection(1 - chromosomesToIgnore / 4.0); AssertLowestChromosomesAreIgnored(selection, chromosomesToIgnore); }
static void Main(string[] args) { Stopwatch stopwatch = new Stopwatch(); decimal frequency = Stopwatch.Frequency; if (CommandLine.Parser.Default.ParseArguments(args, Options)) { TextWriter reportWriter = Options.OutputFilePath == null ? Console.Out : new StreamWriter(Options.OutputFilePath); VerboseLog("Data parsing ..."); DataParser parser = new DataParser(); List <KnapsackProblemModel> knapsackProblemModels = parser.ParseProblem(Options.InputFiles); Dictionary <int, int> knownResults = null; Dictionary <int, Tuple <int, long> > bruteForceResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > costToRatioHeuristicsResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > branchAndBoundResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > dynamicByCostResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > fptasResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > geneticResults = new Dictionary <int, Tuple <int, long> >(); if (Options.ResultFiles != null) { knownResults = parser.ParseResults(Options.ResultFiles); } VerboseLog("Done."); IKnapsackSolver bruteForceSolver = new BruteForceSolver(); IKnapsackSolver ratioHeuristicSolver = new RatioHeuristicSolver(); IKnapsackSolver branchAndBoundSolver = new BranchAndBoundSolver(); IKnapsackSolver dynamicByCostSolve = new DynamicByCostSolver(); IKnapsackSolver fptasSolver = null; IKnapsackSolver geneticSolver = null; if (Options.FPTAS) { fptasSolver = new FPTASSolver(Options.FPTASAccuracy); } if (Options.Genetics) { ISelectionMethod selectionMethod = null; switch (Options.SelectionMethod) { case "roulette": selectionMethod = new RouletteWheelSelection(); break; case "rank": selectionMethod = new RankSelection(); break; case "elitary": selectionMethod = new EliteSelection(); break; default: Console.WriteLine("Wrong selection method for genetics"); break; } if (selectionMethod == null) { return; } if (Options.GeneticMetaoptimization) { //Random selection portion for (int i = 0; i < 100; i++) { double randomSelectionPortion = (i * 0.001) + 0; //Crossover rate for (int j = 0; j < 1; j++) { double crossoverRate = (j * 0.03) + 0.22; //Mutation rate for (int k = 0; k < 1; k++) { double mutationRate = (k * 0.04) + 0.87; geneticSolver = new GeneticSolver(Options.PopulationSize, Options.IterationsCount, selectionMethod, mutationRate, crossoverRate, randomSelectionPortion, false, false); geneticResults.Clear(); foreach (KnapsackProblemModel problem in knapsackProblemModels) { int result = 0; try { stopwatch.Restart(); result = geneticSolver.Solve(problem); stopwatch.Stop(); } catch (Exception ex) { } geneticResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); } decimal totalTime = 0; decimal totalError = 0; foreach (KnapsackProblemModel problem in knapsackProblemModels) { int problemId = problem.ProblemId; Tuple <int, long> result = geneticResults[problemId]; totalTime += (result.Item2 / frequency); totalError += CalculateRelativeError(knownResults[problemId], result.Item1); } decimal averageError = totalError / knapsackProblemModels.Count; reportWriter.WriteLine(randomSelectionPortion + "," + crossoverRate + "," + mutationRate + "," + totalTime + "," + averageError); } } } } geneticSolver = new GeneticSolver(Options.PopulationSize, Options.IterationsCount, selectionMethod, Options.MutationRate, Options.CrossoverRate, Options.RandomSelectionPortion, Options.DiversityCheck, true); } VerboseLog("Solving JIT instance"); KnapsackProblemModel jitProblem = new KnapsackProblemModel(-1, 100, new List <Item> { new Item(18, 114, 0), new Item(42, 136, 1), new Item(88, 192, 2), new Item(3, 223, 3) }); bruteForceSolver.Solve(jitProblem); ratioHeuristicSolver.Solve(jitProblem); branchAndBoundSolver.Solve(jitProblem); dynamicByCostSolve.Solve(jitProblem); if (fptasSolver != null) { fptasSolver.Solve(jitProblem); } if (geneticSolver != null) { geneticSolver.Solve(jitProblem); } VerboseLog("Calculation started"); foreach (KnapsackProblemModel problem in knapsackProblemModels) { VerboseLog("Solving problem:"); VerboseLog(problem); int knownResult = -1; if (knownResults != null) { knownResult = knownResults[problem.ProblemId]; VerboseLog("Result should be: " + knownResult); } if (Options.BruteForce) { VerboseLog("Brute force solver ..."); stopwatch.Restart(); int result = bruteForceSolver.Solve(problem); stopwatch.Stop(); bruteForceResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); if (knownResult != -1 && result != knownResult) { Console.WriteLine("ERROR - Brute force algorithm not accurate for problem " + problem); Environment.Exit(1); } } if (Options.BranchAndBound) { VerboseLog("Branch and bound solver ..."); stopwatch.Restart(); int result = branchAndBoundSolver.Solve(problem); stopwatch.Stop(); branchAndBoundResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); if (knownResult != -1 && result != knownResult) { Console.WriteLine("ERROR - Branch and bound algorithm not accurate for problem " + problem); Environment.Exit(1); } } if (Options.DynamicByCost) { VerboseLog("Dynamic by cost solver ..."); stopwatch.Restart(); int result = dynamicByCostSolve.Solve(problem); stopwatch.Stop(); dynamicByCostResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); if (knownResult != -1 && result != knownResult) { Console.WriteLine("ERROR - Dynamic by cost algorithm not accurate for problem " + problem); Environment.Exit(1); } } if (Options.CostToRatioHeuristics) { VerboseLog("Ratio heuristics solver ..."); stopwatch.Restart(); int result = ratioHeuristicSolver.Solve(problem); stopwatch.Stop(); costToRatioHeuristicsResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); } if (Options.FPTAS) { VerboseLog("FPTAS solver ..."); if (fptasSolver != null) { stopwatch.Restart(); int result = fptasSolver.Solve(problem); stopwatch.Stop(); fptasResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); } } if (Options.Genetics) { VerboseLog("Genetics solver ..."); if (geneticSolver != null) { stopwatch.Restart(); int result = geneticSolver.Solve(problem); stopwatch.Stop(); geneticResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); } } VerboseLog("Problem solved."); } reportWriter.Write("Problem ID;Items count"); if (knownResults != null) { reportWriter.Write(";Known result"); } if (Options.BruteForce) { reportWriter.Write(";Brute force result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } if (Options.CostToRatioHeuristics) { reportWriter.Write(";Cost to weight ration heuristics result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } if (Options.BranchAndBound) { reportWriter.Write(";Branch and bound result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } if (Options.DynamicByCost) { reportWriter.Write(";Dynamic programming by cost result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } if (Options.FPTAS) { reportWriter.Write(";FPTAS result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error;Max possible error"); } } if (Options.Genetics) { reportWriter.Write(";Genetics result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } reportWriter.WriteLine(); foreach (KnapsackProblemModel problem in knapsackProblemModels) { var problemId = problem.ProblemId; reportWriter.Write(problemId); reportWriter.Write(";" + problem.Items.Count); if (knownResults != null) { reportWriter.Write(";" + knownResults[problemId]); } if (Options.BruteForce) { Tuple <int, long> bruteForceResult = bruteForceResults[problemId]; reportWriter.Write(";" + bruteForceResult.Item1 + ";" + bruteForceResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], bruteForceResult.Item1)); } } if (Options.CostToRatioHeuristics) { Tuple <int, long> heuristicsResult = costToRatioHeuristicsResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); } } if (Options.BranchAndBound) { Tuple <int, long> heuristicsResult = branchAndBoundResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); } } if (Options.DynamicByCost) { Tuple <int, long> heuristicsResult = dynamicByCostResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); } } if (Options.FPTAS) { Tuple <int, long> heuristicsResult = fptasResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); reportWriter.Write(";" + ((FPTASSolver)fptasSolver).GetMaximumError(problem)); } } if (Options.Genetics) { Tuple <int, long> heuristicsResult = geneticResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); } } reportWriter.WriteLine(); } if (Options.Genetics) { decimal totalTime = 0; decimal totalError = 0; foreach (KnapsackProblemModel problem in knapsackProblemModels) { int problemId = problem.ProblemId; Tuple <int, long> result = geneticResults[problemId]; totalTime += (result.Item2 / frequency); totalError += CalculateRelativeError(knownResults[problemId], result.Item1); } decimal averageError = totalError / knapsackProblemModels.Count; reportWriter.WriteLine("Aggregate results"); reportWriter.WriteLine("Aggregate time"); reportWriter.WriteLine(totalTime); reportWriter.WriteLine("Average error"); reportWriter.WriteLine(averageError); } } else { Environment.Exit(1); } Environment.Exit(0); }
/// <summary> /// Trains and evaluates a genetic algorithm with the specified parameters. /// </summary> /// <param name="data">The data to be used for training.</param> /// <param name="solution">The reference to where the solution will be stored.</param> /// <param name="bestChromosome">The best chromosome.</param> /// <param name="error">The reference where error rate will be stored.</param> /// <param name="predictions">The reference to where the predictions will be stored.</param> /// <param name="iterations">The number of iterations to perform.</param> /// <param name="population">The size of the population.</param> /// <param name="inputCount">The number of inputs.</param> /// <param name="shuffle">Value indicating whether to shuffle the chromosomes on each epoch.</param> /// <param name="constants">The constant inputs.</param> /// <param name="geneType">Type of the gene functions.</param> /// <param name="chromosomeType">Type of the chromosome.</param> /// <param name="selectionType">Type of the chromosome selection.</param> /// <param name="cancelToken">The cancellation token for the async operation.</param> /// <param name="progressCallback">The progress callback: current iteration.</param> /// <returns> /// <c>true</c> if the training and evaluation was successful, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentException">Array should be size of data minus number of inputs.</exception> public static bool TrainAndEval(double[] data, ref double[] solution, ref string bestChromosome, ref double error, ref double[] predictions, int iterations, int population, int inputCount, bool shuffle, double[] constants, GeneFunctions geneType, Chromosomes chromosomeType, Selections selectionType, CancellationToken cancelToken, Action <int> progressCallback = null) { IGPGene gene; switch (geneType) { case GeneFunctions.Simple: gene = new SimpleGeneFunction(inputCount + constants.Length); break; case GeneFunctions.Extended: gene = new ExtendedGeneFunction(inputCount + constants.Length); break; default: return(false); } IChromosome chromosome; switch (chromosomeType) { case Chromosomes.GPT: chromosome = new GPTreeChromosome(gene); break; case Chromosomes.GEP: chromosome = new GEPChromosome(gene, 20); break; default: return(false); } ISelectionMethod selection; switch (selectionType) { case Selections.Elite: selection = new EliteSelection(); break; case Selections.Rank: selection = new RankSelection(); break; case Selections.Roulette: selection = new RouletteWheelSelection(); break; default: return(false); } cancelToken.ThrowIfCancellationRequested(); var ga = new Population( population, chromosome, new TimeSeriesPredictionFitness(data, inputCount, 0, constants), selection ) { AutoShuffling = shuffle }; if (solution.Length != data.Length - inputCount) { throw new ArgumentException("Array should be the size of data minus number of inputs.", nameof(solution)); } var input = new double[inputCount + constants.Length]; for (var j = 0; j < data.Length - inputCount; j++) { solution[j] = j + inputCount; } Array.Copy(constants, 0, input, inputCount, constants.Length); for (var i = 0; i < iterations; i++) { ga.RunEpoch(); progressCallback?.Invoke(i); cancelToken.ThrowIfCancellationRequested(); } error = 0.0; bestChromosome = ga.BestChromosome.ToString(); for (int j = 0, n = data.Length - inputCount; j < n; j++) { for (int k = 0, b = j + inputCount - 1; k < inputCount; k++) { input[k] = data[b - k]; } solution[j] = PolishExpression.Evaluate(bestChromosome, input); error += Math.Abs((solution[j] - data[inputCount + j]) / data[inputCount + j]); cancelToken.ThrowIfCancellationRequested(); } error = error / (data.Length - inputCount) * 100; if (predictions.Length != 0) { Array.Copy(solution, solution.Length - inputCount, predictions, 0, inputCount); for (var i = inputCount; i < predictions.Length; i++) { for (int j = 0; j < inputCount; j++) { input[j] = predictions[(i - inputCount) + j]; } predictions[i] = PolishExpression.Evaluate(bestChromosome, input); cancelToken.ThrowIfCancellationRequested(); } } return(true); }
public void SelectChromosomes_Generation_ChromosomesSelected() { var target = new RankSelection(); var c1 = Substitute.ForPartsOf <ChromosomeBase>(2); c1.Fitness = 0.1; var c2 = Substitute.ForPartsOf <ChromosomeBase>(2); c2.Fitness = 0.5; var c3 = Substitute.ForPartsOf <ChromosomeBase>(2); c3.Fitness = 0; var c4 = Substitute.ForPartsOf <ChromosomeBase>(2); c4.Fitness = 0.7; var generation = new Generation(1, new List <IChromosome>() { c1, c2, c3, c4 }); // Just one selected chromosome is c1. FlowAssert.IsAtLeastOneAttemptOk(100, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(1, actual.Count(c => c.Fitness == 0.1)); }); // All selected chromosome is c1. FlowAssert.IsAtLeastOneAttemptOk(1000, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.IsTrue(actual.All(c => c.Fitness == 0.1)); }); // Just one selected chromosome is c2. FlowAssert.IsAtLeastOneAttemptOk(100, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(1, actual.Count(c => c.Fitness == 0.5)); }); // All selected chromosome is c2. FlowAssert.IsAtLeastOneAttemptOk(1000, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.IsTrue(actual.All(c => c.Fitness == 0.5)); }); // Just one selected chromosome is c3. FlowAssert.IsAtLeastOneAttemptOk(100, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(1, actual.Count(c => c.Fitness == 0)); }); // All selected chromosome is c3. FlowAssert.IsAtLeastOneAttemptOk(1000, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.IsTrue(actual.All(c => c.Fitness == 0)); }); // Just one selected chromosome is c4. FlowAssert.IsAtLeastOneAttemptOk(100, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.AreEqual(1, actual.Count(c => c.Fitness == 0.7)); }); // All selected chromosome is c4. FlowAssert.IsAtLeastOneAttemptOk(1000, () => { var actual = target.SelectChromosomes(2, generation); Assert.AreEqual(2, actual.Count); Assert.IsTrue(actual.All(c => c.Fitness == 0.7)); }); }