src/GenFx.Components/Lists/MultiPointCrossoverOperator.cs
/// <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>
Executes a single-point crossover between two list-based entities.
Executes a single - point crossover between two list - based entities .
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);
            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>();
            bool entityLengthsAreSwapped = (this.CrossoverPointCount % 2 != 0 && entity1Length != entity2Length);
            int maxLength = Math.Max(entity1Length, entity2Length);
            if (entityLengthsAreSwapped)
            {
                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 (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)
            {
                listEntity1.Length = entity2Length;
                listEntity2.Length = entity1Length;
            }
            crossoverOffspring.Add(listEntity1);
            crossoverOffspring.Add(listEntity2);
            return crossoverOffspring;
        }
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 ) ; 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 > ( ) ; bool entityLengthsAreSwapped = ( this . CrossoverPointCount % 2 != 0 && entity1Length != entity2Length ) ; int maxLength = Math . Max ( entity1Length , entity2Length ) ; if ( entityLengthsAreSwapped ) { 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 ( 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 ) { listEntity1 . Length = entity2Length ; listEntity2 . Length = entity1Length ; } crossoverOffspring . Add ( listEntity1 ) ; crossoverOffspring . Add ( listEntity2 ) ; return crossoverOffspring ; }
Executes a single-point crossover between two list-based entities.
Executes a single - point crossover between two list - based entities .
// Generate the set of crossover points. // 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. // Normalize the lists into a common length // If this is a crossover point, swap the source entities // Set the length based on their swapped length
Collection of the list-based entities resulting from the crossover.
Collection of the list - based entities resulting from the crossover .
parents
IList<GeneticEntity>
The  objects to be operated upon.
The objects to be operated upon .