예제 #1
0
        /// <summary>
        /// order-based crossover operator (OX2)
        /// Precondition: parent1 and parent2 contain the same alleles.
        /// Postcondition: child contains the same alleles as parent1.
        /// </summary>
        /// <param name="parent1"></param>
        /// <param name="parent2"></param>
        /// <returns></returns>
        public Genotype OrderBasedCrossover(Genotype parent1, Genotype parent2)
        {
            var count = parent1.Count;

            if (count <= 1)
            {
                return(parent1);
            }

            var minNumberOfPositions = (int)Math.Max(1, count * MinimumNumberOfPositionsFactor);
            var maxNumberOfPositions = (int)Math.Max(1, count * MaximumNumberOfPositionsFactor);
            var numberOfPositions    = random.Next(minNumberOfPositions, maxNumberOfPositions);

            // select alleles
            var selectedAllelesP2 = new HashSet <int>();

            for (int i = 0; i < numberOfPositions; i++)
            {
                if (!selectedAllelesP2.Add(parent2[random.Next(0, count)]))
                {
                    // already selected, try again
                    i--;
                }
            }

            // copy alleles from parent1 which are not selected
            var emptyIndices = new List <int>(count - numberOfPositions);
            var child        = new int[count];

            for (int i = 0; i < count; i++)
            {
                var allele = parent1[i];
                if (!selectedAllelesP2.Contains(allele))
                {
                    child[i] = allele;
                }
                else
                {
                    emptyIndices.Add(i);
                }
            }

            // add the missing alleles in the order they appear in parent2
            var nextPositionParent2 = 0;
            var missingAlleles      = parent2.Intersect(selectedAllelesP2).ToArray();

            foreach (var i in emptyIndices)
            {
                // find next allele
                child[i] = missingAlleles[nextPositionParent2];
                nextPositionParent2++;
            }

            return(new Genotype(child));
        }