Example #1
0
        /// <summary>
        /// Добавляет организм в популяцию. Проверяет на валидность организм.
        /// </summary>
        /// <param name="organism">Организм</param>
        /// <param name="population">Популяция</param>
        private void AddToPopulation(Organism organism, List<Organism> population)
        {
            if (organism.GenesCount == 0)
                throw new ArgumentOutOfRangeException("organism");

            if (organism.Factors.Count == 0)
                throw new ArgumentOutOfRangeException("organism");

            population.Add(organism);
        }
Example #2
0
        private AnalyzablePage Solution(Organism organism)
        {
            try
            {
                var triggerValue = organism.Factors[0].Value;
                var minHeight = organism.Factors[1].Value;
                var height = _hystogram.GetLength(0);
                var page = new AnalyzablePage(height,_width);

                int start = 0;

                var isLine = false;

                for (var y = 0; y < height; y++)
                {
                    var trigger = (_hystogram[y] > triggerValue);

                    if (trigger)
                    {
                        if (!isLine)
                        {
                            start = y;
                            isLine = true;
                        }
                    }
                    else
                    {
                        if (isLine)
                        {
                            int end = y;
                            var lineHeight = end - start + 1;
                            if (lineHeight > minHeight)
                                page.AddLine(new AnalyzableLine(start, lineHeight));
                            isLine = false;
                        }

                    }
                }

                return page;

            }
            catch (Exception e)
            {
                throw new Exception("Cant generate solution",e);
            }
        }
Example #3
0
        /// <summary>
        /// Находит решение
        /// </summary>
        protected void Solve()
        {
            var iterations = 0;
            var globalMaximumIterations = 0;
            double maxFitness = 0;
            double globalMaximum = 0.0;
            _population = GenerateInitialPopulation();
            var fitnessLog = new List<double>();
            fitnessLog.Add(0);

            try
            {
                while (true)
                {
                    if (maxFitness > globalMaximum)
                    {
                        globalMaximum = maxFitness;
                        globalMaximumIterations = 0;
                    }
                    else
                        globalMaximumIterations++;

                    fitnessLog.Add(maxFitness);
                    GenerateFitnesses();
                    GenerateLikalihoods();
                    BestOrganism =
                        (from organism in _population orderby organism.Fitness descending select organism).ToList()[0];
                    maxFitness = BestOrganism.Fitness;

                    var solved = ((globalMaximumIterations < GeneticConfiguration.MaximumIterations*(1 - globalMaximum)) ||
                                  !(Math.Abs(maxFitness - globalMaximum) < 0.01)) &&
                                 (iterations < GeneticConfiguration.MaximumIterations);

                    if (solved)
                        break;

                    _population = NewPopulation();
                    iterations++;
                }
            }
            catch (Exception e)
            {
                throw new Exception("Cant solve",e);
            }
        }
Example #4
0
        protected override double Fitness(Organism organism)
        {
            try
            {
                AnalyzablePage segmentation = Solution(organism);
                int heightsRange = segmentation.HeightRange();
                int distanceRange = segmentation.DistanceRange();
                //double densityRange = segmentation.DensityRange();
                var summ = (segmentation.Lines.Count > 2) ? segmentation.Lines.Sum(line => line.Height) : 0;
                double fitness = 1 /
                                 ((double)(1 + heightsRange) * (1 + distanceRange)*(1+Math.Abs(2*segmentation.Height - summ)));

                if (!((fitness >= 0) && (fitness <= 1)))
                    throw new ArgumentOutOfRangeException();

                return fitness;
            }
            catch (Exception e)
            {
                throw new Exception("Cant calculate fitness",e);
            }
        }
Example #5
0
        /// <summary>
        /// Скрещивание организмов
        /// </summary>
        /// <param name="alpha">Первая особь</param>
        /// <param name="beta">Вторая особь</param>
        /// <returns>Потомок</returns>
        private Organism Breed(Organism alpha, Organism beta)
        {
            try
            {
                if (alpha.GenesCount != beta.GenesCount)
                {
                    throw new ArgumentOutOfRangeException("alpha", @"Chromosome lengths must be same");
                }

                //С вероятностью 0.5 инициирующей особью будет A
                if (_random.NextDouble() <= 0.5)
                {
                    Organism t = alpha;
                    alpha = beta;
                    beta = t;
                }

                Organism offspring = Crossover(alpha, beta);

                MutateOrganism(offspring);

                return offspring;
            }
            catch (Exception e)
            {
                throw new Exception("Cant breed", e);
            }
        }
Example #6
0
        /// <summary>
        /// Мутирует каждый ген организма с определенной вероятностью
        /// </summary>
        /// <param name="organism">Организм для мутации</param>
        private void MutateOrganism(Organism organism)
        {
            double mutationRate = GeneticConfiguration.MutationRate;
            if ((mutationRate < 0) || (mutationRate > 1))
            {
                throw new ArgumentOutOfRangeException();
            }

            try
            {
                for (int index = 0; index < organism.GenesCount; index++)
                    if (_random.NextDouble() <= GeneticConfiguration.MutationRate)
                        organism.Alleles[index] = !organism.Alleles[index];
            }
            catch (Exception e)
            {
                throw new Exception("Cant mutate organism", e);
            }
        }
Example #7
0
        /// <summary>
        /// Генерирует организм с факторами, содержащими случайные 
        /// </summary>
        /// <returns></returns>
        private Organism GenerateRandomOrganism()
        {
            try
            {
                var organism = new Organism();
                foreach (
                    var factor in
                        GeneticConfiguration.FactorConfigs.Select(GenerateRandomFactor))
                {
                    organism.AddFactorAndCode(factor);
                }

                return organism;
            }
            catch (Exception e)
            {
                throw new Exception("Cant generate random organism", e);
            }
        }
Example #8
0
 protected abstract double Fitness(Organism organism);
Example #9
0
        /// <summary>
        /// Выполняет операцию кроссовера к генам двух особей
        /// </summary>
        /// <param name="alpha">Инициирующий</param>
        /// <param name="beta">Инициируемый</param>
        /// <returns>Потомок</returns>
        private Organism Crossover(Organism alpha, Organism beta)
        {
            try
            {
                if (alpha.GenesCount != beta.GenesCount)
                {
                    throw new ArgumentOutOfRangeException("alpha", @"Chromosome lengths must be different");
                }

                int length = alpha.GenesCount;

                var offspring = new Organism {Factors = alpha.Factors};

                //Сгенерируем точки кроссовера
                var crossoverPoints = new[] {_random.Next(length), _random.Next(length)};
                int crossoverStart = crossoverPoints.Min(); //Начало отрезка - меньшая точка
                int crossoverEnd = crossoverPoints.Max(); //Конец - большая

                //Получаем новую хромосому, заменяя гены инициируемого организма в [start; end] генами из инициирующего.
                // A {Ai..As..Ae..An} + B {Bi..Bs..Be..Bn} = Descendant {Bi..Bs-1,As..Ae,Be+1..Bn}
                for (int i = 0; i < length; i++)
                    if ((i >= crossoverStart) && (i <= crossoverEnd))
                        offspring.AddGene(alpha.GetGene(i));
                    else
                        offspring.AddGene(beta.GetGene(i));
                offspring.Factors = offspring.GenerateFactors();
                return offspring;
            }
            catch (Exception e)
            {
                throw new Exception("Cant crossover", e);
            }
        }
Example #10
0
        /// <summary>
        /// Скрещивает два организма с помощью взвешенного выбора
        /// </summary>
        /// <returns>Потомок</returns>
        private Organism CreateOffspring()
        {
            var alpha = new Organism();
            Organism beta = alpha;
            try
            {
                while (alpha == beta)
                {
                    alpha = Roullete();
                    beta = Roullete();
                }

                return Breed(alpha, beta);
            }
            catch (Exception e)
            {
                throw new Exception("Cant create offspring", e);
            }
        }
Example #11
0
 private void CalculateFitness(Organism organism)
 {
     try
     {
         var fitness = Fitness(organism);
         organism.Fitness = fitness;
     }
     catch (Exception e)
     {
         throw new Exception("Cant calculate fitness",e);
     }
 }
Example #12
0
 protected abstract double Fitness(Organism organism);