/// <summary> /// Will compare two instances of genotypes with one another. The comparison is gene by gene. /// </summary> /// <remarks> /// One consequence of how this method is currently implemented is that if there is a random mutation that is a deletion, it will be 'off by one'. In this case, a couple could have a radically different child. /// This may or may not be a good thing, but it's certainly something to keep in mind. /// </remarks> /// <param name="comparison">The genotype to compare with.</param> /// <returns>The percentage of similarity.</returns> public double SimilarTo(Genotype comparison) { // get the number of genes that are exactly equal in value. int count = this.Genes.Where((target, iterator) => iterator < comparison.Genes.Count && comparison.Genes[iterator].Value == target.Value).Count(); // return the number of genes that are equal divided by the total number. return (double)count / Math.Max(this.Genes.Count, comparison.Genes.Count); }
/// <summary> /// Will compare two instances of genotypes with one another. The comparison is gene by gene. /// </summary> /// <remarks> /// One consequence of how this method is currently implemented is that if there is a random mutation that is a deletion, it will be 'off by one'. In this case, a couple could have a radically different child. /// This may or may not be a good thing, but it's certainly something to keep in mind. /// </remarks> /// <param name="comparison">The genotype to compare with.</param> /// <returns>The percentage of similarity.</returns> public double SimilarTo(Genotype comparison) { // get the number of genes that are exactly equal in value. int count = this.Genes.Where((target, iterator) => iterator < comparison.Genes.Count && comparison.Genes[iterator].Value == target.Value).Count(); // return the number of genes that are equal divided by the total number. return((double)count / Math.Max(this.Genes.Count, comparison.Genes.Count)); }
/// <summary> /// The mother and father produces a child. /// </summary> /// <returns>The child produced</returns> public Genotype GetChild() { // TODO Add checks for different genotype lengths. // TODO difference of lengths too great will produce could produce a null offspring // TODO There is a random chance of producing a null offspring no matter what // TODO There is a random chance of producing a really crazy off spring? // TODO Add possibility of multiple children? var genotype = new Genotype(); for (int i = 0; i < Couple.Mother.Genes.Count; i++) { var mutate = this.ShouldMutate(); // Handle different genotype lengths if (i < Couple.Father.Genes.Count && (Couple.Father.Genes[i] != Couple.Mother.Genes[i] || mutate)) { if (mutate) { this.Mutate(genotype); } else { // Randomly take mother or father genotype.Genes.Add(RandomNumberSource.GetNext(1) == 1 ? Couple.Mother.Genes[i] : Couple.Father.Genes[i]); } } else if (i < Couple.Father.Genes.Count) { // mothers genes are longer genotype.Genes.Add(Couple.Mother.Genes[i]); } else { // they are equal genotype.Genes.Add(Couple.Mother.Genes[i]); } } if (Couple.Father.Genes.Count > Couple.Mother.Genes.Count) { for (var i = Couple.Father.Genes.Count - Couple.Mother.Genes.Count; i < Couple.Father.Genes.Count; i++) { if (this.ShouldMutate()) { this.Mutate(genotype); } else { genotype.Genes.Add(Couple.Father.Genes[i]); } } } return genotype; }
/// <summary> /// The mother and father produces a child. /// </summary> /// <returns>The child produced</returns> public Genotype GetChild() { // TODO Add checks for different genotype lengths. // TODO difference of lengths too great will produce could produce a null offspring // TODO There is a random chance of producing a null offspring no matter what // TODO There is a random chance of producing a really crazy off spring? // TODO Add possibility of multiple children? var genotype = new Genotype(); for (int i = 0; i < Couple.Mother.Genes.Count; i++) { var mutate = this.ShouldMutate(); // Handle different genotype lengths if (i < Couple.Father.Genes.Count && (Couple.Father.Genes[i] != Couple.Mother.Genes[i] || mutate)) { if (mutate) { this.Mutate(genotype); } else { // Randomly take mother or father genotype.Genes.Add(RandomNumberSource.GetNext(1) == 1 ? Couple.Mother.Genes[i] : Couple.Father.Genes[i]); } } else if (i < Couple.Father.Genes.Count) { // mothers genes are longer genotype.Genes.Add(Couple.Mother.Genes[i]); } else { // they are equal genotype.Genes.Add(Couple.Mother.Genes[i]); } } if (Couple.Father.Genes.Count > Couple.Mother.Genes.Count) { for (var i = Couple.Father.Genes.Count - Couple.Mother.Genes.Count; i < Couple.Father.Genes.Count; i++) { if (this.ShouldMutate()) { this.Mutate(genotype); } else { genotype.Genes.Add(Couple.Father.Genes[i]); } } } return(genotype); }
/// <summary> /// Constructs a random genotype of the requested size. /// </summary> /// <param name="size">The length of the genome to construct</param> /// <returns>The constructed Genotype</returns> public static Genotype GetRandomGenotype(int size) { var genotype = new Genotype(); for (var j = 0; j < size; j++) { genotype.Genes.Add(Gene.GetRandomGene()); } return genotype; }
/// <summary> /// Constructs a random genotype of the requested size. /// </summary> /// <param name="size">The length of the genome to construct</param> /// <returns>The constructed Genotype</returns> public static Genotype GetRandomGenotype(int size) { var genotype = new Genotype(); for (var j = 0; j < size; j++) { genotype.Genes.Add(Gene.GetRandomGene()); } return(genotype); }
/// <summary> /// The create random population. /// </summary> /// <param name="populationSize"> /// The population size. /// </param> /// <param name="genotypeSize"> /// The genotype size. /// </param> /// <param name="chanceOfMutation"> /// The chance of mutation. /// </param> /// <returns> /// The <see cref="Generation"/>. /// </returns> public static Generation CreateRandomPopulation(int populationSize, int genotypeSize, double chanceOfMutation) { var genotypes = new List <Genotype>(); for (int i = 0; i < populationSize; i++) { genotypes.Add(Genotype.GetRandomGenotype(genotypeSize)); } return(new Generation(chanceOfMutation, genotypes)); }
/// <summary> /// Performs a mutation on the given genotype /// </summary> /// <param name="genotype"> /// The genotype. /// </param> private void Mutate(Genotype genotype) { // Delete current gene, add 1 random, or 2 random int next = RandomNumberSource.GetNext(2); if (next == 2 || next == 1) { this.AddRandomGene(genotype); } else if (next == 2) { this.AddRandomGene(genotype); } }
/// <summary> /// The add random gene. /// </summary> /// <param name="genotype"> /// The genotype. /// </param> private void AddRandomGene(Genotype genotype) { genotype.Genes.Add(Gene.GetRandomGene()); }