/// <inheritdoc/> public override void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { var target = ObtainGenome(parents, parentIndex, offspring, offspringIndex); if (target.LinksChromosome.Count < MinLink) { // don't remove from small genomes return; } // determine the target and remove var index = RangeRandomizer.RandomInt(0, target .LinksChromosome.Count - 1); NEATLinkGene targetGene = target.LinksChromosome[index]; target.LinksChromosome.Remove(targetGene); // if this orphaned any nodes, then kill them too! if (!IsNeuronNeeded(target, targetGene.FromNeuronId)) { RemoveNeuron(target, targetGene.FromNeuronId); } if (!IsNeuronNeeded(target, targetGene.ToNeuronId)) { RemoveNeuron(target, targetGene.ToNeuronId); } }
private void NewCase_Click(object sender, RoutedEventArgs e) { EncogRandom r = new EncogRandom(); this.resolution = int.Parse(((ComboBoxItem)Resolution.SelectedValue).Content.ToString()); this.testCase.InitTestCase(r.Next(3)); Render(); }
/// <inheritdoc/> public NEATGenome Factor(EncogRandom rnd, NEATPopulation pop, int inputCount, int outputCount, double connectionDensity) { return new NEATGenome(rnd, pop, inputCount, outputCount, connectionDensity); }
/// <inheritdoc /> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { IEvolutionaryOperator opp = _components.Pick(rnd); opp.PerformOperation(rnd, parents, parentIndex, offspring, offspringIndex); }
/// <summary> /// Construct the EA worker. /// </summary> /// <param name="theTrain">The trainer.</param> /// <param name="theSpecies">The species.</param> public EAWorker(BasicEA theTrain, ISpecies theSpecies) { _train = theTrain; _species = theSpecies; _rnd = _train.RandomNumberFactory.Factor(); _parents = new IGenome[_train.Operators.MaxParents()]; _children = new IGenome[_train.Operators.MaxOffspring()]; }
/// <inheritdoc /> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { var program = (EncogProgram) parents[0]; EncogProgramContext context = program.Context; EncogProgram result = context.CloneProgram(program); MutateNode(rnd, result.RootNode); offspring[0] = result; }
/// <inheritdoc/> public override void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { int countTrysToAddLink = Owner.MaxTries; NEATGenome target = ObtainGenome(parents, parentIndex, offspring, offspringIndex); // the link will be between these two neurons long neuron1Id = -1; long neuron2Id = -1; // try to add a link while ((countTrysToAddLink--) > 0) { NEATNeuronGene neuron1 = ChooseRandomNeuron(target, true); NEATNeuronGene neuron2 = ChooseRandomNeuron(target, false); if (neuron1 == null || neuron2 == null) { return; } // do not duplicate // do not go to a bias neuron // do not go from an output neuron // do not go to an input neuron if (!IsDuplicateLink(target, neuron1.Id, neuron2.Id) && (neuron2.NeuronType != NEATNeuronType.Bias) && (neuron2.NeuronType != NEATNeuronType.Input)) { if (((NEATPopulation)Owner.Population).ActivationCycles != 1 || neuron1.NeuronType != NEATNeuronType.Output) { neuron1Id = neuron1.Id; neuron2Id = neuron2.Id; break; } } } // did we fail to find a link if ((neuron1Id < 0) || (neuron2Id < 0)) { return; } double r = ((NEATPopulation)target.Population).WeightRange; CreateLink(target, neuron1Id, neuron2Id, RangeRandomizer.Randomize(rnd, -r, r)); target.SortGenes(); }
/// <inheritdoc /> public override ProgramNode CreateNode(EncogRandom rnd, EncogProgram program, int depthRemaining, IList<EPLValueType> types) { int actualDepthRemaining = depthRemaining; if (rnd.NextDouble() > 0.5) { return _fullGenerator.CreateNode(rnd, program, actualDepthRemaining, types); } return _growGenerator.CreateNode(rnd, program, actualDepthRemaining, types); }
/// <inheritdoc /> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { var parent1 = (EncogProgram) parents[0]; var parent2 = (EncogProgram) parents[1]; offspring[0] = null; EncogProgramContext context = parent1.Context; int size1 = parent1.RootNode.Count; int size2 = parent2.RootNode.Count; bool done = false; int tries = 100; while (!done) { int p1Index = rnd.Next(size1); int p2Index = rnd.Next(size2); var holder1 = new LevelHolder(p1Index); var holder2 = new LevelHolder(p2Index); IList<EPLValueType> types = new List<EPLValueType>(); types.Add(context.Result.VariableType); FindNode(rnd, parent1.RootNode, types, holder1); FindNode(rnd, parent2.RootNode, types, holder2); if (LevelHolder.CompatibleTypes(holder1.Types, holder2.Types)) { EncogProgram result = context.CloneProgram(parent1); ProgramNode resultNode = parent1.FindNode(p1Index); ProgramNode p2Node = parent2.FindNode(p2Index); ProgramNode newInsert = context.CloneBranch(result, p2Node); result.ReplaceNode(resultNode, newInsert); offspring[0] = result; done = true; } else { tries--; if (tries < 0) { done = true; } } } }
/// <inheritdoc/> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { DoubleArrayGenome parent = (DoubleArrayGenome)parents[parentIndex]; offspring[offspringIndex] = parent.Population.GenomeFactory.Factor(); DoubleArrayGenome child = (DoubleArrayGenome)offspring[offspringIndex]; for (int i = 0; i < parent.Size; i++) { double value = parent.Data[i]; value += (perturbAmount - (rnd.NextDouble() * perturbAmount * 2)); child.Data[i] = value; } }
/// <inheritdoc /> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { var program = (EncogProgram) parents[0]; EncogProgramContext context = program.Context; EncogProgram result = context.CloneProgram(program); IList<EPLValueType> types = new List<EPLValueType>(); types.Add(context.Result.VariableType); var globalIndex = new int[1]; globalIndex[0] = rnd.Next(result.RootNode.Count); FindNode(rnd, result, result.RootNode, types, globalIndex); offspring[0] = result; }
/// <inheritdoc/> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { IArrayGenome parent = (IArrayGenome)parents[parentIndex]; offspring[offspringIndex] = this.owner.Population.GenomeFactory.Factor(); IArrayGenome child = (IArrayGenome)offspring[offspringIndex]; child.Copy(parent); int length = parent.Size; int iswap1 = (int)(rnd.NextDouble() * length); int iswap2 = (int)(rnd.NextDouble() * length); // can't be equal if (iswap1 == iswap2) { // move to the next, but // don't go out of bounds if (iswap1 > 0) { iswap1--; } else { iswap1++; } } // make sure they are in the right order if (iswap1 > iswap2) { int temp = iswap1; iswap1 = iswap2; iswap2 = temp; } child.Swap(iswap1, iswap2); }
/// <inheritdoc/> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { IArrayGenome mother = (IArrayGenome)parents[parentIndex]; IArrayGenome father = (IArrayGenome)parents[parentIndex + 1]; IArrayGenome offspring1 = (IArrayGenome)this.owner.Population.GenomeFactory.Factor(); IArrayGenome offspring2 = (IArrayGenome)this.owner.Population.GenomeFactory.Factor(); offspring[offspringIndex] = offspring1; offspring[offspringIndex + 1] = offspring2; int geneLength = mother.Size; // the chromosome must be cut at two positions, determine them int cutpoint1 = (int)(rnd.Next(geneLength - this.cutLength)); int cutpoint2 = cutpoint1 + this.cutLength; // handle cut section for (int i = 0; i < geneLength; i++) { if (!((i < cutpoint1) || (i > cutpoint2))) { offspring1.Copy(father, i, i); offspring2.Copy(mother, i, i); } } // handle outer sections for (int i = 0; i < geneLength; i++) { if ((i < cutpoint1) || (i > cutpoint2)) { offspring1.Copy(mother, i, i); offspring2.Copy(father, i, i); } } }
/// <inheritdoc/> public override void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { var target = ObtainGenome(parents, parentIndex, offspring, offspringIndex); var countTrysToFindOldLink = Owner.MaxTries; var pop = ((NEATPopulation)target.Population); // the link to split NEATLinkGene splitLink = null; int sizeBias = ((NEATGenome)parents[0]).InputCount + ((NEATGenome)parents[0]).OutputCount + 10; // if there are not at least int upperLimit; if (target.LinksChromosome.Count < sizeBias) { upperLimit = target.NumGenes - 1 - (int)Math.Sqrt(target.NumGenes); } else { upperLimit = target.NumGenes - 1; } while ((countTrysToFindOldLink--) > 0) { // choose a link, use the square root to prefer the older links int i = RangeRandomizer.RandomInt(0, upperLimit); NEATLinkGene link = target.LinksChromosome[i]; // get the from neuron long fromNeuron = link.FromNeuronId; if ((link.Enabled) && (target.NeuronsChromosome [GetElementPos(target, fromNeuron)] .NeuronType != NEATNeuronType.Bias)) { splitLink = link; break; } } if (splitLink == null) { return; } splitLink.Enabled = false; long from = splitLink.FromNeuronId; long to = splitLink.ToNeuronId; NEATInnovation innovation = ((NEATPopulation)Owner.Population).Innovations .FindInnovationSplit(from, to); // add the splitting neuron IActivationFunction af = ((NEATPopulation)Owner.Population).ActivationFunctions.Pick(new Random()); target.NeuronsChromosome.Add( new NEATNeuronGene(NEATNeuronType.Hidden, af, innovation .NeuronId, innovation.InnovationId)); // add the other two sides of the link CreateLink(target, from, innovation.NeuronId, splitLink.Weight); CreateLink(target, innovation.NeuronId, to, pop.WeightRange); target.SortGenes(); }
/// <inheritdoc /> public override ProgramNode CreateNode(EncogRandom rnd, EncogProgram program, int depthRemaining, IList<EPLValueType> types) { return CreateRandomNode(rnd, program, depthRemaining, types, true, true); }
/// <inheritdoc/> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { var mom = (NEATGenome)parents[parentIndex + 0]; var dad = (NEATGenome)parents[parentIndex + 1]; var best = FavorParent(rnd, mom, dad); var notBest = (best == mom) ? mom : dad; var selectedLinks = new List<NEATLinkGene>(); var selectedNeurons = new List<NEATNeuronGene>(); int curMom = 0; // current gene index from mom int curDad = 0; // current gene index from dad NEATLinkGene selectedGene = null; // add in the input and bias, they should always be here int alwaysCount = ((NEATGenome)parents[0]).InputCount + ((NEATGenome)parents[0]).OutputCount + 1; for (int i = 0; i < alwaysCount; i++) { AddNeuronId(i, selectedNeurons, best, notBest); } while ((curMom < mom.NumGenes) || (curDad < dad.NumGenes)) { NEATLinkGene momGene = null; // the mom gene object NEATLinkGene dadGene = null; // the dad gene object long momInnovation = -1; long dadInnovation = -1; // grab the actual objects from mom and dad for the specified // indexes // if there are none, then null if (curMom < mom.NumGenes) { momGene = mom.LinksChromosome[curMom]; momInnovation = momGene.InnovationId; } if (curDad < dad.NumGenes) { dadGene = dad.LinksChromosome[curDad]; dadInnovation = dadGene.InnovationId; } // now select a gene for mom or dad. This gene is for the baby if ((momGene == null) && (dadGene != null)) { if (best == dad) { selectedGene = dadGene; } curDad++; } else if ((dadGene == null) && (momGene != null)) { if (best == mom) { selectedGene = momGene; } curMom++; } else if (momInnovation < dadInnovation) { if (best == mom) { selectedGene = momGene; } curMom++; } else if (dadInnovation < momInnovation) { if (best == dad) { selectedGene = dadGene; } curDad++; } else if (dadInnovation == momInnovation) { selectedGene = rnd.NextDouble() < 0.5f ? momGene : dadGene; curMom++; curDad++; } if (selectedGene != null) { if (selectedLinks.Count == 0) { selectedLinks.Add(selectedGene); } else { if (selectedLinks[selectedLinks.Count - 1] .InnovationId != selectedGene .InnovationId) { selectedLinks.Add(selectedGene); } } // Check if we already have the nodes referred to in // SelectedGene. // If not, they need to be added. AddNeuronId(selectedGene.FromNeuronId, selectedNeurons, best, notBest); AddNeuronId(selectedGene.ToNeuronId, selectedNeurons, best, notBest); } } // now create the required nodes. First sort them into order selectedNeurons.Sort(); // finally, create the genome var factory = (INEATGenomeFactory)_owner .Population.GenomeFactory; var babyGenome = factory.Factor(selectedNeurons, selectedLinks, mom.InputCount, mom.OutputCount); babyGenome.BirthGeneration = _owner.IterationNumber; babyGenome.Population = _owner.Population; babyGenome.SortGenes(); offspring[offspringIndex] = babyGenome; }
/// <summary> /// Choose a parent to favor. /// </summary> /// <param name="rnd">Random generator.</param> /// <param name="mom">The mother.</param> /// <param name="dad">The father</param> /// <returns></returns> private NEATGenome FavorParent(EncogRandom rnd, NEATGenome mom, NEATGenome dad) { // first determine who is more fit, the mother or the father? // see if mom and dad are the same fitness if (Math.Abs(mom.Score - dad.Score) < EncogFramework.DefaultDoubleEqual) { // are mom and dad the same fitness if (mom.NumGenes == dad.NumGenes) { // if mom and dad are the same fitness and have the same number // of genes, // then randomly pick mom or dad as the most fit. if (rnd.NextDouble() > 0.5) { return mom; } return dad; } // mom and dad are the same fitness, but different number of genes // favor the parent with fewer genes if (mom.NumGenes < dad.NumGenes) { return mom; } return dad; } // mom and dad have different scores, so choose the better score. // important to note, better score COULD BE the larger or smaller // score. if (_owner.SelectionComparer.Compare(mom, dad) < 0) { return mom; } return dad; }
/// <inheritdoc/> public override void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { NEATGenome target = ObtainGenome(parents, parentIndex, offspring, offspringIndex); double weightRange = ((NEATPopulation)Owner.Population).WeightRange; IList<NEATLinkGene> list = _linkSelection.SelectLinks(rnd, target); foreach (NEATLinkGene gene in list) { _weightMutation.MutateWeight(rnd, gene, weightRange); } }
/// <inheritdoc /> public void Randomize(EncogRandom rnd, IList<EPLValueType> desiredType, ProgramNode actual, double minValue, double maxValue) { if (_delRandomize != null) { _delRandomize(rnd, desiredType, actual, minValue, maxValue); } }
/// <summary> /// This method is called reflexivly as we iterate downward. Once we reach /// the desired point (when current level drops to zero), the operation is /// performed. /// </summary> /// <param name="rnd">A random number generator.</param> /// <param name="result">The parent node.</param> /// <param name="parentNode"></param> /// <param name="types">The desired node</param> /// <param name="globalIndex">The level holder.</param> private void FindNode(EncogRandom rnd, EncogProgram result, ProgramNode parentNode, IList<EPLValueType> types, int[] globalIndex) { if (globalIndex[0] == 0) { globalIndex[0]--; ProgramNode newInsert = Generator.CreateNode(rnd, result, _maxDepth, types); result.ReplaceNode(parentNode, newInsert); } else { globalIndex[0]--; for (int i = 0; i < parentNode.Template.ChildNodeCount; i++) { ProgramNode childNode = parentNode.GetChildNode(i); IList<EPLValueType> childTypes = parentNode.Template.Params[i].DetermineArgumentTypes(types); FindNode(rnd, result, childNode, childTypes, globalIndex); } } }
/// <inheritdoc/> public abstract void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex);
/// <summary> /// Create a new genome with the specified connection density. This /// constructor is typically used to create the initial population. /// </summary> /// <param name="rnd">Random number generator.</param> /// <param name="pop">The population.</param> /// <param name="inputCount">The input count.</param> /// <param name="outputCount">The output count.</param> /// <param name="connectionDensity">The connection density.</param> public NEATGenome(EncogRandom rnd, NEATPopulation pop, int inputCount, int outputCount, double connectionDensity) { AdjustedScore = 0; InputCount = inputCount; OutputCount = outputCount; // get the activation function IActivationFunction af = pop.ActivationFunctions.PickFirst(); // first bias int innovationId = 0; var biasGene = new NEATNeuronGene(NEATNeuronType.Bias, af, inputCount, innovationId++); _neuronsList.Add(biasGene); // then inputs for (var i = 0; i < inputCount; i++) { var gene = new NEATNeuronGene(NEATNeuronType.Input, af, i, innovationId++); _neuronsList.Add(gene); } // then outputs for (int i = 0; i < outputCount; i++) { var gene = new NEATNeuronGene(NEATNeuronType.Output, af, i + inputCount + 1, innovationId++); _neuronsList.Add(gene); } // and now links for (var i = 0; i < inputCount + 1; i++) { for (var j = 0; j < outputCount; j++) { // make sure we have at least one connection if (_linksList.Count < 1 || rnd.NextDouble() < connectionDensity) { long fromId = this._neuronsList[i].Id; long toId = this._neuronsList[inputCount + j + 1].Id; double w = RangeRandomizer.Randomize(rnd, -pop.WeightRange, pop.WeightRange); var gene = new NEATLinkGene(fromId, toId, true, innovationId++, w); _linksList.Add(gene); } } } }
/// <inheritdoc/> public void MutateWeight(EncogRandom rnd, NEATLinkGene linkGene, double weightRange) { double delta = rnd.NextGaussian() * _sigma; double w = linkGene.Weight + delta; w = NEATPopulation.ClampWeight(w, weightRange); linkGene.Weight = w; }
/// <summary> /// Called for each node in the progrmam. If this is a const node, then /// mutate it according to the frequency and sigma specified. /// </summary> /// <param name="rnd">Random number generator.</param> /// <param name="node">The node to mutate.</param> private void MutateNode(EncogRandom rnd, ProgramNode node) { if (node.Template == StandardExtensions.EXTENSION_CONST_SUPPORT) { if (rnd.NextDouble() < _frequency) { ExpressionValue v = node.Data[0]; if (v.IsFloat) { double adj = rnd.NextGaussian()*_sigma; node.Data[0] = new ExpressionValue(v.ToFloatValue() + adj); } } } foreach (ITreeNode n in node.ChildNodes) { var childNode = (ProgramNode) n; MutateNode(rnd, childNode); } }
/// <summary> /// Construct a random HyperNEAT genome. /// </summary> /// <param name="rnd">Random number generator.</param> /// <param name="pop">The target population.</param> /// <param name="inputCount">The input count.</param> /// <param name="outputCount">The output count.</param> /// <param name="connectionDensity">The connection densitoy, 1.0 for fully connected.</param> public HyperNEATGenome(EncogRandom rnd, NEATPopulation pop, int inputCount, int outputCount, double connectionDensity) : base(rnd, pop, inputCount, outputCount, connectionDensity) { }
/// <summary> /// This method is called reflexivly as we iterate downward. Once we reach /// the desired point (when current level drops to zero), the operation is /// performed. /// </summary> /// <param name="rnd">A random number generator.</param> /// <param name="parentNode">The parent node.</param> /// <param name="types">The desired node.</param> /// <param name="holder">The level holder.</param> private void FindNode(EncogRandom rnd, ProgramNode parentNode, IList<EPLValueType> types, LevelHolder holder) { if (holder.CurrentLevel == 0) { holder.DecreaseLevel(); holder.Types = types; holder.NodeFound = parentNode; } else { holder.DecreaseLevel(); for (int i = 0; i < parentNode.Template.ChildNodeCount; i++) { ProgramNode childNode = parentNode.GetChildNode(i); IList<EPLValueType> childTypes = parentNode.Template .Params[i].DetermineArgumentTypes(types); FindNode(rnd, childNode, childTypes, holder); } } }
/// <inheritdoc /> public override int DetermineMaxDepth(EncogRandom rnd) { int range = MaxDepth - _minDepth; return rnd.Next(range) + _minDepth; }
/// <inheritdoc/> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { IntegerArrayGenome mother = (IntegerArrayGenome)parents[parentIndex]; IntegerArrayGenome father = (IntegerArrayGenome)parents[parentIndex + 1]; IntegerArrayGenome offspring1 = (IntegerArrayGenome)this.owner.Population.GenomeFactory.Factor(); IntegerArrayGenome offspring2 = (IntegerArrayGenome)this.owner.Population.GenomeFactory.Factor(); offspring[offspringIndex] = offspring1; offspring[offspringIndex + 1] = offspring2; int geneLength = mother.Size; // the chromosome must be cut at two positions, determine them int cutpoint1 = (int)(rnd.Next(geneLength - this.cutLength)); int cutpoint2 = cutpoint1 + this.cutLength; // keep track of which genes have been taken in each of the two // offspring, defaults to false. HashSet<int> taken1 = new HashSet<int>(); HashSet<int> taken2 = new HashSet<int>(); // handle cut section for (int i = 0; i < geneLength; i++) { if (!((i < cutpoint1) || (i > cutpoint2))) { offspring1.Copy(father, i, i); offspring2.Copy(mother, i, i); taken1.Add(father.Data[i]); taken2.Add(mother.Data[i]); } } // handle outer sections for (int i = 0; i < geneLength; i++) { if ((i < cutpoint1) || (i > cutpoint2)) { offspring1.Data[i] = SpliceNoRepeat.GetNotTaken(mother, taken1); offspring2.Data[i] = SpliceNoRepeat.GetNotTaken(father, taken2); } } }
/// <summary> /// Select a random variable from the defined variables. /// </summary> /// <param name="rnd">A random number generator.</param> /// <param name="desiredTypes">The desired types that the variable can be.</param> /// <returns>The index of the defined variable, or -1 if unable to define.</returns> public int SelectRandomVariable(EncogRandom rnd, IList<EPLValueType> desiredTypes) { IList<VariableMapping> selectionSet = _context .FindVariablesByTypes(desiredTypes); if (selectionSet.Count == 0 && desiredTypes.Contains(EPLValueType.IntType)) { IList<EPLValueType> floatList = new List<EPLValueType>(); floatList.Add(EPLValueType.FloatingType); selectionSet = _context.FindVariablesByTypes(floatList); } if (selectionSet.Count == 0) { return -1; } VariableMapping selected = selectionSet[rnd.Next(selectionSet.Count)]; return Context.DefinedVariables.IndexOf(selected); }
/// <inheritdoc/> public IList<NEATLinkGene> SelectLinks(EncogRandom rnd, NEATGenome genome) { IList<NEATLinkGene> result = new List<NEATLinkGene>(); int cnt = Math.Min(_linkCount, genome.LinksChromosome.Count); while (result.Count < cnt) { int idx = rnd.Next(genome.LinksChromosome.Count); NEATLinkGene link = genome.LinksChromosome[idx]; if (!result.Contains(link)) { result.Add(link); } } return result; }