/// <summary> /// Perform a multi-point crossover. /// </summary> protected override IList<ICell> Reproduce(ICell actor, ICell target) { if (actor == null) throw new ArgumentNullException("actor"); if (target == null) throw new ArgumentNullException("target"); // Percentage of each tag crossing over is normalized to produce one // cross on average by default. This is modified by the CrossoverFactor. int crossoverPercent = (int) (100 / actor.ActiveTagsInModel * CrossoverFactor); ICell child1 = actor.CreateEmptyCell(); ICell child2 = actor.CreateEmptyCell(); for (int i = 0; i < actor.ActiveTagsInModel; i++) { if (RandomProvider.Next(100) < crossoverPercent) { Tag actorTag = actor.GetTagByIndex(i); Tag targetTag = target.GetTagByIndex(i); Tag childTag1 = null; Tag childTag2 = null; CrossoverInteraction.CrossOverTags(actorTag, targetTag, out childTag1, out childTag2); child1.SetTagByIndex(i, childTag1); child2.SetTagByIndex(i, childTag2); } else { child1.SetTagByIndex(i, Tag.New(actor.GetTagByIndex(i))); child2.SetTagByIndex(i, Tag.New(target.GetTagByIndex(i))); } } if (AllowMutation) { PointMutation.Mutate(child1); PointMutation.Mutate(child1); } return new List<ICell>() { child1, child2 }; }
/// <summary> /// Perform a single point crossover. /// </summary> protected override IList<ICell> Reproduce(ICell actor, ICell target) { if (actor == null) throw new ArgumentNullException("actor"); if (target == null) throw new ArgumentNullException("target"); // Select the tag to crossover int crossoverIndex = RandomProvider.Next(0, actor.ActiveTagsInModel - 1); // Create two new cells like this (assuming crossover in tag 3): // // AAAA AAAA AATT TTTT // TTTT TTTT TTAA AAAA ICell child1 = actor.CreateEmptyCell(); ICell child2 = actor.CreateEmptyCell(); for (int i = 0; i < actor.ActiveTagsInModel; i++) { if (i < crossoverIndex) { child1.SetTagByIndex(i, Tag.New(actor.GetTagByIndex(i))); child2.SetTagByIndex(i, Tag.New(target.GetTagByIndex(i))); } else if (i > crossoverIndex) { child1.SetTagByIndex(i, Tag.New(target.GetTagByIndex(i))); child2.SetTagByIndex(i, Tag.New(actor.GetTagByIndex(i))); } else // i == crossoverIndex { // There are length+1 crossover points for a Tag (start, end, length-1 midpoints) Tag actorTag = actor.GetTagByIndex(i); Tag targetTag = target.GetTagByIndex(i); Tag childTag1 = null; Tag childTag2 = null; CrossOverTags(actorTag, targetTag, out childTag1, out childTag2); child1.SetTagByIndex(i, childTag1); child2.SetTagByIndex(i, childTag2); } } if (AllowMutation) { PointMutation.Mutate(child1); PointMutation.Mutate(child1); } return new List<ICell>() {child1, child2}; }