예제 #1
0
 /// <summary>
 /// Initializes a new instance of the class.
 /// </summary>
 /// <param name="randomSeed">The random seed.</param>
 /// <param name="maximumIterations">The maximum number of iterations.</param>
 /// <param name="maximumIterationsWithoutImprovement">The maximum number of iterations without improvement.</param>
 /// <param name="maximumRunningTime">The maximum number of seconds.</param>
 /// <param name="maximumPathLength">The maximum path length.</param>
 /// <param name="populationSize">The population size.</param>
 /// <param name="randomGenesPerChromosome">The maximum number of genes whose value can be simultaneously randomly generated.</param>
 /// <param name="percentageRandom">The percentage of a population which is composed of randomly generated chromosomes.</param>
 /// <param name="percentageElite">The percentage of a population which is composed of the elite chromosomes of the previous population.</param>
 /// <param name="probabilityMutation">The probability of mutation for each gene of a chromosome.</param>
 /// <param name="crossoverType">The crossover algorithm to be used.</param>
 /// <param name="mutationType">The mutation algorithm to be used.</param>
 public Parameters(int randomSeed, int maximumIterations, int maximumIterationsWithoutImprovement, int maximumRunningTime, int maximumPathLength, int populationSize, int randomGenesPerChromosome, double percentageRandom, double percentageElite, double probabilityMutation, AnalysisCrossoverType crossoverType, AnalysisMutationType mutationType)
 {
     // Assign the value for each parameter.
     RandomSeed        = randomSeed;
     MaximumIterations = maximumIterations;
     MaximumIterationsWithoutImprovement = maximumIterationsWithoutImprovement;
     MaximumRunningTime       = maximumRunningTime;
     MaximumPathLength        = maximumPathLength;
     PopulationSize           = populationSize;
     RandomGenesPerChromosome = randomGenesPerChromosome;
     PercentageRandom         = percentageRandom;
     PercentageElite          = percentageElite;
     ProbabilityMutation      = probabilityMutation;
     CrossoverType            = crossoverType;
     MutationType             = mutationType;
 }
예제 #2
0
        /// <summary>
        /// Creates a new offspring chromosome from this and a second chromosome parents.
        /// </summary>
        /// <param name="secondChromosome">The second parent chromosome of the offspring.</param>
        /// <param name="nodeIndex">The dictionary containing, for each node, its index in the node list.</param>
        /// <param name="powersMatrixCA">The list containing the different powers of the matrix (CA, CA^2, CA^3, ... ).</param>
        /// <param name="nodeIsPreferred">The dictionary containing, for each node, if it is in the preferred node list.</param>
        /// <param name="crossoverType">The crossover type for the algorithm.</param>
        /// <param name="random">The random seed.</param>
        /// <returns>A new offspring chromosome from this and a second chromosome parents.</returns>
        public Chromosome Crossover(Chromosome secondChromosome, Dictionary <string, int> nodeIndex, List <Matrix <double> > powersMatrixCA, Dictionary <string, bool> nodeIsPreferred, AnalysisCrossoverType crossoverType, Random random)
        {
            // Define a new chromosome.
            var chromosome = new Chromosome(Genes.Keys.ToList());
            // Define the number of tries in which to try and find a valid chromosome.
            var tries = _tries;
            // Get the number of occurances of each gene in this chromosome and which genes of each are preferred.
            var occurrences = GetUniqueInputNodes()
                              .Concat(secondChromosome.GetUniqueInputNodes())
                              .Distinct()
                              .ToDictionary(item => item, item => Genes.Count(item1 => item1.Value == item) + secondChromosome.Genes.Count(item1 => item1.Value == item));

            // Use the specified crossover type.
            switch (crossoverType)
            {
            // If we have a standard crossover.
            case AnalysisCrossoverType.WeightedRandom:
                // Repeat while the chromosome is not valid.
                while (tries > 0)
                {
                    // Decrease the number of tries.
                    tries--;
                    // Go over each of the target nodes.
                    foreach (var item in chromosome.Genes.Keys.ToList())
                    {
                        // Get the number of occurances in each chromosome.
                        var inFirst  = occurrences[Genes[item]];
                        var inSecond = occurrences[secondChromosome.Genes[item]];
                        // Assign to the gene in the chromosome its corresponding random parent value with the a probability depending on the occurances.
                        chromosome.Genes[item] = random.NextDouble() < (double)inFirst / (double)(inFirst + inSecond) ? Genes[item] : secondChromosome.Genes[item];
                    }
                    // Check if the chromosome is valid.
                    if (chromosome.IsValid(nodeIndex, powersMatrixCA))
                    {
                        // Exit the loop.
                        break;
                    }
                }
                // End the switch statement.
                break;

            // If we have a standard crossover with preference.
            case AnalysisCrossoverType.WeightedRandomPreferred:
                // Repeat while the chromosome is not valid.
                while (tries > 0)
                {
                    // Decrease the number of tries.
                    tries--;
                    // Go over each of the target nodes.
                    foreach (var item in chromosome.Genes.Keys.ToList())
                    {
                        // Get the number of occurances in each chromosome.
                        var inFirst  = occurrences[Genes[item]];
                        var inSecond = occurrences[secondChromosome.Genes[item]];
                        // Check if the gene in any of the chromosomes is a preferred node.
                        var isPreferredFirst  = nodeIsPreferred[Genes[item]];
                        var isPreferredSecond = nodeIsPreferred[secondChromosome.Genes[item]];
                        // Check if the first corresponding gene is preferred, and the second one isn't.
                        if (isPreferredFirst && !isPreferredSecond)
                        {
                            // Choose one of the parent genes with a probability depending on their occurances, the preferred node being two times more likely to be selected.
                            chromosome.Genes[item] = random.NextDouble() < (double)inFirst * 2 / (double)(inFirst * 2 + inSecond) ? Genes[item] : secondChromosome.Genes[item];
                        }
                        // Check if the second corresponding gene is preferred, and the first one isn't.
                        else if (!isPreferredFirst && isPreferredSecond)
                        {
                            // Choose one of the parent genes with a probability depending on their occurances, the preferred node being two times more likely to be selected.
                            chromosome.Genes[item] = random.NextDouble() < (double)inSecond * 2 / (double)(inFirst + inSecond * 2) ? secondChromosome.Genes[item] : Genes[item];
                        }
                        // Otherwise they both have the same state.
                        else
                        {
                            // Choose one of the parent genes with a probability depending on their occurances.
                            chromosome.Genes[item] = random.NextDouble() < (double)inFirst / (double)(inFirst + inSecond) ? Genes[item] : secondChromosome.Genes[item];
                        }
                    }
                    // Check if the chromosome is valid.
                    if (chromosome.IsValid(nodeIndex, powersMatrixCA))
                    {
                        // Exit the loop.
                        break;
                    }
                }
                // End the switch statement.
                break;

            // If we have a default crossover.
            case AnalysisCrossoverType.Dominant:
                // Repeat while the chromosome is not valid.
                while (tries > 0)
                {
                    // Decrease the number of tries.
                    tries--;
                    // Go over each of the target nodes.
                    foreach (var item in chromosome.Genes.Keys.ToList())
                    {
                        // Get the number of occurances in each chromosome.
                        var inFirst  = occurrences[Genes[item]];
                        var inSecond = occurrences[secondChromosome.Genes[item]];
                        // Assign to the gene in the chromosome its corresponding random parent value with the a probability depending on the occurances.
                        chromosome.Genes[item] = inSecond < inFirst ? Genes[item] : inFirst < inSecond ? secondChromosome.Genes[item] : random.NextDouble() < 0.5 ? Genes[item] : secondChromosome.Genes[item];
                    }
                    // Check if the chromosome is valid.
                    if (chromosome.IsValid(nodeIndex, powersMatrixCA))
                    {
                        // Exit the loop.
                        break;
                    }
                }
                // End the switch statement.
                break;

            // If we have a default crossover with preference.
            case AnalysisCrossoverType.DominantPreferred:
                // Repeat while the chromosome is not valid.
                while (tries > 0)
                {
                    // Decrease the number of tries.
                    tries--;
                    // Go over each of the target nodes.
                    foreach (var item in chromosome.Genes.Keys.ToList())
                    {
                        // Check if the gene in any of the chromosomes is a preferred node.
                        var isPreferredFirst  = nodeIsPreferred[Genes[item]];
                        var isPreferredSecond = nodeIsPreferred[secondChromosome.Genes[item]];
                        // Check if the first corresponding gene is preferred, and the second one isn't.
                        if (isPreferredFirst && !isPreferredSecond)
                        {
                            // Choose the preferred node.
                            chromosome.Genes[item] = Genes[item];
                        }
                        // Check if the second corresponding gene is preferred, and the first one isn't.
                        else if (!isPreferredFirst && isPreferredSecond)
                        {
                            // Choose the preferred node.
                            chromosome.Genes[item] = secondChromosome.Genes[item];
                        }
                        // Otherwise they both have the same state.
                        else
                        {
                            // Get the number of occurances in each chromosome.
                            var inFirst  = occurrences[Genes[item]];
                            var inSecond = occurrences[secondChromosome.Genes[item]];
                            // Choose one of the parent genes with a probability depending on their occurances.
                            chromosome.Genes[item] = inSecond < inFirst ? Genes[item] : inFirst < inSecond ? secondChromosome.Genes[item] : random.NextDouble() < 0.5 ? Genes[item] : secondChromosome.Genes[item];
                        }
                    }
                    // Check if the chromosome is valid.
                    if (chromosome.IsValid(nodeIndex, powersMatrixCA))
                    {
                        // Exit the loop.
                        break;
                    }
                }
                // End the switch statement.
                break;

            // If we have none of the above.
            default:
                // Set the tries to 0, such that the new chromosome will inherit completely one of the parents.
                tries = 0;
                // End the switch statement.
                break;
            }
            // Check if the new chromosome is still not valid.
            if (tries == 0)
            {
                // Choose randomly a parent to give all of its genes.
                chromosome.Genes = random.NextDouble() < 0.5 ? new Dictionary <string, string>(Genes) : new Dictionary <string, string>(secondChromosome.Genes);
            }
            // Return the new chromosome.
            return(chromosome);
        }