Exemple #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);
        }
Exemple #2
0
        /// <summary>
        /// Mutates each bit of a <see cref="ListEntityBase{T}"/> if it meets a certain
        /// probability.
        /// </summary>
        /// <param name="entity"><see cref="ListEntityBase{T}"/> 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));
            }

            bool isMutated = false;
            ListEntityBase <bool> bsEntity = (ListEntityBase <bool>)entity;

            for (int i = 0; i < bsEntity.Length; i++)
            {
                if (RandomNumberService.Instance.GetDouble() <= this.MutationRate)
                {
                    isMutated = true;
                    if (!bsEntity[i])
                    {
                        bsEntity[i] = true;
                    }
                    else
                    {
                        bsEntity[i] = false;
                    }
                }
            }
            return(isMutated);
        }
        /// <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 crossoverLocus1 = RandomNumberService.Instance.GetRandomValue(listEntity1.Length);
            int crossoverLocus2 = RandomNumberService.Instance.GetRandomValue(listEntity2.Length);

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

            List <object?> entity1Elements = GetEntityElements(listEntity1);
            List <object?> entity2Elements = GetEntityElements(listEntity2);

            ReplaceBits(listEntity1, entity2Elements, crossoverLocus1, crossoverLocus2);
            ReplaceBits(listEntity2, entity1Elements, crossoverLocus2, crossoverLocus1);

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

            return(crossoverOffspring);
        }
 /// <summary>
 /// Replaces the elements in <paramref name="entity"/>, starting at <paramref name="targetCrossoverLocus"/>,
 /// with the elements located in <paramref name="sourceElements"/> starting at <paramref name="sourceCrossoverLocus"/>.
 /// </summary>
 /// <param name="entity"><see cref="ListEntityBase"/> whose bits are to be replaced.</param>
 /// <param name="sourceElements">List of elements to replace with.</param>
 /// <param name="targetCrossoverLocus">Element position at which to begin replacement.</param>
 /// <param name="sourceCrossoverLocus">Element position of the source elements to begin copying from.</param>
 private static void ReplaceBits(ListEntityBase entity, List <object?> sourceElements, int targetCrossoverLocus, int sourceCrossoverLocus)
 {
     entity.Length = targetCrossoverLocus + sourceElements.Count - sourceCrossoverLocus;
     for (int sourceBitIndex = sourceCrossoverLocus, targetBitIndex = targetCrossoverLocus; sourceBitIndex < sourceElements.Count; sourceBitIndex++, targetBitIndex++)
     {
         entity.SetValue(targetBitIndex, sourceElements[sourceBitIndex]);
     }
 }
        /// <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);
        }
Exemple #7
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);
        }
        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);
        }
Exemple #9
0
        /// <summary>
        /// Returns whether <paramref name="component"/> is valid.
        /// </summary>
        /// <param name="component"><see cref="GeneticComponent"/> to be validated.</param>
        /// <param name="errorMessage">Error message that should be displayed if the component fails validation.</param>
        /// <returns>True if <paramref name="component"/> is valid; otherwise, false.</returns>
        public override bool IsValid(GeneticComponent component, out string?errorMessage)
        {
            errorMessage = null;

            ListEntityBase entity = (ListEntityBase)component;

            if (entity.MinimumStartingLength > entity.MaximumStartingLength)
            {
                errorMessage = StringUtil.GetFormattedString(
                    Resources.ErrorMsg_MismatchedMinMaxValues,
                    nameof(ListEntityBase.MinimumStartingLength),
                    nameof(ListEntityBase.MaximumStartingLength));
            }

            return(errorMessage == null);
        }
        /// <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);
        }
        /// <summary>
        /// Executes a single-point crossover between two list-based entities.
        /// </summary>
        /// <param name="parents">The <see cref="GeneticEntity"/> objects to be operated upon.</param>
        /// <returns>
        /// Collection of the list-based entities 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;

            List <int> crossoverLoci = new List <int>();

            int minLength = Math.Min(entity1Length, entity2Length);

            // Generate the set of crossover points.
            for (int i = 0; i < this.CrossoverPointCount; i++)
            {
                int crossoverLocus;
                do
                {
                    crossoverLocus = RandomNumberService.Instance.GetRandomValue(minLength);
                } while (crossoverLoci.Contains(crossoverLocus));

                crossoverLoci.Add(crossoverLocus);
            }

            crossoverLoci.Sort();

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

            // If the number of crossover points is odd and the lengths of the entities are not the
            // same, the crossover will cause the lengths of the entities to be swapped.
            bool entityLengthsAreSwapped = (this.CrossoverPointCount % 2 != 0 && entity1Length != entity2Length);

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

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

            ListEntityBase originalEntity1 = (ListEntityBase)listEntity1.Clone();
            ListEntityBase originalEntity2 = (ListEntityBase)listEntity2.Clone();

            ListEntityBase entity1Source = listEntity1;
            ListEntityBase entity2Source = listEntity2;

            for (int i = crossoverLoci[0]; i < maxLength; i++)
            {
                // If this is a crossover point, swap the source entities
                if (crossoverLoci.Contains(i))
                {
                    if (listEntity1 == entity1Source)
                    {
                        entity1Source = listEntity2;
                        entity2Source = listEntity1;
                    }
                    else
                    {
                        entity1Source = listEntity1;
                        entity2Source = listEntity2;
                    }
                }

                object?entity1SourceVal = null;
                object?entity2SourceVal = null;

                if (i < listEntity1.Length)
                {
                    entity1SourceVal = this.GetEntityValue(i, listEntity1, entity1Source, originalEntity1, originalEntity2);
                }

                if (i < listEntity2.Length)
                {
                    entity2SourceVal = this.GetEntityValue(i, listEntity2, entity2Source, originalEntity2, originalEntity1);
                }

                if (entity1SourceVal != null)
                {
                    listEntity1.SetValue(i, entity1SourceVal);
                }

                if (entity2SourceVal != null)
                {
                    listEntity2.SetValue(i, entity2SourceVal);
                }
            }

            if (entityLengthsAreSwapped)
            {
                // Set the length based on their swapped length
                listEntity1.Length = entity2Length;
                listEntity2.Length = entity1Length;
            }

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

            return(crossoverOffspring);
        }