/// <summary>
        /// Split the set according to a test.
        /// </summary>
        /// <param name="test"></param>
        /// <returns></returns>
        public override IEnumerable <ItemSet> Split(Test test)
        {
            WeightedItemSet[] sets = new WeightedItemSet[test.NumOfIssues];

            double[] setSizes = new double[test.NumOfIssues];

            double        setSizeSum          = 0.0d;
            List <Item>   unkonwnItems        = new List <Item>();
            List <double> unknownItemsWeights = new List <double>();

            for (int i = 0; i < sets.Length; i++)
            {
                sets[i] = new WeightedItemSet(this._attributeSet);
            }

            for (int i = 0; i < this._items.Count; i++)
            {
                Item           it     = this._items[i];
                double         weight = this._weights[i];
                AttributeValue val    = it.ValueOf(this._attributeSet, test.Attribute);

                if (val.IsUnknown())
                {
                    unkonwnItems.Add(it);
                    unknownItemsWeights.Add(weight);
                }
                else
                {
                    int id = test.Perform(val);
                    sets[id].Add(it, weight);
                }
            }

            for (int i = 0; i < sets.Length; i++)
            {
                setSizes[i] = sets[i].Size();
                setSizeSum += setSizes[i];
            }

            for (int i = 0; i < unkonwnItems.Count; i++)
            {
                Item   it     = unkonwnItems[i];
                double weight = unknownItemsWeights[i];

                for (int j = 0; j < sets.Length; j++)
                {
                    sets[j].Add(it, weight * setSizes[j] / setSizeSum);
                }
            }

            return(sets);
        }
        /// <summary>
        /// Returns the distribution of goal values. This distributionis represented by an array,
        /// its i-th element is proportional to the weight of the i-th goal value.
        /// The Sum of the elements of this array is equal to 1.
        /// </summary>
        /// <returns>An array describing the goal value distribution associated to this node.</returns>
        public override double[] GetGoalValueDistribution()
        {
            WeightedItemSet itemSet;
            DecisionTree    dt = base.Tree();

            if (dt == null || _learningSet == null)
            {
                return(null);
            }

            if (!(_learningSet is WeightedItemSet))
            {
                itemSet = new WeightedItemSet(_learningSet);
            }
            else
            {
                itemSet = (WeightedItemSet)_learningSet;
            }

            SymbolicAttribute goalAttr = dt.GoalAttribute;

            if (goalAttr == null)
            {
                return(null);
            }

            //Find the most frequent goal value in the items of the learning set
            double[] frequencies = new double[goalAttr.NumOfValues];

            for (int i = 0; i < itemSet.NumOfItems(); i++)
            {
                int id = ((KnownSymbolicValue)(itemSet.Items[i].ValueOf(itemSet.AttrSet.IndexOf(goalAttr)))).IntValue;
                frequencies[id] += itemSet.GetWeight(i);
            }

            for (int i = 0; i < frequencies.Length; i++)
            {
                frequencies[i] /= itemSet.Size();
            }

            return(frequencies);
        }