Exemplo n.º 1
0
        private void Mutate(MathExpressionTree expression)
        {
            MathExpressionNode randomNode = expression.GetRandomNode();

            randomNode.SubstiteValue(randomNode.IsLeaf ?
                                     stohasticGenerator.GetRandomOperand()
                                           : stohasticGenerator.GetRandomOperator(randomNode.LeftChild, randomNode.RightChild));
        }
Exemplo n.º 2
0
        public List <MathExpressionTree> Evolve(List <MathExpressionTree> selectedIndividuals)
        {
            List <(MathExpressionTree, MathExpressionTree)> pairs = selectedIndividuals.ParallelOrderBy(x => new Guid())
                                                                    .Take(selectedIndividuals.Count)
                                                                    .Select((individual, i) => new { index = i, individual })
                                                                    .GroupBy(x => x.index / 2, x => x.individual)
                                                                    .Select(g => (g.First(), g.Skip(1).FirstOrNew(populationSelector)))
                                                                    .ToList();
            List <MathExpressionTree> newPopulation = new List <MathExpressionTree>();

            ThreadSafeRandom crossoverRandom = new ThreadSafeRandom();
            ThreadSafeRandom mutationRandom  = new ThreadSafeRandom();

            foreach ((MathExpressionTree firstParent, MathExpressionTree secondParent) in pairs)
            {
                double randomProbability = crossoverRandom.NextDouble();
                if (randomProbability > crossoverProbability)
                {
                    MathExpressionTree firstCopy  = firstParent.Copy();
                    MathExpressionTree secondCopy = secondParent.Copy();
                    Crossover(firstCopy, secondCopy);
                    newPopulation.AddTwo(firstCopy, secondCopy);
                }
            }
            pairs.ForEach(x =>
            {
                newPopulation.AddTwo(x.Item1, x.Item2);
            });

            foreach (MathExpressionTree expression in newPopulation)
            {
                double randomProbability = mutationRandom.NextDouble();
                if (randomProbability < mutationProbability || !expression.IsValidExpression())
                {
                    Mutate(expression);
                }
            }

            List <MathExpressionTree> validExpressions = newPopulation.Where(x => x.IsValidExpression())
                                                         .Distinct(new MathExpressionTreeEqualityComparer())
                                                         .ToList();

            while (validExpressions.Count < populationSize)
            {
                validExpressions.Add(populationSelector.GenerateIndividual());
            }

            IEnumerable <MathExpressionTree> elite = validExpressions.ParallelOrderBy(x => populationSelector.CalculateFitness(x))
                                                     .Take(eliteCount);

            return(elite.Concat(validExpressions)
                   .Take(populationSize)
                   .ToList());
        }
Exemplo n.º 3
0
        public List <MathExpressionTree> GeneratePopulation(int initialPopulationSize)
        {
            BlockingCollection <MathExpressionTree> expressions = new BlockingCollection <MathExpressionTree>(initialPopulationSize);

            Parallel.For(0, initialPopulationSize, i =>
            {
                MathExpressionTree expression = GenerateIndividual();
                expressions.Add(expression);
            });
            return(expressions.ToList());
        }
        public async Task Execute(int populationSize, int lookup, int[] operands, int iterationCount = 100, int eliteCount = 1, double mutationProbability = 0.05, double crossover = 0.15)
        {
            GeneticAlgorithmConfiguration configuration = new GeneticAlgorithmConfiguration(lookup, mutationProbability, crossover, populationSize, eliteCount, iterationCount)
            {
                Operands = operands
            };
            CancellationTokenSource  cancellationTokenSource = new CancellationTokenSource();
            GeneticAlgorithmExecutor geneticAlgorithm        = new GeneticAlgorithmExecutor(configuration, cancellationTokenSource.Token, new SemaphoreSlim(1));
            MathExpressionTree       result = await geneticAlgorithm.Execute();

            Assert.IsNotNull(result, "Result is not found");
        }
Exemplo n.º 5
0
        private void Crossover(MathExpressionTree first, MathExpressionTree second)
        {
            MathExpressionNode crossoverPointOfFirst  = first.GetRandomSubtree();
            MathExpressionNode crossoverPointOfSecond = second.GetRandomSubtree();
            MathExpressionNode firstParent            = crossoverPointOfFirst.Parent;
            MathExpressionNode secondParent           = crossoverPointOfSecond.Parent;

            if (firstParent != null)
            {
                if (firstParent.LeftChild.Id == crossoverPointOfFirst.Id)
                {
                    firstParent.LeftChild = crossoverPointOfSecond;
                }
                else
                {
                    firstParent.RightChild = crossoverPointOfSecond;
                }
            }
            else
            {
                first.Root = crossoverPointOfSecond;
            }
            if (secondParent != null)
            {
                if (secondParent.LeftChild.Id == crossoverPointOfSecond.Id)
                {
                    secondParent.LeftChild = crossoverPointOfFirst;
                }
                else
                {
                    secondParent.RightChild = crossoverPointOfFirst;
                }
            }
            else
            {
                second.Root = crossoverPointOfFirst;
            }

            crossoverPointOfFirst.Parent  = secondParent;
            crossoverPointOfSecond.Parent = firstParent;
        }
Exemplo n.º 6
0
        public MathExpressionTree GenerateIndividual()
        {
            MathExpressionTree validExpression;

            do
            {
                int operandsCount = stohasticGenerator.OperandsCount();
                List <MathExpressionNode> operatorsAndOperands = Enumerable.Range(0, 2 * operandsCount - 1)
                                                                 .Select(x => x % 2 == 0 ? stohasticGenerator.GetRandomOperand() : stohasticGenerator.GetRandomOperator())
                                                                 .ToList();
                MathExpressionNode root = operatorsAndOperands.Where(x => !x.IsLeaf)
                                          .OrderBy(x => Guid.NewGuid())
                                          .First();

                MathExpressionNode getGenome(List <MathExpressionNode> elements, MathExpressionNode parent, MathExpressionNode rootNode = null)
                {
                    if (elements.Count == 0)
                    {
                        return(null);
                    }
                    MathExpressionNode currentNode = (rootNode ?? elements.FirstOrDefault(x => !x.IsLeaf)) ?? elements.First();

                    currentNode.Parent = parent;
                    if (!currentNode.IsLeaf)
                    {
                        int currentNodeIndex = elements.IndexOf(currentNode);
                        currentNode.LeftChild  = getGenome(elements.Take(currentNodeIndex).ToList(), currentNode);
                        currentNode.RightChild = getGenome(elements.Skip(currentNodeIndex + 1).ToList(), currentNode);
                    }
                    return(currentNode);
                }

                validExpression = new MathExpressionTree(getGenome(operatorsAndOperands, null, root));
            } while (!validExpression.IsValidExpression());
            return(validExpression);
        }
Exemplo n.º 7
0
 public static void AddTwo(this List <MathExpressionTree> list, MathExpressionTree first, MathExpressionTree second)
 {
     list.Add(first);
     list.Add(second);
 }
Exemplo n.º 8
0
 public int CalculateFitness(MathExpressionTree individual)
 => Math.Abs(result - individual.Root.GetValue());