diff --git a/src/GeneticSharp.Domain/Chromosomes/IntegerArrayChromosome.cs b/src/GeneticSharp.Domain/Chromosomes/IntegerArrayChromosome.cs new file mode 100644 index 00000000..16f367e3 --- /dev/null +++ b/src/GeneticSharp.Domain/Chromosomes/IntegerArrayChromosome.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections; +using System.Linq; + +namespace GeneticSharp +{ + /// + /// IntegerArray chromosome, uses binary values (0 and 1). + /// + public class IntegerArrayChromosome : BinaryChromosomeBase + { + private readonly int[] m_maxValues; + private readonly int[] m_totalBits; + private readonly int[] m_cumulativeBits; + private readonly BitArray[] m_originalValues; + + /// + /// Initializes a new instance of the class. + /// + /// array of int[] maximum values; this chromosome assumes that the minvalue >= 0 + public IntegerArrayChromosome(int[] maxValues, int[] seedingValues = null) + : base(maxValues.Sum(x => Convert.ToString(x, 2).Length)) { + int length = maxValues.Length; + m_maxValues = maxValues; + m_totalBits = new int[length]; + m_originalValues = new BitArray[length]; + m_cumulativeBits = new int[length]; + int cumulativeBitsSum = 0; + for (int i = 0; i < length; i++) { + int bitLength = Convert.ToString(maxValues[i], 2).Length; + m_totalBits[i] = bitLength; + cumulativeBitsSum += bitLength; + m_cumulativeBits[i] = cumulativeBitsSum; + + int intValue = (seedingValues != null && seedingValues.Length == length) ? seedingValues[i] : RandomizationProvider.Current.GetInt(0, maxValues[i]); + m_originalValues[i] = new BitArray(new int[] { intValue }); + } + CreateGenes(); + } + + /// + /// Generates the gene. + /// + /// The gene. + /// Gene index. + public override Gene GenerateGene(int geneIndex) { + int arrayIndex = Array.BinarySearch(m_cumulativeBits, geneIndex); + if (arrayIndex < 0) arrayIndex = ~arrayIndex; + int localIndex = (arrayIndex == 0) ? geneIndex : (geneIndex - m_cumulativeBits[arrayIndex - 1]); + return new Gene(m_originalValues[arrayIndex][localIndex]); + } + + /// + /// Fast flip of the gene. + /// + /// The Gene index. + /// If gene's value is true, it will flip it to false and vice-versa. + public override void FlipGene(int index) { + int arrayIndex = Array.BinarySearch(m_cumulativeBits, index); + if (arrayIndex < 0) arrayIndex = ~arrayIndex; + var value = (bool)GetGene(index).Value; + ReplaceGene(index, new Gene(!value)); + } + + /// + /// Creates a new Chromosome. + /// + /// a new instance of Chromosome of type IntegerArrayChromosome. + public override IChromosome CreateNew() { + return new IntegerArrayChromosome(m_maxValues); + } + + /// + /// Converts a chromosome to an array of integers. + /// + /// int[] array. + public int[] ToIntegerArray() { + int[] result = new int[m_maxValues.Length]; + int bitCounter = 0; + for (int i = 0; i < m_maxValues.Length; i++) { + int[] array = new int[1]; + bool[] genes = new bool[m_totalBits[i]]; + for (int j = 0; j < m_totalBits[i]; j++) { + genes[j] = (bool)GetGene(bitCounter + j).Value; + } + BitArray bitArray = new BitArray(genes); + bitArray.CopyTo(array, 0); + result[i] = Math.Min(array[0], m_maxValues[i]); + bitCounter += m_totalBits[i]; + } + return result; + } + + /// + /// Returns a that represents the current . + /// + /// A that represents the current . + public override string ToString(){ + return String.Join("", GetGenes().Select(g => (bool)g.Value ? "1" : "0").ToArray()); + } + } + +} +