private CodeTree <S, G, R> Combine(GenePool <S, G, R> genePool, CodeTree <S, G, R> source, CodeTree <S, G, R> remove, CodeTree <S, G, R> replace) { var copy = source; if (source == remove) { return(replace.Clone()); } if (copy.Node.Kind != NodeKind.Terminal) { for (int i = 0; i <= copy.Children.GetUpperBound(0); i++) { var child = Combine(genePool, copy.Children[i], remove, replace); copy.Children[i] = child; if (genePool.GetCanMutate()) { copy.Children[i].Node = genePool.GetTerminal(); } } } return(copy); }
public CodeTree(GenePool <S, G, R> genePool, Node node, int maxDepth) { Node = node; if (Node.Kind != NodeKind.Terminal) { Children = Enumerable.Range(1, Node.ChildCount).Select( x => new CodeTree <S, G, R>(genePool, GetNode(genePool, maxDepth), maxDepth - 1)).ToArray(); } }
private Node GetNode(GenePool <S, G, R> genePool, int maxDepth) { if (maxDepth > 0) { return(genePool.GetFunctionOrTerminal()); } else { return(genePool.GetTerminal()); } }
private void Crossover(GenePool <S, G, R> genePool, CodeTree <S, G, R> parent1, CodeTree <S, G, R> parent2, out CodeTree <S, G, R> child1, out CodeTree <S, G, R> child2) { var nodes1 = parent1.ToList(); var nodes2 = parent2.ToList(); int crossover1 = genePool.Next(0, nodes1.Count - 1); int crossover2 = genePool.Next(0, nodes2.Count - 1); child1 = Combine(genePool, parent1, nodes1[crossover1], nodes2[crossover2]); child2 = Combine(genePool, parent2, nodes2[crossover2], nodes1[crossover1]); }
public static void Evolve(S settings, CancellationTokenSource cts, Action <EntitySet <S, G, R> > onResultSet, Action <AggregateException> onErrors, Action onSuccess) { try { Contract.Requires(settings != null, nameof(settings)); settings.Validate(); var genePool = new GenePool <S, G, R>(settings); EntitySet <S, G, R> entitySet = null; for (var cohortId = 0; cohortId < settings.MaxCohorts; cohortId++) { entitySet = new EntitySet <S, G, R>( settings, genePool, cohortId, entitySet); var metGoals = entitySet.CompileAndRun(settings, cts); onResultSet(entitySet); if (metGoals) { break; } } onSuccess(); } catch (AggregateException errors) { onErrors(errors); } catch (Exception error) { onErrors(new AggregateException(error)); } }
internal EntitySet(S settings, GenePool <S, G, R> genePool, int cohortId, IEnumerable <Entity <S, G, R> > entities) { Cohort = new Cohort(cohortId); if (entities == null) { for (int entityId = 0; entityId <= settings.Population - 1; entityId++) { var codeTree = new CodeTree <S, G, R>( genePool, genePool.GetFunction(), settings.MaxTreeDepth); var knownAs = new KnownAs(Cohort, entityId); Items.Add(new Entity <S, G, R>(knownAs, codeTree)); } } else { Items.AddRange(entities.Take(settings.NumToKeep)); for (int entityId = Count; entityId <= settings.Population - 2; entityId += 2) { CodeTree <S, G, R> child1, child2, parent1, parent2; int index1, index2; SelectAndCloneParents(genePool, this, settings.NumToKeep, out index1, out parent1, out index2, out parent2); Crossover(genePool, parent1, parent2, out child1, out child2); Items.Add(new Entity <S, G, R>(new KnownAs(Cohort, entityId), this[index1].KnownAs, this[index2].KnownAs, child1)); Items.Add(new Entity <S, G, R>(new KnownAs(Cohort, entityId + 1), this[index1].KnownAs, this[index2].KnownAs, child2)); } } }
private void SelectAndCloneParents(GenePool <S, G, R> genePool, EntitySet <S, G, R> entitySet, int limit, out int index1, out CodeTree <S, G, R> parent1, out int index2, out CodeTree <S, G, R> parent2) { var totalFitness = 0.0; for (int i = 0; i < limit; i++) { totalFitness += entitySet[i].Report.Fitness; } index1 = -1; index2 = -1; while ((index1 == -1) | (index2 == -1)) { for (int i = 0; i < limit; i++) { var range = entitySet[i].Report.Fitness / totalFitness; if (genePool.InRange(range)) { if (index1 == -1) { index1 = i; } else { index2 = i; } } } } parent1 = entitySet[index1].CodeTree.DeepClone(); parent2 = entitySet[index2].CodeTree.DeepClone(); }