Ejemplo n.º 1
0
        public Population(int size, IFitnessFunction fitnessFunction, IReproduction reproductionFunction, INodeMutator mutator, ISelection selection)
        {
            this.populationSize = size;
            this.fitnessFunction = fitnessFunction;
            this.reproductionFunction = reproductionFunction;
            this.mutator = mutator;
            this.selector = selection;

            this.fitnessFunction.Initialise();

            // Create the initial population
            for (int i = 0; i < size; i++)
            {
                try
                {
                    NodeContext zeroContext = new NodeContext();
                    zeroContext.AvailableCollections = fitnessFunction.GetCollections();
                    zeroContext.AvailableInputs = fitnessFunction.GetInputs();

                    INode candidateNode = NodeFactory.GenerateNode(zeroContext);

                    // Make sure we have a decent candidate (i.e. not too large)
                    double fitness = this.fitnessFunction.CalculateFitness(candidateNode);
                    if (fitness == Double.MaxValue) continue;

                    this.population.Add(NodeFactory.GenerateNode(zeroContext));
                }
                catch (StackOverflowException)
                {
                }
            }
        }
Ejemplo n.º 2
0
 public object Clone()
 {
     NodeContext result = new NodeContext();
     result.DepthLevel = this.DepthLevel;
     result.AvailableCollections = new List<int>(this.AvailableCollections);
     result.AvailableInputs = new List<int>(this.AvailableInputs);
     return result;
 }
Ejemplo n.º 3
0
        public static INode GenerateNode(NodeContext context)
        {
            INode result = null;
            if (context.DepthLevel > 20)
            {
                result = new ConstantNode(context.GenerateNewLevel());
                return result;
            }

            int probability = 10;

            while (result == null)
            {
                if (RandomUtil.Random.Next(100) < probability)
                {
                    result = new AddNode(context.GenerateNewLevel());
                }
                else if (RandomUtil.Random.Next(100) < probability)
                {
                    result = new SubtractNode(context.GenerateNewLevel());
                }
                else if (RandomUtil.Random.Next(100) < probability)
                {
                    result = new MultiplyNode(context.GenerateNewLevel());
                }
                else if (RandomUtil.Random.Next(100) < probability)
                {
                    result = new DivideNode(context.GenerateNewLevel());
                }
                else if (RandomUtil.Random.Next(100) < probability)
                {
                    result = new InputSizeNode(context.GenerateNewLevel());
                }
                else if (RandomUtil.Random.Next(100) < probability)
                {
                    result = new CollectionSizeNode(context.GenerateNewLevel());
                }
                else if (RandomUtil.Random.Next(100) < probability && context.AvailableInputs.Count > 0)
                {
                    result = new InputVariableNode(context.GenerateNewLevel());
                }
                else if (RandomUtil.Random.Next(100) < probability && context.AvailableCollections.Count > 0)
                {
                    result = new SumNode(context.GenerateNewLevel());
                }
            }

            //NodeFactory.SimplifyNode(ref result);

            return result;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Generate a new population based on the fitness of the previous population's
        /// individuals
        /// </summary>
        public void ProcessGeneration()
        {
            NodeContext zeroContext = new NodeContext();
            zeroContext.AvailableCollections = fitnessFunction.GetCollections();
            zeroContext.AvailableInputs = fitnessFunction.GetInputs();

            // Create a new set of tests
            fitnessFunction.Initialise();

            Console.WriteLine("Calculate");

            // Get the fitness measure for each individual
            var fitnesses = new ThreadSafeDictionary<int, double>();
            for (int i = 0; i < this.population.Count; ++i)
            {
                fitnesses[i] = this.fitnessFunction.CalculateFitness(this.population[i]);
                fitnesses[i] = Math.Abs(fitnesses[i]);
            }

            //var loopResult = Parallel.For(0, this.population.Count, delegate(int i)
            //{
            //    fitnesses[i] = Math.Abs(this.fitnessFunction.CalculateFitness(this.population[i]));
            //    //fitnesses[i] = Math.Abs(fitnesses[i]);
            //});

            //if (!loopResult.IsCompleted)
            //{
            //    Console.WriteLine("Loop failed");
            //}

            this.selector.Initialise(this.population, fitnesses);

            var bestIndividuals = from k in fitnesses.Keys orderby fitnesses[k] ascending select this.population[k];

            INode best = bestIndividuals.FirstOrDefault();
            this.BestIndividual = best;

            // Update the best fitness
            this.BestFitness = fitnesses.Values.Min();
            this.AverageFitness = fitnesses.Values.Sum(f => f < Double.MaxValue ? f : 0)/fitnesses.Values.Count(f => f < Double.MaxValue);

            Console.WriteLine("Best fitness: {0} {1}", fitnesses.Values.Min(), best);

            this.PrintAverageTreeSize();

            List<INode> newPopulation = new List<INode>();

            // Always keep the best 10%
            newPopulation.AddRange(bestIndividuals.Take(this.populationSize / 10));

            while (newPopulation.Count < this.populationSize)
            {
                INode parentA = this.selector.SelectNode();
                INode parentB = this.selector.SelectNode();
                INode child = this.reproductionFunction.Reproduce(parentA, parentB);
                //INode child = (INode) this.selector.SelectNode().Clone();
                this.mutator.Mutate(ref child, zeroContext);
                newPopulation.Add(child);

            }

            // Replace the old population);
            this.population = newPopulation;
        }