forked from giacomelli/GeneticSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OnePointCrossover.cs
120 lines (109 loc) · 4.16 KB
/
OnePointCrossover.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using GeneticSharp.Domain.Chromosomes;
using GeneticSharp.Infrastructure.Framework.Texts;
namespace GeneticSharp.Domain.Crossovers
{
/// <summary>
/// One-Point crossover (C1).
/// <remarks>
/// A single crossover point on both parents is selected.
/// All data beyond that point in either is swapped between the two parents.
/// <see href="http://en.wikipedia.org/wiki/Crossover_(genetic_algorithm)#One-point_crossover">One-point crossover</see>
/// <example>
/// Parents:
/// |0|0|0| x |1|1|1|
/// Have two swap points indexes: 0 and 1.
/// <para>
/// 1)
/// new OnePointCrossover(0);
/// Children result:
/// |0|1|1| and |1|0|0|
/// </para>
/// <para>
/// 2)
/// new OnePointCrossover(1);
/// Children result:
/// |0|0|1| and |1|1|0|
/// </para>
/// </example>
/// </remarks>
/// </summary>
[DisplayName("One-Point")]
public class OnePointCrossover : CrossoverBase
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="GeneticSharp.Domain.Crossovers.OnePointCrossover"/> class.
/// </summary>
/// <param name="swapPointIndex">Swap point index.</param>
public OnePointCrossover(int swapPointIndex) : base(2, 2)
{
SwapPointIndex = swapPointIndex;
}
/// <summary>
/// Initializes a new instance of the <see cref="GeneticSharp.Domain.Crossovers.OnePointCrossover"/> class.
/// </summary>
public OnePointCrossover() : this(0)
{
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the index of the swap point.
/// </summary>
/// <value>The index of the swap point.</value>
public int SwapPointIndex { get; set; }
#endregion
#region Methods
/// <summary>
/// Performs the cross with specified parents generating the children.
/// </summary>
/// <param name="parents">The parents chromosomes.</param>
/// <returns>
/// The offspring (children) of the parents.
/// </returns>
protected override IList<IChromosome> PerformCross(IList<IChromosome> parents)
{
var firstParent = parents[0];
var secondParent = parents[1];
var swapPointsLength = firstParent.Length - 1;
if (SwapPointIndex >= swapPointsLength)
{
throw new ArgumentOutOfRangeException(
"parents",
"The swap point index is {0}, but there is only {1} genes. The swap should result at least one gene to each side.".With(SwapPointIndex, firstParent.Length));
}
return CreateChildren(firstParent, secondParent);
}
/// <summary>
/// Creates the children.
/// </summary>
/// <param name="firstParent">The first parent.</param>
/// <param name="secondParent">The second parent.</param>
/// <returns>The children chromosomes.</returns>
protected IList<IChromosome> CreateChildren(IChromosome firstParent, IChromosome secondParent)
{
var firstChild = CreateChild(firstParent, secondParent);
var secondChild = CreateChild(secondParent, firstParent);
return new List<IChromosome>() { firstChild, secondChild };
}
/// <summary>
/// Creates the child.
/// </summary>
/// <returns>The child.</returns>
/// <param name="leftParent">Left parent.</param>
/// <param name="rightParent">Right parent.</param>
protected virtual IChromosome CreateChild(IChromosome leftParent, IChromosome rightParent)
{
var cutGenesCount = SwapPointIndex + 1;
var child = leftParent.CreateNew();
child.ReplaceGenes(0, leftParent.GetGenes().Take(cutGenesCount).ToArray());
child.ReplaceGenes(cutGenesCount, rightParent.GetGenes().Skip(cutGenesCount).ToArray());
return child;
}
#endregion
}
}