Пример #1
0
        public static void mutateOpportunistic(GeneticTree current)
        {
            NodeStatistics       stats         = current.allNodesStats(current._root, 0, "", 0);
            List <NodeStatsPair> opportunities = new List <NodeStatsPair>();

            foreach (var item in current._nodeStatsDictionary)
            {
                //Debug.WriteLine("Node " + item.Key + " /// Operator variance: " + item.Value._opVariance + " Variable variance: " + item.Value._varVariance + " Avg depth: " + item.Value._avgDepth + " Avg branching: " + item.Value._avgBranching);
                opportunities.Add(new NodeStatsPair(item.Key, item.Value._avgBranching + item.Value._avgDepth + item.Value._opVariance + item.Value._varVariance));
            }

            float max = opportunities.Max(x => x._mutationValue);

            foreach (var item in opportunities)
            {
                item._mutationValue = max - item._mutationValue + 1; // make less branchy, depthy and variant more likely to be mutated
            }
            opportunities = opportunities.OrderByDescending(x => x._mutationValue).ToList();


            float[] wSum = new float[opportunities.Count];

            wSum[0] = opportunities[0]._mutationValue;
            for (int i = 1; i < wSum.Length; i++)
            {
                wSum[i] = opportunities[i]._mutationValue + wSum[i - 1];
            }

            float sumF = opportunities.Sum(x => x._mutationValue);

            double centil = Rng.Rnd.NextDouble() * sumF;

            int index = 0;

            for (int i = 0; i < opportunities.Count && centil < wSum[i]; i++)
            {
                index = i;
            }

            string currentIndex = opportunities[index]._node;

            int         newDepth = (int)current._maxDepth - currentIndex.Length + 1;
            GeneticTree added    = new GeneticTree((uint)newDepth, current._maxBranching);

            GeneticNode tmp = current._root;

            for (int i = 1; i < currentIndex.Length; i++) // traversing to find proper index
            {
                index = GeneticTree._TREE_NODES_CHAR_TO_INT[currentIndex[i]];
                tmp   = tmp._children._children[index];
            }

            current.attachNode(added._root, currentIndex);

            current.recalculateIndices();
        }
Пример #2
0
        public NodeStatistics allNodesStats(GeneticNode current, int currentDepth, string previousTag, int childOrdinal)
        {
            string         currentTag = previousTag + _TREE_NODES_INT_TO_CHAR[childOrdinal];
            NodeStatistics ns         = new NodeStatistics();

            ns._totalCount++;
            ns._depth += currentDepth;
            switch (current)
            {
            case OperatorNode on:
                ns._totalOpCount++;
                ns._branching += (int)current._childNum;
                ns._opCount[(int)on._operatorType]++;
                for (int i = 0; i < on._childNum; i++)
                {
                    NodeStatistics res = allNodesStats(on._children[i], currentDepth + 1, currentTag, i);
                    ns._branching    += res._branching;
                    ns._depth        += res._depth;
                    ns._totalCount   += res._totalCount;
                    ns._totalOpCount += res._totalOpCount;
                    ns._opCount       = res._opCount.Zip(ns._opCount, (x, y) => x + y).ToArray();
                    ns._varCount      = res._varCount.Zip(ns._varCount, (x, y) => x + y).ToArray();
                }
                break;

            case VariableNode vn:
                ns._varCount[(int)vn._variableType]++;
                break;

            case MultipleNode mn:
                ns._totalOpCount++;
                ns._opCount[OPERATOR_NODES_NUM + MULTIPLE_NODES_NUM - 1]++;
                ns._branching += (int)current._childNum;
                for (int i = 0; i < mn._childNum; i++)
                {
                    NodeStatistics res = allNodesStats(mn._children[i], currentDepth + 1, currentTag, i);
                    ns._branching    += res._branching;
                    ns._totalCount   += res._totalCount;
                    ns._totalOpCount += res._totalOpCount;
                    ns._depth        += res._depth;
                    ns._opCount       = res._opCount.Zip(ns._opCount, (x, y) => x + y).ToArray();
                    ns._varCount      = res._varCount.Zip(ns._varCount, (x, y) => x + y).ToArray();
                }
                break;

            default:     // ConstNode
                ns._varCount[GeneticTree.VARIABLE_NODES_NUM + GeneticTree.CONST_NODES_NUM - 1]++;
                break;
            }
            if (currentDepth < _maxDepth)
            {
                if (ns._branching == 0 || ns._totalOpCount == 0)
                {
                    ns._avgBranching = 1;
                }
                else
                {
                    ns._avgBranching = ns._branching / (float)ns._totalOpCount;
                }
                ns._avgDepth  = (float)ns._depth / (float)ns._totalCount;
                ns._avgDepth -= currentDepth;

                double opAvg = ns._opCount.Average();
                double varAvg = ns._varCount.Average();
                double accOp = 0, accVar = 0;
                accOp           = ns._opCount.Aggregate(0.0, (acc, val) => (double)(acc + ((val - opAvg) * (val - opAvg))));
                accVar          = ns._varCount.Aggregate(0.0, (acc, val) => (double)(acc + ((val - varAvg) * (val - varAvg))));
                ns._opVariance  = (float)accOp / ns._opCount.Length;
                ns._varVariance = (float)accVar / ns._varCount.Length;

                _nodeStatsDictionary[currentTag] = ns;
            }
            return(ns);
        }