private TmpNode FindMaxGainNode(List <TmpNode> tmpNodes)
        {
            if (tmpNodes.Count == 0)
            {
                throw new Exception("Missing nodes.");
            }

            TmpNode newNode = new TmpNode {
                Gain = -1.0
            };

            foreach (var node in tmpNodes)
            {
                if (newNode.Gain < node.Gain)
                {
                    newNode = node;
                }
            }

            return(newNode);
        }
        private TreeNode GetRootNode(Data data, string parentName, TreeNode parent)
        {
            // Obliczanie entropii atrybutu decyzyjnego
            double decisionEntropy = CalculateEntropy(data.Rows.Select(node => node.Last()).Count(d => d.ToUpper().Equals("YES")), data.Rows.Count);

            int            decisionAttributeIndex = data.Rows.FirstOrDefault().Count - 1;
            List <TmpNode> nodeGains       = new List <TmpNode>();
            int            propertiesCount = data.Rows.FirstOrDefault().Count;

            for (int index = 0; index < propertiesCount - 1; index++)
            {
                List <TmpNode> attribute = GetListOfAttributesEntropies(data, decisionAttributeIndex, index);

                nodeGains.Add(new TmpNode
                {
                    Index = index,
                    Nodes = attribute,
                    // Obliczanie przyrostu informacji
                    Gain = CalculateGain(decisionEntropy, attribute, data)
                });
            }

            TmpNode       newNode         = FindMaxGainNode(nodeGains);
            List <string> attributesNames = new List <string>();

            foreach (var dataRow in data.Rows)
            {
                var found = attributesNames.Any(t => t.ToUpper().Equals(dataRow[newNode.Index].ToString().ToUpper()));

                if (!found)
                {
                    attributesNames.Add(dataRow[newNode.Index]);
                }
            }

            return(new TreeNode(false, parentName, data.Columns[newNode.Index], newNode.Index, attributesNames, parent));
        }