public void SelectDistinctTest() { // Config var config = JsonConvert.DeserializeObject <OptimizerConfiguration>(@"{ ""genes"": [ { ""key"": ""period"", ""min"": 60, ""max"": 300 }, { ""key"": ""mult"", ""min"": 1.5, ""max"": 2.9 } ], ""population-initial-size"": 4}"); // Population var population = new PopulationRandom(config.GeneConfigArray, config.PopulationInitialSize); population.CreateInitialGeneration(); var chromosomes = population.CurrentGeneration.Chromosomes; // Assign fitness to all in first collection and assign to merge var merged = chromosomes.Select(c => { c.Fitness = 10; return(c); }).ToList(); // Clone first and add to merge var chromosomes2 = chromosomes.Select(c => c.CreateNew()).ToList(); merged.AddRange(chromosomes2); // Obtain result var result = merged.SelectDistinct(); // Assert Assert.AreEqual(4, result.Count); foreach (var r in result) { Assert.AreEqual(r.Fitness, 10); } }
/// <summary> /// Initializes a new instance of the <see cref="AlgorithmOptimumFinder"/> class /// </summary> /// <param name="start">Algorithm start date</param> /// <param name="end">Algorithm end date</param> /// <param name="fitScore">Argument of <see cref="FitnessScore"/> type. Fintess function to rank the backtest results</param> /// <param name="filterEnabled">Indicates whether to apply fitness filter to backtest results</param> public AlgorithmOptimumFinder(DateTime start, DateTime end, FitnessScore fitScore, bool filterEnabled) { // Assign Dates and Criteria to sort the results StartDate = start; EndDate = end; FitnessScore = fitScore; // Common properties var selection = new RouletteWheelSelection(); // Properties specific to optimization modes IFitness fitness; PopulationBase population; ITaskExecutor executor; ITermination termination; // Task execution mode switch (Shared.Config.TaskExecutionMode) { // Enable fitness filtering while searching for optimum parameters case TaskExecutionMode.Linear: executor = new LinearTaskExecutor(); fitness = new OptimizerFitness(StartDate, EndDate, fitScore, filterEnabled); break; case TaskExecutionMode.Parallel: executor = new ParallelTaskExecutor(); fitness = new OptimizerFitness(StartDate, EndDate, fitScore, filterEnabled); break; case TaskExecutionMode.Azure: executor = new ParallelTaskExecutor(); fitness = new AzureFitness(StartDate, EndDate, fitScore, filterEnabled); break; default: throw new Exception("Executor initialization failed"); } // Optimization mode switch (Shared.Config.OptimizationMode) { case OptimizationMode.BruteForce: { // Create cartesian population population = new PopulationCartesian(Shared.Config.GeneConfigArray); termination = new GenerationNumberTermination(1); break; } case OptimizationMode.Genetic: { // Create random population population = new PopulationRandom(Shared.Config.GeneConfigArray, Shared.Config.PopulationInitialSize) { GenerationMaxSize = Shared.Config.GenerationMaxSize }; // Logical terminaton var localTerm = new LogicalOrTermination(); localTerm.AddTermination(new FruitlessGenerationsTermination(3)); if (Shared.Config.Generations.HasValue) { localTerm.AddTermination(new GenerationNumberTermination(Shared.Config.Generations.Value)); } if (Shared.Config.StagnationGenerations.HasValue) { localTerm.AddTermination(new FitnessStagnationTermination(Shared.Config.StagnationGenerations.Value)); } termination = localTerm; break; } default: throw new Exception("Optimization mode specific objects were not initialized"); } // Create GA itself GenAlgorithm = new GeneticAlgorithm(population, fitness, executor) { // Reference types Selection = selection, Termination = termination, // Values types CrossoverParentsNumber = Shared.Config.CrossoverParentsNumber, CrossoverMixProbability = Shared.Config.CrossoverMixProbability, MutationProbability = Shared.Config.MutationProbability }; }