/// <summary> /// /// </summary> /// <param name="individual">not null > 0</param> private void InversionMutate(Genotype individual) { var count = individual.Count; var inversionSize = Math.Min(count, GetMutationSize(2, count * MutationSizeStdevFactor)); var inversionStart = random.Next(0, count - inversionSize + 1); var mutationSubset = individual.GetRange(inversionStart, inversionSize); var afterSubset = individual.GetRange(inversionStart + inversionSize, count - (inversionStart + inversionSize)); // remove everything after inversionStart individual.RemoveRange(inversionStart, count - inversionStart); // add reverse again mutationSubset.Reverse(); individual.AddRange(mutationSubset); // add subset after mutation again individual.AddRange(afterSubset); }
/// <summary> /// Replaces genotype with the parts of split /// </summary> /// <param name="genotype"></param> /// <param name="split"></param> private void RestoreGenotype(Genotype genotype, List <Genotype>[] split) { genotype.Clear(); foreach (var day in split) { foreach (var part in day) { genotype.AddRange(part); } } }
/// <summary> /// Returns generated genotypes and mapping from allele to visitId. /// The returned Genotypes are already repaired. /// </summary> /// <param name="input"></param> /// <param name="numberOfIndividuals"></param> /// <param name="maxNumberOfSantas"></param> /// <returns>Population and the AlleleToVisitIdMapping</returns> public (List <Genotype>, Dictionary <int, int>) Generate(OptimizationInput input, int numberOfIndividuals, int maxNumberOfSantas) { var numberOfSeparators = input.Days.Length * maxNumberOfSantas - 1; var alleleToVisitIdMapping = CreateAlleles(input); var elements = new Genotype(); elements.AddRange(alleleToVisitIdMapping.Keys); elements.AddRange(Enumerable.Range(-numberOfSeparators, numberOfSeparators)); var repairOperation = new RepairOperation(input, alleleToVisitIdMapping); var population = new List <Genotype>(numberOfIndividuals); for (int i = 0; i < numberOfIndividuals; i++) { elements.Shuffle(random); var genotype = new Genotype(elements); repairOperation.Repair(genotype); population.Add(genotype); } return(population, alleleToVisitIdMapping); }