예제 #1
0
        /// <summary>
        /// Copies the state from this <see cref="TreeNode"/> to <paramref name="node"/>.
        /// </summary>
        /// <param name="node"><see cref="TreeNode"/> to which state is to be copied.</param>
        /// <param name="newTree"><see cref="TreeEntityBase"/> to which the <paramref name="node"/> should be assigned.</param>
        /// <param name="newParentNode"><see cref="TreeNode"/> to be assigned as the parent node of the <paramref name="node"/>.</param>
        /// <remarks>
        /// <para>
        /// The default implementation of this method is to copy the state of <see cref="TreeNode"/>
        /// to the <see cref="TreeNode"/> passed in.
        /// </para>
        /// <para>
        /// <b>Notes to inheritors:</b> When overriding this method, it is necessary to call the
        /// <b>CopyTo</b> method of the base class.  This method should be used in conjunction with
        /// the <see cref="TreeNode.Clone(TreeEntityBase, TreeNode)"/> method.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="node"/> is null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="newTree"/> is null.</exception>
        public virtual void CopyTo(TreeNode node, TreeEntityBase newTree, TreeNode?newParentNode)
        {
            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            if (newTree is null)
            {
                throw new ArgumentNullException(nameof(newTree));
            }

            for (int i = 0; i < this.childNodes.Count; i++)
            {
                TreeNode?child = childNodes[i];
                if (child != null)
                {
                    node.ChildNodes.Add(child.Clone(newTree, node));
                }
            }

            node.ParentNode = newParentNode;
            node.Tree       = newTree;
            node.Value      = this.nodeValue;
        }
        /// <summary>
        /// When overriden in a derived class, generates a crossover based on the parent entities.
        /// </summary>
        /// <param name="parents">The <see cref="GeneticEntity"/> objects to be operated upon.</param>
        /// <returns>
        /// Collection of the <see cref="GeneticEntity"/> objects resulting from the crossover.
        /// </returns>
        protected override IEnumerable <GeneticEntity> GenerateCrossover(IList <GeneticEntity> parents)
        {
            if (parents == null)
            {
                throw new ArgumentNullException(nameof(parents));
            }

            TreeEntityBase tree1 = (TreeEntityBase)parents[0];
            TreeEntityBase tree2 = (TreeEntityBase)parents[1];

            int crossoverLocation1 = RandomNumberService.Instance.GetRandomValue(tree1.GetSize());
            int crossoverLocation2 = RandomNumberService.Instance.GetRandomValue(tree2.GetSize());

            TreeNode swapNode1 = GetSwapNode(tree1, crossoverLocation1);
            TreeNode swapNode2 = GetSwapNode(tree2, crossoverLocation2);

            TreeHelper.Swap(swapNode1, swapNode2);

            List <GeneticEntity> geneticEntities = new List <GeneticEntity>
            {
                tree1,
                tree2
            };

            return(geneticEntities);
        }
예제 #3
0
        /// <summary>
        /// Replaces <paramref name="locationNode"/> by moving <paramref name="movingNode"/> with all of its children to the location of <paramref name="locationNode"/>.
        /// </summary>
        /// <param name="movingNode"><see cref="TreeNode"/> to be moved.</param>
        /// <param name="locationNodeTree"><see cref="TreeEntityBase"/> containing the <paramref name="locationNode"/>.</param>
        /// <param name="locationNode"><see cref="TreeNode"/> where <paramref name="movingNode"/> should be moved to.</param>
        /// <param name="locationParentNode"><see cref="TreeNode"/> of the parent of <paramref name="locationNode"/>.</param>
        public static void ReplaceNodeInTree(TreeNode movingNode, TreeEntityBase locationNodeTree, TreeNode locationNode, TreeNode?locationParentNode)
        {
            if (movingNode is null)
            {
                throw new ArgumentNullException(nameof(movingNode));
            }

            if (locationNodeTree is null)
            {
                throw new ArgumentNullException(nameof(locationNodeTree));
            }

            if (locationNode is null)
            {
                throw new ArgumentNullException(nameof(locationNode));
            }

            if (locationParentNode is null)
            {
                locationNodeTree.SetRootNode(movingNode);
            }
            else
            {
                int childIndex = locationParentNode.ChildNodes.IndexOf(locationNode);
                locationParentNode.ChildNodes.Remove(locationNode);
                locationParentNode.InsertChild(childIndex, movingNode);
            }
        }
예제 #4
0
        /// <summary>
        /// Returns an enumerable collection of <see cref="TreeNode"/> objects containing the nodes
        /// of the tree sorted in postfix order.
        /// </summary>
        /// <param name="treeEntity">The tree entity from which to get the nodes.</param>
        /// <returns>An enumerable collection of <see cref="TreeNode"/> objects containing the nodes
        /// of the tree sorted in prefix order.</returns>
        public static IEnumerable <TreeNode> GetPostfixTree(this TreeEntityBase treeEntity)
        {
            if (treeEntity is null)
            {
                throw new ArgumentNullException(nameof(treeEntity));
            }

            return(TreeEntityExtensions.GetPostfixTree(treeEntity.RootNode));
        }
예제 #5
0
        /// <summary>
        /// Returns the number of nodes contained in the tree.
        /// </summary>
        /// <returns>The number of nodes contained in the tree.</returns>
        public static int GetSize(this TreeEntityBase treeEntity)
        {
            if (treeEntity is null)
            {
                throw new ArgumentNullException(nameof(treeEntity));
            }

            return(TreeEntityExtensions.GetSubtreeSize(treeEntity.RootNode));
        }
예제 #6
0
        /// <summary>
        /// Returns a clone of this node.
        /// </summary>
        /// <param name="newTree"><see cref="TreeEntityBase"/> to which the cloned node should be assigned.</param>
        /// <param name="newParentNode"><see cref="TreeNode"/> to be assigned as the parent node of the cloned node.</param>
        /// <returns>A clone of this node.</returns>
        /// <remarks>
        /// <b>Notes to implementers:</b> When this method is overriden, it is suggested that the
        /// <see cref="TreeNode.CopyTo(TreeNode, TreeEntityBase, TreeNode)"/> method is also overriden.
        /// In that case, the suggested implementation of this method is the following:
        /// <code>
        /// <![CDATA[
        /// public override object Clone(TreeEntity newTree, TreeNode newParentNode)
        /// {
        ///     MyTreeNode node = new MyTreeNode();
        ///     this.CopyTo(node, newTree, newParentNode);
        ///     return node;
        /// }
        /// ]]>
        /// </code>
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="newTree"/> is null.</exception>
        public virtual TreeNode Clone(TreeEntityBase newTree, TreeNode?newParentNode)
        {
            if (newTree is null)
            {
                throw new ArgumentNullException(nameof(newTree));
            }

            TreeNode node = new TreeNode();

            this.CopyTo(node, newTree, newParentNode);
            return(node);
        }
예제 #7
0
        /// <summary>
        /// Copies the state from this object> to <paramref name="entity"/>.
        /// </summary>
        /// <param name="entity"><see cref="GeneticEntity"/> to which state is to be copied.</param>
        /// <exception cref="ArgumentNullException"><paramref name="entity"/> is null.</exception>
        public override void CopyTo(GeneticEntity entity)
        {
            if (entity is null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            TreeEntityBase treeEntity = (TreeEntityBase)entity;

            treeEntity.rootNode = this.rootNode?.Clone(treeEntity, null);

            base.CopyTo(entity);
        }
 /// <summary>
 /// Returns the node at the specified prefix position.
 /// </summary>
 private static TreeNode GetSwapNode(TreeEntityBase tree, int nodePosition)
 {
     Debug.Assert(nodePosition < tree.GetSize(), "nodePosition must be less than the size of the tree.");
     return(tree.GetPrefixTree().Where((node, index) => index == nodePosition).FirstOrDefault());
 }