public void BasicTest()
        {
            RandomGenerator.GetInstance().RandomSource =
                new MockRandomSource(new List<int>(), new List<double> {0.350, 0.623, 0.311, 0.511, 0.999});

            ListGenotype<FloatGene> genotype1 =
                new ListGenotype<FloatGene>(10000);
            ListGenotype<FloatGene> genotype2 =
                new ListGenotype<FloatGene>(20000);
            ListGenotype<FloatGene> genotype3 =
                new ListGenotype<FloatGene>(30000);

            List<Individual<ListGenotype<FloatGene>, double>> individuals =
                new List<Individual<ListGenotype<FloatGene>, double>>
                {
                    new Individual<ListGenotype<FloatGene>, double>(genotype1, 300),
                    new Individual<ListGenotype<FloatGene>, double>(genotype2, 200),
                    new Individual<ListGenotype<FloatGene>, double>(genotype3, 500)
                };

            RouletteWheelSelector<ListGenotype<FloatGene>> selector =
                new RouletteWheelSelector<ListGenotype<FloatGene>>(5);

            IList<Individual<ListGenotype<FloatGene>, double>> selection = selector.Apply(individuals);

            Assert.AreEqual(5, selection.Count);
            Assert.AreSame(individuals[2], selection[0]);
            Assert.AreSame(individuals[0], selection[1]);
            Assert.AreSame(individuals[2], selection[2]);
            Assert.AreSame(individuals[0], selection[3]);
            Assert.AreSame(individuals[1], selection[4]);

            Assert.AreNotSame(individuals[0], selection[0]);
            Assert.AreNotSame(individuals[1], selection[0]);
        }
示例#2
0
        /**
         * This method finds a node using the logic given in the langdon paper.
         * @param nodeToSubtrees For Tree of Parent2 all precomputed stats about depth,subtrees etc
         * @param sizeToNodes Quick lookup for LinkedList of size to Nodes
         * @param parent1SelectedNode Node selected in parent1
         * @param Tree2 Tree of parent2
         * @param state Evolution State passed for getting access to Random Object of MersenneTwiser
         * @param thread thread number
         */
        protected GPNode FindFairSizeNode(ArrayList nodeToSubtrees,
                                          Hashtable sizeToNodes,
                                          GPNode parent1SelectedNode,
                                          GPTree tree2,
                                          IEvolutionState state,
                                          int thread)
        {
            GPNode selectedNode = null;
            // get the size of subtrees of parent1
            int parent1SubTrees = parent1SelectedNode.NumNodes(GPNode.NODESEARCH_NONTERMINALS);
            // the maximum length in mate we are looking for
            int maxmatesublen = parent1SubTrees == 0 ? 0 : 2 * parent1SubTrees + 1;

            // lets see if for all lengths we have trees corresponding
            bool[] mateSizeAvailable = new bool[maxmatesublen + 1];
            // initialize the array to false
            for (int i = 0; i < maxmatesublen; i++)
            {
                mateSizeAvailable[i] = false;
            }
            // check for ones we have
            for (int i = 0; i < nodeToSubtrees.Count; i++)
            {
                NodeInfo nodeInfo = (NodeInfo)nodeToSubtrees[i];
                // get the length of trees
                int subtree = nodeInfo.NumberOfSubTreesBeneath;
                if (subtree <= maxmatesublen)
                {
                    mateSizeAvailable[subtree] = true;
                }
            }
            // choose matesublen so mean size change=0 if possible
            int countOfPositives = 0;
            int countOfNegatives = 0;
            int sumOfPositives   = 0;
            int sumOfNegatives   = 0;
            int l;

            for (l = 1; l < parent1SubTrees; l++)
            {
                if (mateSizeAvailable[l])
                {
                    countOfNegatives++;
                    sumOfNegatives += parent1SubTrees - l;
                }
            }
            for (l = parent1SubTrees + 1; l <= maxmatesublen; l++)
            {
                if (mateSizeAvailable[l])
                {
                    countOfPositives++;
                    sumOfPositives += l - parent1SubTrees;
                }
            }
            // if they are missing use the same
            int mateSublengthSelected = 0;

            if (sumOfPositives == 0 || sumOfNegatives == 0)
            {
                //if so then check if mate has the length and use that
                if (mateSizeAvailable[parent1SubTrees])
                {
                    mateSublengthSelected = parent1SubTrees;
                }
                //else we go with zero
            }
            else
            {
                // probability of same is dependent on do we find same sub trees
                // else 0.0
                double pzero = (mateSizeAvailable[parent1SubTrees]) ? 1.0 / parent1SubTrees : 0.0;
                // positive probability
                double ppositive = (1.0 - pzero) /
                                   (countOfPositives +
                                    ((double)(countOfNegatives * sumOfPositives) / (sumOfNegatives)));
                // negative probability
                double pnegative = (1.0 - pzero) /
                                   (countOfNegatives +
                                    ((double)(countOfPositives * sumOfNegatives) / (sumOfPositives)));
                // total probability, just for making sure math is right ;-)
                double total = countOfNegatives * pnegative + pzero + countOfPositives * ppositive;
                // putting an assert for floating point calculations, similar to what langdon does
                // assert(total<1.01&&total>.99);
                // now create a Roulette Wheel
                RouletteWheelSelector wheel = new RouletteWheelSelector(maxmatesublen);
                // add probabilities to the wheel
                // all below the length of parent node get pnegative
                // all above get ppositive and one on node gets pzero
                for (l = 1; l < parent1SubTrees; l++)
                {
                    if (mateSizeAvailable[l])
                    {
                        wheel.Add(pnegative, l);
                    }
                }
                if (mateSizeAvailable[parent1SubTrees])
                {
                    wheel.Add(pzero, parent1SubTrees);
                }
                for (l = parent1SubTrees + 1; l <= maxmatesublen; l++)
                {
                    if (mateSizeAvailable[l])
                    {
                        wheel.Add(ppositive, l);
                    }
                }
                // spin the wheel
                mateSublengthSelected = wheel.Roulette(state, thread);
            }
            // now we have length chosen, but there can be many nodes with that
            //
            LinkedList <NodeInfo> listOfNodes = (LinkedList <NodeInfo>)sizeToNodes[mateSublengthSelected];

            if (listOfNodes == null)
            {
                state.Output.Fatal("In SizeFairCrossoverPipeline, nodes for tree length " + mateSublengthSelected + " is null, indicates some serious error");
            }
            // in size fair we choose the elements at random for given length
            int chosenNode = 0;

            // if using fair size get random from the list
            if (!Homologous)
            {
                chosenNode = state.Random[thread].NextInt(listOfNodes.Count);
            }
            // if Homologous
            else
            {
                if (listOfNodes.Count > 1)
                {
                    GPInitializer initializer        = ((GPInitializer)state.Initializer);
                    int           currentMinDistance = int.MaxValue;
                    for (int i = 0; i < listOfNodes.Count; i++)
                    {
                        // get the GP node
                        GPNode selectedMateNode = listOfNodes.ElementAt(i).Node;
                        // now lets traverse selected and parent 1 to see divergence
                        GPNode currentMateNode    = selectedMateNode;
                        GPNode currentParent1Node = parent1SelectedNode;
                        // found a match?
                        bool foundAMatchInAncestor = false;
                        int  distance = 0;
                        while (currentMateNode.Parent != null &&
                               currentMateNode.Parent is GPNode &&
                               currentParent1Node.Parent != null &&
                               currentParent1Node.Parent is GPNode &&
                               !foundAMatchInAncestor)
                        {
                            GPNode parent1 = (GPNode)currentParent1Node.Parent;
                            GPNode parent2 = (GPNode)currentMateNode.Parent;
                            // if there is match between compatibility of Parents break
                            if (parent1.SwapCompatibleWith(initializer, parent2))
                            {
                                foundAMatchInAncestor = true;
                                break;
                            }
                            else
                            {
                                // need to go one level above of both
                                currentMateNode    = parent2;
                                currentParent1Node = parent1;
                                //increment the distance
                                distance = distance + 1;
                            }
                        }
                        // find the one with least distance
                        if (distance < currentMinDistance)
                        {
                            currentMinDistance = distance;
                            chosenNode         = i;
                        }
                    }
                }
                // else take the first node, no choice
            }
            NodeInfo nodeInfoSelected = listOfNodes.ElementAt(chosenNode);

            selectedNode = nodeInfoSelected.Node;

            return(selectedNode);
        }