forked from giacomelli/GeneticSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PositionBasedCrossover.cs
81 lines (70 loc) · 2.84 KB
/
PositionBasedCrossover.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using GeneticSharp.Domain.Chromosomes;
using GeneticSharp.Domain.Randomizations;
namespace GeneticSharp.Domain.Crossovers
{
/// <summary>
/// Position-based crossover (POS).
/// <remarks>
/// The position-based crossover operator (POS), which was also suggested in connection with schedule problems,
/// is a second modification of the OX1 operator. It also starts with selecting a random set of positions in
/// the parent strings. However, this operator imposes the position of the selected elements on the
/// corresponding elements of the other parent. For example, consider the parents (1 2 3 4 5 6 7 8)
/// and (2 4 6 8 7 5 3 1), and suppose that the second, third and sixth positions are selected.
/// This leads to the following offspring: (1 4 6 2 3 5 7 8) and (4 2 3 8 7 6 5 1).
/// </remarks>
/// </summary>
[DisplayName("Position-based (POS)")]
public class PositionBasedCrossover : OrderBasedCrossover
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="GeneticSharp.Domain.Crossovers.PositionBasedCrossover"/> class.
/// </summary>
public PositionBasedCrossover()
{
}
#endregion
#region Methods
/// <summary>
/// Validates the parents.
/// </summary>
/// <param name="parents">The parents.</param>
protected override void ValidateParents(IList<IChromosome> parents)
{
if (parents.AnyHasRepeatedGene())
{
throw new CrossoverException(this, "The Position-based Crossover (POS) can be only used with ordered chromosomes. The specified chromosome has repeated genes.");
}
}
/// <summary>
/// Creates the child.
/// </summary>
/// <param name="firstParent">First parent.</param>
/// <param name="secondParent">Second parent.</param>
/// <param name="swapIndexes">The swap indexes.</param>
/// <returns>
/// The child.
/// </returns>
protected override IChromosome CreateChild(IChromosome firstParent, IChromosome secondParent, int[] swapIndexes)
{
var firstParentGenes = new List<Gene>(firstParent.GetGenes());
var child = firstParent.CreateNew();
for (int i = 0; i < firstParent.Length; i++)
{
if (swapIndexes.Contains(i))
{
var gene = secondParent.GetGene(i);
firstParentGenes.Remove(gene);
firstParentGenes.Insert(i, gene);
}
}
child.ReplaceGenes(0, firstParentGenes.ToArray());
return child;
}
#endregion
}
}