예제 #1
0
        /// <summary>
        /// Computes the reached target leaves for the current tree.
        /// </summary>
        /// <param name="tree">
        /// The tree.
        /// </param>
        /// <param name="parentGenomes">
        /// The parent genomes.
        /// </param>
        /// <param name="indexSetsForCategoricalFeaturesInDoubleRepresentation">
        /// The index sets for categorical features in double representation.
        ///     (
        ///     <see cref="GeneticEngineering{TLearnerModel,TPredictorModel,TSamplingStrategy}.ComputeIndexSetsForCategoricalFeaturesInDoubleRepresentation"/>
        ///     ).
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{TreeNodeAndFixations}"/> that conatins all leaf nodes that an offspring of the
        ///     <paramref name="parentGenomes"/> can fall into.
        /// </returns>
        public static IEnumerable <TreeNodeAndFixations> ComputeReachableTargetLeavesForTree(
            GenomePredictionTree tree,
            ParentGenomesConverted parentGenomes,
            Dictionary <int, HashSet <int> > indexSetsForCategoricalFeaturesInDoubleRepresentation)
        {
            if (indexSetsForCategoricalFeaturesInDoubleRepresentation == null)
            {
                indexSetsForCategoricalFeaturesInDoubleRepresentation = new Dictionary <int, HashSet <int> >(0);
            }

            var queue = new List <TreeNodeAndFixations> {
                new TreeNodeAndFixations(tree.Root, null)
            };
            var head = 0;

            while (head < queue.Count)
            {
                var currentNodeAndFixations = queue[head++];
                var currentNode             = currentNodeAndFixations.CurrentNode;

                // check if we reached a leaf:
                if (currentNode.IsLeafNode())
                {
                    yield return(currentNodeAndFixations.CreateCopy());

                    continue;
                }

                var competitiveParentGoesLeft    = CheckIfParentGoesLeft(parentGenomes.CompetitiveParent, currentNode);
                var nonCompetitiveParentGoesLeft = CheckIfParentGoesLeft(parentGenomes.NonCompetitiveParent, currentNode);
                var parentsFollowSamePath        = competitiveParentGoesLeft == nonCompetitiveParentGoesLeft;

                // no need to fix features
                if (parentsFollowSamePath)
                {
                    var childNode            = tree.Nodes[competitiveParentGoesLeft ? currentNode.LeftIndex : currentNode.RightIndex];
                    var childNodeAndFixation = new TreeNodeAndFixations(childNode, currentNodeAndFixations.FixedIndicesInDoubleRepresentation);
                    queue.Add(childNodeAndFixation);
                    continue;
                }

                // we know that parents will take separate paths.
                AddTreeNodeAndFixationsIfParentCanContinue(
                    parentGenomes,
                    tree,
                    currentNodeAndFixations,
                    TargetLeafGenomeFixation.FixedToCompetitiveParent,
                    indexSetsForCategoricalFeaturesInDoubleRepresentation,
                    queue);
                AddTreeNodeAndFixationsIfParentCanContinue(
                    parentGenomes,
                    tree,
                    currentNodeAndFixations,
                    TargetLeafGenomeFixation.FixedToNonCompetitiveParent,
                    indexSetsForCategoricalFeaturesInDoubleRepresentation,
                    queue);
            }
        }
예제 #2
0
        /// <summary>
        /// Checks if the given <paramref name="parentToCheck"/> can follow the current tree path.
        /// </summary>
        /// <param name="parents">
        /// The converted parent genomes.
        /// </param>
        /// <param name="tree">
        /// The tree.
        /// </param>
        /// <param name="currentNodeAndFixations">
        /// The current node and feature fixations.
        /// </param>
        /// <param name="parentToCheck">
        /// The parent to check.
        /// </param>
        /// <param name="indexSetsForCategoricalFeaturesInDoubleRepresentation">
        /// The index sets for categorical features in double representation.
        /// </param>
        /// <param name="queue">
        /// The queue of open nodes to traverse.
        ///     If the <paramref name="parentToCheck"/> can continue (i.e. the current node's feature is not fixed to the 'other'
        ///     parent),
        ///     the child node that is visited by <paramref name="parentToCheck"/> will be added (and fixed to the
        ///     <paramref name="parentToCheck"/>).
        /// </param>
        private static void AddTreeNodeAndFixationsIfParentCanContinue(
            ParentGenomesConverted parents,
            GenomePredictionTree tree,
            TreeNodeAndFixations currentNodeAndFixations,
            TargetLeafGenomeFixation parentToCheck,
            Dictionary <int, HashSet <int> > indexSetsForCategoricalFeaturesInDoubleRepresentation,
            List <TreeNodeAndFixations> queue)
        {
            var canParentToCheckContinue = CheckIfGenomeCanContinueAlone(currentNodeAndFixations, parentToCheck);

            if (!canParentToCheckContinue)
            {
                return;
            }

            var currentParent  = parents.GetParentToFollow(parentToCheck);
            var currentNode    = currentNodeAndFixations.CurrentNode;
            var parentGoesLeft = CheckIfParentGoesLeft(currentParent, currentNode);
            var nextNodeInPath = tree.Nodes[parentGoesLeft ? currentNode.LeftIndex : currentNode.RightIndex];
            var competitiveChildNodeAndFixation = new TreeNodeAndFixations(
                nextNodeInPath,
                currentNodeAndFixations.FixedIndicesInDoubleRepresentation);

            // now add fixation
            if (!indexSetsForCategoricalFeaturesInDoubleRepresentation.ContainsKey(currentNode.FeatureIndex))
            {
                competitiveChildNodeAndFixation.FixedIndicesInDoubleRepresentation[currentNode.FeatureIndex] = parentToCheck;
            }
            else
            {
                // fix all columns of a feature, when one of them is used for a split.
                var allFeatureIndices = indexSetsForCategoricalFeaturesInDoubleRepresentation[currentNode.FeatureIndex];

                foreach (var categoricalFeatureIndex in allFeatureIndices)
                {
                    competitiveChildNodeAndFixation.FixedIndicesInDoubleRepresentation[categoricalFeatureIndex] = parentToCheck;
                }
            }

            queue.Add(competitiveChildNodeAndFixation);
        }
예제 #3
0
        /// <summary>
        /// Checks if parent can continue alone.
        ///     I.e. the current node's split feature index is not fixed to the 'other' parent.
        /// </summary>
        /// <param name="currentNodeAndFixations">
        /// The current node and fixations.
        /// </param>
        /// <param name="parentToCheck">
        /// The parent to check.
        /// </param>
        /// <returns>
        /// <c>True</c>, iff the current node's split feature index is not fixed to the 'other' parent.
        /// </returns>
        private static bool CheckIfGenomeCanContinueAlone(TreeNodeAndFixations currentNodeAndFixations, TargetLeafGenomeFixation parentToCheck)
        {
            var currentFeatureIndex = currentNodeAndFixations.CurrentNode.FeatureIndex;

            return(!IsFixedToDifferentGenome(currentFeatureIndex, parentToCheck, currentNodeAndFixations.FixedIndicesInDoubleRepresentation));
        }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TreeNodeAndFixations"/> class.
 /// Simple copy constructor.
 /// </summary>
 /// <param name="source">
 /// The source to copy from.
 /// Must not be null.
 /// </param>
 private TreeNodeAndFixations(TreeNodeAndFixations source)
     : this(source.CurrentNode, source.FixedIndicesInDoubleRepresentation)
 {
 }