예제 #1
0
        /// <summary>
        /// Mutates each element of a <see cref="ListEntityBase"/> if it meets a certain
        /// probability.
        /// </summary>
        /// <param name="entity"><see cref="ListEntityBase"/> to be mutated.</param>
        /// <returns>True if a mutation occurred; otherwise, false.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="entity"/> is null.</exception>
        protected override bool GenerateMutation(GeneticEntity entity)
        {
            if (entity is null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            ListEntityBase listEntity = (ListEntityBase)entity;

            if (RandomNumberService.Instance.GetDouble() <= this.MutationRate)
            {
                int firstPosition = RandomNumberService.Instance.GetRandomValue(listEntity.Length - 1);
                int secondPosition;
                do
                {
                    secondPosition = RandomNumberService.Instance.GetRandomValue(listEntity.Length - 1);
                } while (secondPosition == firstPosition);

                object?firstValue = listEntity.GetValue(firstPosition);
                listEntity.SetValue(firstPosition, listEntity.GetValue(secondPosition));
                listEntity.SetValue(secondPosition, firstValue);
                return(true);
            }

            return(false);
        }
예제 #2
0
        /// <summary>
        /// Mutates each bit of a <see cref="ListEntityBase"/> if it meets a certain
        /// probability.
        /// </summary>
        /// <param name="entity"><see cref="ListEntityBase"/> to be mutated.</param>
        /// <returns>True if a mutation occurred; otherwise, false.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="entity"/> is null.</exception>
        protected override bool GenerateMutation(GeneticEntity entity)
        {
            if (entity is null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            ListEntityBase listEntity = (ListEntityBase)entity;

            if (RandomNumberService.Instance.GetDouble() <= this.MutationRate)
            {
                int firstPosition = RandomNumberService.Instance.GetRandomValue(listEntity.Length);
                int secondPosition;
                do
                {
                    secondPosition = RandomNumberService.Instance.GetRandomValue(listEntity.Length);
                } while (secondPosition == firstPosition);

                if (firstPosition < secondPosition)
                {
                    object?currentMovingValue = listEntity.GetValue(firstPosition);
                    for (int i = firstPosition + 1; i <= secondPosition; i++)
                    {
                        object?savedValue = listEntity.GetValue(i);
                        listEntity.SetValue(i, currentMovingValue);
                        currentMovingValue = savedValue;
                    }

                    listEntity.SetValue(firstPosition, currentMovingValue);
                }
                else
                {
                    object?currentMovingValue = listEntity.GetValue(firstPosition);

                    for (int i = firstPosition - 1; i >= secondPosition; i--)
                    {
                        object?savedValue = listEntity.GetValue(i);
                        listEntity.SetValue(i, currentMovingValue);
                        currentMovingValue = savedValue;
                    }

                    listEntity.SetValue(firstPosition, currentMovingValue);
                }

                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Returns the list of bits contained in <paramref name="entity"/>.
        /// </summary>
        /// <param name="entity"><see cref="ListEntityBase"/> whose bits are to be returned.</param>
        /// <returns>List of bits contained in <paramref name="entity"/>.</returns>
        private static List <object?> GetEntityElements(ListEntityBase entity)
        {
            List <object?> elements = new List <object?>();

            for (int i = 0; i < entity.Length; i++)
            {
                elements.Add(entity.GetValue(i));
            }
            return(elements);
        }
        /// <summary>
        /// Returns whether the entity contains the specified value.
        /// </summary>
        /// <param name="entity">Entity to use.</param>
        /// <param name="value">Value to search for.</param>
        /// <param name="maxIndex">The max index to iterate to when searching for the value.</param>
        /// <returns>True if the value was found; otherwise, false.</returns>
        private static bool ContainsValue(ListEntityBase entity, object?value, int maxIndex)
        {
            for (int i = 0; i <= maxIndex; i++)
            {
                if (Object.Equals(entity.GetValue(i), value))
                {
                    return(true);
                }
            }

            return(false);
        }
        private object?GetEntityValue(int index, ListEntityBase entity, ListEntityBase sourceEntity, ListEntityBase originalEntity, ListEntityBase originalOtherEntity)
        {
            object?entitySourceVal = sourceEntity.GetValue(index);

            if (((ListEntityBase?)this.Algorithm?.GeneticEntitySeed)?.RequiresUniqueElementValues == true)
            {
                while (ContainsValue(entity, entitySourceVal, index - 1))
                {
                    int duplicateValueIndex = originalOtherEntity.IndexOf(entitySourceVal);
                    entitySourceVal = originalEntity.GetValue(duplicateValueIndex);
                }
            }

            return(entitySourceVal);
        }
        /// <summary>
        /// When overriden in a derived class, generates a crossover based on the parent entities.
        /// </summary>
        /// <param name="parents">The <see cref="GeneticEntity"/> objects to be operated upon.</param>
        /// <returns>
        /// Collection of the <see cref="GeneticEntity"/> objects resulting from the crossover.
        /// </returns>
        protected override IEnumerable <GeneticEntity> GenerateCrossover(IList <GeneticEntity> parents)
        {
            if (parents == null)
            {
                throw new ArgumentNullException(nameof(parents));
            }

            ListEntityBase listEntity1 = (ListEntityBase)parents[0];
            ListEntityBase listEntity2 = (ListEntityBase)parents[1];

            int entity1Length = listEntity1.Length;
            int entity2Length = listEntity2.Length;

            int crossoverLocus = RandomNumberService.Instance.GetRandomValue(Math.Min(entity1Length, entity2Length));

            IList <GeneticEntity> crossoverOffspring = new List <GeneticEntity>();

            int maxLength = Math.Max(entity1Length, entity2Length);

            // Normalize the lists into a common length
            if (entity1Length != entity2Length)
            {
                listEntity1.Length = maxLength;
                listEntity2.Length = maxLength;
            }

            // swap the elements of the lists starting at the crossover locus
            for (int i = crossoverLocus; i < maxLength; i++)
            {
                object?tempGeneValue = listEntity1.GetValue(i);
                listEntity1.SetValue(i, listEntity2.GetValue(i));
                listEntity2.SetValue(i, tempGeneValue);
            }

            // Set the length based on their swapped length
            listEntity1.Length = entity2Length;
            listEntity2.Length = entity1Length;

            crossoverOffspring.Add(listEntity1);
            crossoverOffspring.Add(listEntity2);

            return(crossoverOffspring);
        }