/// <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); }
/// <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); } }
/// <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)); }
/// <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)); }
/// <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); }
/// <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()); }