예제 #1
0
        /// <summary>
        /// Takes two parent individuals P0 and P1.
        /// Randomly choose a node i from the second parent, then test all possible crossover points from the first parent to determine the best location for i to be inserted.
        /// </summary>
        public static ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, IExecutionContext context,
                                                    ISymbolicDataAnalysisSingleObjectiveEvaluator <T> evaluator, T problemData, List <int> rows, int maxDepth, int maxLength)
        {
            // randomly choose a node from the second parent
            var possibleChildren = new List <ISymbolicExpressionTreeNode>();

            parent1.Root.ForEachNodePostfix((n) => {
                if (n.Parent != null && n.Parent != parent1.Root)
                {
                    possibleChildren.Add(n);
                }
            });

            var selectedChild   = possibleChildren.SampleRandom(random);
            var crossoverPoints = new List <CutPoint>();
            var qualities       = new List <Tuple <CutPoint, double> >();

            parent0.Root.ForEachNodePostfix((n) => {
                if (n.Parent != null && n.Parent != parent0.Root)
                {
                    var totalDepth  = parent0.Root.GetBranchLevel(n) + selectedChild.GetDepth();
                    var totalLength = parent0.Root.GetLength() - n.GetLength() + selectedChild.GetLength();
                    if (totalDepth <= maxDepth && totalLength <= maxLength)
                    {
                        var crossoverPoint = new CutPoint(n.Parent, n);
                        if (crossoverPoint.IsMatchingPointType(selectedChild))
                        {
                            crossoverPoints.Add(crossoverPoint);
                        }
                    }
                }
            });

            if (crossoverPoints.Any())
            {
                // this loop will perform two swap operations per each crossover point
                foreach (var crossoverPoint in crossoverPoints)
                {
                    // save the old parent so we can restore it later
                    var parent = selectedChild.Parent;
                    // perform a swap and check the quality of the solution
                    Swap(crossoverPoint, selectedChild);
                    IExecutionContext childContext = new ExecutionContext(context, evaluator, context.Scope);
                    double            quality      = evaluator.Evaluate(childContext, parent0, problemData, rows);
                    qualities.Add(new Tuple <CutPoint, double>(crossoverPoint, quality));
                    // restore the correct parent
                    selectedChild.Parent = parent;
                    // swap the replaced subtree back into the tree so that the structure is preserved
                    Swap(crossoverPoint, crossoverPoint.Child);
                }

                qualities.Sort((a, b) => a.Item2.CompareTo(b.Item2)); // assuming this sorts the list in ascending order
                var crossoverPoint0 = evaluator.Maximization ? qualities.Last().Item1 : qualities.First().Item1;
                // swap the node that would create the best offspring
                // this last swap makes a total of (2 * crossoverPoints.Count() + 1) swap operations.
                Swap(crossoverPoint0, selectedChild);
            }

            return(parent0);
        }
예제 #2
0
        /// <summary>
        /// Takes two parent individuals P0 and P1.
        /// Randomly choose a node i from the first parent, then test all nodes j from the second parent to determine the best child that would be obtained by swapping i for j.
        /// </summary>
        public static ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, IExecutionContext context,
                                                    ISymbolicDataAnalysisSingleObjectiveEvaluator <T> evaluator, T problemData, List <int> rows, int maxDepth, int maxLength)
        {
            var crossoverPoints0 = new List <CutPoint>();

            parent0.Root.ForEachNodePostfix((n) => {
                if (n.Parent != null && n.Parent != parent0.Root)
                {
                    crossoverPoints0.Add(new CutPoint(n.Parent, n));
                }
            });

            CutPoint crossoverPoint0 = crossoverPoints0.SampleRandom(random);
            int      level           = parent0.Root.GetBranchLevel(crossoverPoint0.Child);
            int      length          = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength();

            var allowedBranches = new List <ISymbolicExpressionTreeNode>();

            parent1.Root.ForEachNodePostfix((n) => {
                if (n.Parent != null && n.Parent != parent1.Root)
                {
                    if (n.GetDepth() + level <= maxDepth && n.GetLength() + length <= maxLength && crossoverPoint0.IsMatchingPointType(n))
                    {
                        allowedBranches.Add(n);
                    }
                }
            });

            if (allowedBranches.Count == 0)
            {
                return(parent0);
            }

            // create symbols in order to improvize an ad-hoc tree so that the child can be evaluated
            ISymbolicExpressionTreeNode selectedBranch = null;
            var nodeQualities = new List <Tuple <ISymbolicExpressionTreeNode, double> >();
            var originalChild = crossoverPoint0.Child;

            foreach (var node in allowedBranches)
            {
                var parent = node.Parent;
                Swap(crossoverPoint0, node); // the swap will set the nodes parent to crossoverPoint0.Parent
                IExecutionContext childContext = new ExecutionContext(context, evaluator, context.Scope);
                double            quality      = evaluator.Evaluate(childContext, parent0, problemData, rows);
                Swap(crossoverPoint0, originalChild); // swap the child back (so that the next swap will not affect the currently swapped node from parent1)
                nodeQualities.Add(new Tuple <ISymbolicExpressionTreeNode, double>(node, quality));
                node.Parent = parent;                 // restore correct parent
            }

            nodeQualities.Sort((a, b) => a.Item2.CompareTo(b.Item2));
            selectedBranch = evaluator.Maximization ? nodeQualities.Last().Item1 : nodeQualities.First().Item1;

            // swap the node that would create the best offspring
            Swap(crossoverPoint0, selectedBranch);
            return(parent0);
        }
예제 #3
0
        public override ISymbolicExpressionTree Crossover(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1)
        {
            if (this.ExecutionContext == null)
            {
                throw new InvalidOperationException("ExecutionContext not set.");
            }
            List <int> rows        = GenerateRowsToEvaluate().ToList();
            T          problemData = ProblemDataParameter.ActualValue;
            ISymbolicDataAnalysisSingleObjectiveEvaluator <T> evaluator = EvaluatorParameter.ActualValue;

            return(Cross(random, parent0, parent1, this.ExecutionContext, evaluator, problemData, rows, MaximumSymbolicExpressionTreeDepth.Value, MaximumSymbolicExpressionTreeLength.Value));
        }