// <summary>
        /// Parses a NeuralChromosome attributes.
        /// </summary>
        /// <param name="chromosomeMetadata">The chromosome metadata.</param>
        /// <param name="element">The NeuralChromosome element.</param>
        private static void ParseNeuralChromosomeAttributes(ref IChromosomeMetadata chromosomeMetadata, XElement element)
        {
            foreach (var attribute in element.Attributes())
            {
                switch (attribute.Name.LocalName)
                {
                case "InputSize":
                    chromosomeMetadata.Properties["InputSize"] = UInt32.Parse(attribute.Value);
                    break;

                case "OutputSize":
                    chromosomeMetadata.Properties["OutputSize"] = UInt32.Parse(attribute.Value);
                    break;

                case "C1":
                    chromosomeMetadata.Properties["C1"] = Double.Parse(attribute.Value);
                    break;

                case "C2":
                    chromosomeMetadata.Properties["C2"] = Double.Parse(attribute.Value);
                    break;

                case "C3":
                    chromosomeMetadata.Properties["C3"] = Double.Parse(attribute.Value);
                    break;

                case "ActivationFunction":
                    chromosomeMetadata.Properties["ActivationFunction"] = (int)Enum.Parse(typeof(ActivationFunction), attribute.Value);
                    break;
                }
            }
        }
        /// <summary>
        /// Parses a Chromosome element.
        /// </summary>
        /// <param name="element">The Chromosome element.</param>
        /// <returns>The parsed chromosome.</returns>
        private static IList <IChromosomeMetadata> ParseChromosome(XElement element)
        {
            var attributes      = element.Attributes();
            var repeatAttribute = attributes.FirstOrDefault(attribute => attribute.Name.LocalName == "Repeat");
            var repeat          = repeatAttribute == null ? 1 : Int32.Parse(repeatAttribute.Value);

            var chromosomeMetadataList = new List <IChromosomeMetadata>();

            for (var i = 0; i < repeat; i++)
            {
                IChromosomeMetadata chromosomeMetadata = null;
                switch (element.Name.LocalName)
                {
                case "BinaryChromosome":
                    chromosomeMetadata = ParseBinaryChromosome(element);
                    break;

                case "PermutationChromosome":
                    chromosomeMetadata = ParsePermutationChromosome(element);
                    break;

                case "NeuralChromosome":
                    chromosomeMetadata = ParseNeuralChromosome(element);
                    break;
                }

                ParseChromosomeAttributes(ref chromosomeMetadata, element, i);

                chromosomeMetadataList.Add(chromosomeMetadata);
            }

            return(chromosomeMetadataList);
        }
        /// <summary>
        /// Validates the chromosome metadata properties.
        /// </summary>
        /// <param name="chromosomeMetadata">The chromosome metatadata to validate.</param>
        private static void ValidateChromosomeProperties(IChromosomeMetadata chromosomeMetadata)
        {
            if (chromosomeMetadata.CrossoverRate < 0 || chromosomeMetadata.CrossoverRate > 1)
            {
                throw new ArgumentException("Error! Crossover rate must be a value between 0 and 1.");
            }
            if (chromosomeMetadata.MutationRate < 0 || chromosomeMetadata.MutationRate > 1)
            {
                throw new ArgumentException("Error! Mutation rate must be a value between 0 and 1.");
            }

            switch (chromosomeMetadata.Type)
            {
            case ChromosomeType.Binary:
                ValidateBinaryChromosomeProperties(chromosomeMetadata);
                break;

            case ChromosomeType.Permutation:
                ValidatePermutationChromosomeProperties(chromosomeMetadata);
                break;

            case ChromosomeType.Neural:
                ValidateNeuralChromosomeProperties(chromosomeMetadata);
                break;
            }
        }
 /// <summary>
 /// Validate that the given property existis in the metadata.
 /// </summary>
 /// <param name="chromosomeMetadata">The chromosome metatadata to validate.</param>
 /// <param name="name">The property name.</param>
 private static void ValidatePropertyExists(IChromosomeMetadata chromosomeMetadata, string name)
 {
     if (!chromosomeMetadata.Properties.ContainsKey(name))
     {
         throw new ArgumentException($"Error! Binary chromosome metadata must contain the {name} property");
     }
 }
        /// <summary>
        /// Adds chromosome metadata to the metadata.
        /// </summary>
        /// <param name="metadata">The metadata to add.</param>
        internal void AddChromosomeMetadata(IChromosomeMetadata metadata)
        {
            if (_chromosomeMetadata.Any(t => t.Name == metadata.Name))
            {
                throw new ArgumentException($"Error! Chromosome metadata named {metadata.Name} already exists.");
            }

            _chromosomeMetadata.Add(metadata);
        }
 // <summary>
 /// Parses a PermutationChromosome attributes.
 /// </summary>
 /// <param name="chromosomeMetadata">The chromosome metadata.</param>
 /// <param name="element">The PermutationChromosome element.</param>
 private static void ParsePermutationChromosomeAttributes(ref IChromosomeMetadata chromosomeMetadata, XElement element)
 {
     foreach (var attribute in element.Attributes())
     {
         switch (attribute.Name.LocalName)
         {
         case "GeneCount":
             chromosomeMetadata.Properties["GeneCount"] = UInt32.Parse(attribute.Value);
             break;
         }
     }
 }
        /// <summary>
        /// Parses the chromosome mutation operators.
        /// </summary>
        /// <typeparam name="TCrossover">The crossover operator type.</typeparam>
        /// <typeparam name="TMutation">The mutation operator type.</typeparam>
        /// <param name="chromosomeMetadata">The chromosome metadata.</param>
        /// <param name="element">The chromosome element.</param>
        private static void ParseMutationOperators <TCrossover, TMutation>(ref IChromosomeMetadata chromosomeMetadata, XElement element)
        {
            foreach (var child in element.Elements())
            {
                var weightAttribute = child.Attributes().FirstOrDefault(attribute => attribute.Name.LocalName == "Weight");
                var weight          = weightAttribute == null ? 1 : Double.Parse(weightAttribute.Value);

                var mutations = ParseOperator <TMutation>(child);

                var metadata = (ChromosomeMetadata <TCrossover, TMutation>)chromosomeMetadata;
                metadata.AddMutationOperators(mutations, weight);
            }
        }
        /// <summary>
        /// Parses the chromosome genetic operators.
        /// </summary>
        /// <typeparam name="TCrossover">The crossover operator type.</typeparam>
        /// <typeparam name="TMutation">The mutation operator type.</typeparam>
        /// <param name="chromosomeMetadata">The chromosome metadata.</param>
        /// <param name="element">The chromosome element.</param>
        private static void ParseOperators <TCrossover, TMutation>(ref IChromosomeMetadata chromosomeMetadata, XElement element)
        {
            foreach (var child in element.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "Crossovers":
                    ParseCrossoverOperators <TCrossover, TMutation>(ref chromosomeMetadata, child);
                    break;

                case "Mutations":
                    ParseMutationOperators <TCrossover, TMutation>(ref chromosomeMetadata, child);
                    break;
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Constructs a chromosome from metadata.
        /// </summary>
        /// <param name="metadata">The chromosome metadata.</param>
        /// <returns>The chromosome.</returns>
        public static IChromosome ConstructChromosome(IChromosomeMetadata metadata)
        {
            switch (metadata.Type)
            {
            case ChromosomeType.Binary:
                return(new BinaryChromosome((uint)metadata.Properties[@"GeneCount"]));

            case ChromosomeType.Permutation:
                return(new PermutationChromosome((uint)metadata.Properties[@"GeneCount"]));

            case ChromosomeType.Neural:
                return(new NeuralChromosome((uint)metadata.Properties[@"InputSize"], (uint)metadata.Properties["OutputSize"], metadata.Name,
                                            metadata.Properties[@"C1"], metadata.Properties[@"C2"], metadata.Properties[@"C3"],
                                            (ActivationFunction)metadata.Properties["ActivationFunction"]));

            default:
                throw new ArgumentException($"Error! Invalid chromosome type.");
            }
        }
        /// <summary>
        /// Parses the chromosome attributes.
        /// </summary>
        /// <param name="chromosomeMetadata">The chromosome metadata.</param>
        /// <param name="element">The chromosome element.</param>
        /// <param name="i">The current repeat count.</param>
        private static void ParseChromosomeAttributes(ref IChromosomeMetadata chromosomeMetadata, XElement element, int i)
        {
            foreach (var attribute in element.Attributes())
            {
                switch (attribute.Name.LocalName)
                {
                case "Name":
                    chromosomeMetadata.Name = Regex.Replace(attribute.Value, "%i", $"{i}");
                    break;

                case "CrossoverRate":
                    chromosomeMetadata.CrossoverRate = Double.Parse(attribute.Value);
                    break;

                case "MutationRate":
                    chromosomeMetadata.MutationRate = Double.Parse(attribute.Value);
                    break;
                }
            }
        }
        /// <summary>
        /// Validates the neural chromosome metadata properties.
        /// </summary>
        /// <param name="chromosomeMetadata">The chromosome metatadata to validate.</param>
        private static void ValidateNeuralChromosomeProperties(IChromosomeMetadata chromosomeMetadata)
        {
            ValidatePropertyExists(chromosomeMetadata, "InputSize");
            ValidatePropertyExists(chromosomeMetadata, "OutputSize");
            ValidatePropertyExists(chromosomeMetadata, "C1");
            ValidatePropertyExists(chromosomeMetadata, "C2");
            ValidatePropertyExists(chromosomeMetadata, "C3");
            ValidatePropertyExists(chromosomeMetadata, "ActivationFunction");

            if (chromosomeMetadata.Properties["C1"] < 0)
            {
                throw new ArgumentException("Error! C1 must be a positive value.");
            }
            if (chromosomeMetadata.Properties["C2"] < 0)
            {
                throw new ArgumentException("Error! C2 must be a positive value.");
            }
            if (chromosomeMetadata.Properties["C3"] < 0)
            {
                throw new ArgumentException("Error! C3 must be a positive value.");
            }
        }
 /// <summary>
 /// Validates the permutation chromosome metadata properties.
 /// </summary>
 /// <param name="chromosomeMetadata">The chromosome metatadata to validate.</param>
 private static void ValidatePermutationChromosomeProperties(IChromosomeMetadata chromosomeMetadata)
 {
     ValidatePropertyExists(chromosomeMetadata, "GeneCount");
 }