/// <summary> /// Choose a random node from the tree. Uses reservoir sampling. /// </summary> /// <param name="rnd">Random number generator.</param> /// <param name="root">The root of the tree.</param> /// <returns>A random node.</returns> public RandomNodeResult SampleRandomNode(IGenerateRandom rnd, TreeGenomeNode root) { var index = new int[1]; var reservoir = new RandomNodeResult(); index[0] = 0; InternalSampleRandomNode(rnd, null, root, index, reservoir); return(reservoir); }
/// <summary> /// /// </summary> /// <param name="rnd"></param> /// <param name="parent"></param> /// <param name="current"></param> /// <param name="index"></param> /// <param name="reservoir"></param> private void InternalSampleRandomNode(IGenerateRandom rnd, TreeGenomeNode parent, TreeGenomeNode current, int[] index, RandomNodeResult reservoir) { int currentIndex = index[0]; index[0]++; // determine if we replace the reservoir int j = rnd.NextInt(0, currentIndex + 1); if (j == 0) { reservoir.Parent = parent; reservoir.Child = current; } // traverse on to the children foreach (TreeGenomeNode child in current.Children) { InternalSampleRandomNode(rnd, current, child, index, reservoir); } }
/// <inheritdoc /> public void PerformOperation(IGenerateRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { var parent1 = (TreeGenome)parents[parentIndex]; EvaluateTree eval = parent1.Evaluator; var off1 = (TreeGenome)_owner.Population.GenomeFactory.Factor(parent1); RandomNodeResult off1Point = eval.SampleRandomNode(rnd, off1.Root); int len = rnd.NextInt(1, _maxGraftLength + 1); TreeGenomeNode randomSequence = eval.Grow(rnd, len); if (off1Point.Parent == null) { off1.Root = randomSequence; } else { int idx = off1Point.Parent.Children.IndexOf(off1Point.Child); off1Point.Parent.Children[idx] = randomSequence; } offspring[0] = off1; }
/// <summary> /// Choose a random node from the tree. Uses reservoir sampling. /// </summary> /// <param name="rnd">Random number generator.</param> /// <param name="root">The root of the tree.</param> /// <returns>A random node.</returns> public RandomNodeResult SampleRandomNode(IGenerateRandom rnd, TreeGenomeNode root) { var index = new int[1]; var reservoir = new RandomNodeResult(); index[0] = 0; InternalSampleRandomNode(rnd, null, root, index, reservoir); return reservoir; }