/// <summary> /// Chromosome copying constructor. /// </summary> /// <param name="c"></param> public Chromosome(Chromosome c) { this.Lengths_3 = new List<int>(c.Lengths_3); this.Lengths_5 = new List<int>(c.Lengths_5); this.Score = new ScoreTotal (c.Score); this.Overlaps = new List<Overlap>(); foreach (Overlap o in c.Overlaps) { this.Overlaps.Add(new Overlap(o)); } }
/// <summary> /// Mutate one chromosome. /// </summary> /// <param name="solution">Solution to mutate.</param> /// <param name="rand">Randomizer.</param> /// <returns>Mutated chromosome.</returns> private Chromosome Mutate(Chromosome solution, Random rand) { int index; int value; if (rand.NextDouble() < 0.5D) { //Mutate 3' index = rand.Next(solution.Lengths_3.Count); value = rand.Next(this.Settings.MinLen_3, this.Settings.MaxLen_3 + 1); solution.Lengths_3[index] = value; } else { //Mutate 5' index = rand.Next(solution.Lengths_5.Count); value = rand.Next(this.Settings.MinLen_5, this.Settings.MaxLen_5 + 1); solution.Lengths_5[index] = value; } return solution; }
/// <summary> /// Lamarckian evolutionary algorithm for overlap optimization. /// </summary> /// <param name="o"></param> /// <param name="args"></param> public void LeaOptimizeOverlaps(object o, DoWorkEventArgs args) { stop = false; this.b = o as BackgroundWorker; Random rand = new Random(); List<Chromosome> population; List<Chromosome> nextPopulation = new List<Chromosome>(); int progress = 0; b.ReportProgress(progress); List<Chromosome> tournament; Chromosome mom, dad, child, best; Tuple<Chromosome, Chromosome> children; double variance; double maxVariance = 0.0; int i = 0; population = Populate(rand, this.Construct.Overlaps); //Local Search evaluates population EvaluatePopulation(population, this.Settings.LeaSettings.IgnoreHeterodimers); if (!stop) population = LocalSearch(population, rand, this.Settings.LeaSettings.IgnoreHeterodimers); best = new Chromosome(Tournament(population)); leaBest = new Chromosome(best); List<Chromosome> bestes = new List<Chromosome>(); leaBestAcrossGenerations.Add(best.Score.NormalizedScore); bestes.Add(new Chromosome(best)); do { //Selection do { //Crossover if (rand.NextDouble() <= this.Settings.LeaSettings.CrossoverRate) { tournament = SelectForTournament(this.Settings.LeaSettings.TournamentSize, population, rand); mom = Tournament(tournament); tournament = SelectForTournament(this.Settings.LeaSettings.TournamentSize, population, rand); dad = Tournament(tournament); children = Crossover(mom, dad, rand); nextPopulation.Add(children.Item1); nextPopulation.Add(children.Item2); } else { //Add two children without crossing over tournament = SelectForTournament(this.Settings.LeaSettings.TournamentSize, population, rand); child = new Chromosome(Tournament(tournament)); nextPopulation.Add(child); tournament = SelectForTournament(this.Settings.LeaSettings.TournamentSize, population, rand); child = new Chromosome(Tournament(tournament)); nextPopulation.Add(child); } } while (nextPopulation.Count < population.Count); //Mutation nextPopulation = MutatePopulation(nextPopulation, rand); //Local Search evaluates population if (!stop) EvaluatePopulation(nextPopulation, this.Settings.LeaSettings.IgnoreHeterodimers); if (!stop) nextPopulation = LocalSearch(nextPopulation, rand, this.Settings.LeaSettings.IgnoreHeterodimers); if (!stop) { best = Tournament(nextPopulation); bestes.Add(new Chromosome(best)); leaBestAcrossGenerations.Add(best.Score.NormalizedScore); } if (!stop && best.Score.NormalizedScore < leaBest.Score.NormalizedScore) { //copy the best solution so far leaBest = new Chromosome(best); } population.Clear(); population.AddRange(nextPopulation); nextPopulation.Clear(); // assess variance only if i > MinIterations variance = Variance(leaBestAcrossGenerations); if (variance > maxVariance) { maxVariance = variance; } //progress = 100 if epsilon == variance //if variance descending if (maxVariance > variance && i > this.Settings.LeaSettings.MinIterations) { //don't confuse the user progress = Math.Max((int)(100.0 * (double)i / (double)this.Settings.LeaSettings.MaxIterations), (int)((100.0 / maxVariance) * (maxVariance + this.Settings.LeaSettings.Epsilon - variance) + 0.5)); } else { progress = (int)Math.Max((100.0 * (double)i / (double)this.Settings.LeaSettings.MaxIterations), (double)progress); } if (progress > 100) { //when variance lower than epsilon progress = 100; } b.ReportProgress(progress); i++; } while (!stop && (progress < 100) && (i < this.Settings.LeaSettings.MaxIterations)); progress = 100; b.ReportProgress(progress); stop = false; if (leaBest == null || leaBest.Score.Equals(ScoreTotal.Inacceptable)) { throw new AssemblyException(); } else { this.Construct.Overlaps = leaBest.ToOverlaps(this.Templates); this.Construct.Evaluate(); } }
/// <summary> /// Perform uniform crossover. /// </summary> /// <param name="mom">Parent 1.</param> /// <param name="dad">Parent 2.</param> /// <param name="rand">Randomizer.</param> /// <returns>Tuple of children.</returns> private Tuple<Chromosome, Chromosome> Crossover(Chromosome mom, Chromosome dad, Random rand) { List<int> len_3_1 = new List<int>(); List<int> len_5_1 = new List<int>(); List<int> len_3_2 = new List<int>(); List<int> len_5_2 = new List<int>(); for (int i = 0; i < mom.Lengths_3.Count; i++) { if (rand.NextDouble() < 0.5) { len_3_1.Add(mom.Lengths_3[i]); len_5_1.Add(mom.Lengths_5[i]); len_3_2.Add(dad.Lengths_3[i]); len_5_2.Add(dad.Lengths_5[i]); } else { len_3_1.Add(dad.Lengths_3[i]); len_5_1.Add(dad.Lengths_5[i]); len_3_2.Add(mom.Lengths_3[i]); len_5_2.Add(mom.Lengths_5[i]); } } Chromosome child1 = new Chromosome(len_3_1, len_5_1, this.Settings.TargetTm); Chromosome child2 = new Chromosome(len_3_2, len_5_2, this.Settings.TargetTm); Tuple<Chromosome, Chromosome> children = new Tuple<Chromosome, Chromosome>(child1, child2); return children; }