giacomelli / GeneticSharp

GeneticSharp is a fast, extensible, multi-platform and multithreading C# Genetic Algorithm library that simplifies the development of applications using Genetic Algorithms (GAs).
MIT License
1.27k stars 332 forks source link

IntegerChromosome example for 32 gene length Last gene is always 0 #30

Closed aveshd closed 6 years ago

aveshd commented 6 years ago

Hi,

I was doing some experiments with the library, it seems in the integer chromosome example when one has 32 genes, last gene value will always be one.

Please let me know if something is missing in my understanding, I guess one can escape this problem by shifting the bit of the integer using some probability cut-off.

regards,

giacomelli commented 6 years ago

I will investigate it tonight, I suspect there something wrong with string representation of IntegerChromosome.

Meanwhile you can use the FloatingPointChromosome with fractionDigits 0. It has been more used and tested than integer one, you can see a sample of it on http://diegogiacomelli.com.br/function-optimization-with-geneticsharp/

Thanks!

giacomelli commented 6 years ago

I found a bug on IntergerChromosome.ToString() that was resulting in "FalseTrueFalse..." instead of "101...", but the chromosome it self was ok, no problem on it genotype or phenotype. Fixed by #31.

About the "last gene value will always be one" as mentioned in #17 we use the two's complement representation, this means that the high-order bit of the highest-order byte (bit 63) is interpreted as the sign bit (https://msdn.microsoft.com/pt-br/library/6wse73s4(v=vs.110).aspx).

aveshd commented 6 years ago

Thank you for fixing the ToString() it does help.

regarding the least bit being 1, your answer helped me solve that problem, I was not using UnSigned int32 as the max value. So I fixed it via giving it full range.

Please take a look at the code below which generates integerChromosome for any number of bits The example problem was limited to 32.

if you think I am not making any mistake I will drop it as an example to help others out

    /// <summary>
    /// Integer chromosome with binary values (0 and 1).
    /// </summary>
    public class IntegerChromosome : BinaryChromosomeBase
    {
        private int m_minValue = Int32.MinValue;
        private int m_maxValue = Int32.MaxValue;
        private BitArray m_originalValue;
        private int m_length = 10;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:GeneticSharp.Domain.Chromosomes.IntegerChromosome"/> class.
        /// </summary>
        /// <param name="minValue">Minimum value.</param>
        /// <param name="maxValue">Maximum value.</param>
        public IntegerChromosome(int length) : base(length)
        {
            m_length = length;
            int num_intElements = length / 32 + 1; ;

            var intValue = RandomizationProvider.Current.GetInts(num_intElements,m_minValue, m_maxValue);

            m_originalValue = new BitArray(intValue);

            CreateGenes();
        }

        #region implemented abstract members of ChromosomeBase
        /// <summary>
        /// Generates the gene.
        /// </summary>
        /// <returns>The gene.</returns>
        /// <param name="geneIndex">Gene index.</param>
        public override Gene GenerateGene(int geneIndex)
        {
            var value = m_originalValue[geneIndex];

            return new Gene(value);
        }

        /// <summary>
        /// Creates the new.
        /// </summary>
        /// <returns>The new.</returns>
        public override IChromosome CreateNew()
        {
            return new IntegerChromosome(m_length);
        }

        #endregion

        /// <summary>
        /// Converts the chromosome to its integer representation.
        /// </summary>
        /// <returns>The integer.</returns>
        public int ToInteger()
        {
            var array = new int[1];
            var genes = GetGenes().Select(g => (bool)g.Value).ToArray();
            var bitArray = new BitArray(genes);
            bitArray.CopyTo(array, 0);

            return array[0];
        }
        public override string ToString()
        {
            return String.Join("", GetGenes().Reverse().Select(g => (bool)g.Value ? "1" : "0").ToArray());
        }
    }
giacomelli commented 6 years ago

Nice solution! This could be added as another constructor to the IntegerChromosome.

If you would like, please, make a pull request adding this new constructor to the IntegerChromosome and it will be great if you add some unit test to validate this new feature.

Thanks!