-
-
Notifications
You must be signed in to change notification settings - Fork 335
/
AlternatingPositionCrossover.cs
84 lines (74 loc) · 3.37 KB
/
AlternatingPositionCrossover.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
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace GeneticSharp
{
/// <summary>
/// Alternating-position (AP).
/// <remarks>
/// <para>
/// The alternating position crossover operator (Larrañaga et al. 1996a) simply creates an offspring by selecting alternately the next
/// element of the first parent and the next element of the second parent, omitting the elements already present in the offspring
/// </para>
/// <para>
/// For example, if parent 1 is (1 2 3 4 5 6 7 8) and parent 2 is (3 7 5 1 6 8 2 4)
/// the AP operator gives the following offspring: (1 3 2 7 5 4 6 8)
/// </para>
/// <para>
/// Exchanging the parents results in (3 1 7 2 5 4 6 8).
/// <see href="../docs/Genetic Algorithms for the Travelling Salesman Problem - A Review of Representations and Operators.pdf">Genetic Algorithms for the Travelling Salesman Problem: A Review of Representations and Operators</see>
/// </para>
/// </remarks>
/// </summary>
[DisplayName("Alternating-position (AP)")]
public sealed class AlternatingPositionCrossover : CrossoverBase
{
/// <summary>
/// Initializes a new instance of the <see cref="GeneticSharp.VotingRecombinationCrossover"/> class.
/// </summary>
public AlternatingPositionCrossover() : base(2, 2)
{
IsOrdered = true;
}
/// <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)
{
if (parents.AnyHasRepeatedGene())
{
throw new CrossoverException(this, "The Alternating-position (AP) can be only used with ordered chromosomes. The specified chromosome has repeated genes.");
}
var p1 = parents[0];
var p2 = parents[1];
var child1 = CreateChild(p1, p2);
var child2 = CreateChild(p2, p1);
return new List<IChromosome> { child1, child2 };
}
private static IChromosome CreateChild(IChromosome firstParent, IChromosome secondParent)
{
var child = firstParent.CreateNew();
var childGenes = new Gene[firstParent.Length];
var childGenesIndex = 0;
for (int i = 0; i < firstParent.Length && childGenesIndex < firstParent.Length; i++)
{
AddChildGene(childGenes, ref childGenesIndex, firstParent.GetGene(i));
// The childGenesIndes could be incremented by the previous AddChildGene call
if (childGenesIndex < secondParent.Length)
AddChildGene(childGenes, ref childGenesIndex, secondParent.GetGene(i));
}
child.ReplaceGenes(0, childGenes);
return child;
}
private static void AddChildGene(Gene[] childGenes, ref int childGenesIndex, Gene parentGene)
{
if (!childGenes.Contains(parentGene))
{
childGenes[childGenesIndex] = parentGene;
childGenesIndex++;
}
}
}
}