/// <summary> /// Perform a single point crossover. /// </summary> public static void Mutate(ICell cell) { if (cell == null) throw new ArgumentNullException("cell"); // Iterate the tags and the resources within the tags for (int i = 0; i < cell.ActiveTagsInModel; i++) { // Potentially modify existing tag resources Tag activeTag = cell.GetTagByIndex(i); for (int j = 0; j < activeTag.Data.Count; j++) { if (ShouldMutateThisPoint()) { activeTag.Data[j] = Resource.Random(true); } } // Potentially add a resource if (activeTag.Data.Count < Tag.MaxSize && ShouldMutateThisPoint()) { int insertionIndex = RandomProvider.Next(0, activeTag.Data.Count); activeTag.Data.Insert(insertionIndex, Resource.Random(true)); } // Potentially remove a resource if (activeTag.Data.Count > 2 && ShouldMutateThisPoint()) { activeTag.Data.RemoveRandom(); } } }
/// <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}; }