Click here to Skip to main content
15,886,797 members
Articles / Programming Languages / C#

Generalization of a Simple Genetic Algorithm (GA)

Rate me:
Please Sign up or sign in to vote.
4.54/5 (8 votes)
20 Nov 200610 min read 46.5K   1.2K   46  
Taking a simple genetic algorithm and constructing a framework to allow easy creation of similar algorithms.
using System;
using System.Collections.Generic;
using System.Text;
using GeneticAlgorithmLib;
using System.ComponentModel;

namespace GeneticAlgorithm
{
    public class CardProblem : BinaryGeneticAlgorithm
    {
        private int m_SumTarget;
        private int m_ProdTarget;
        private int m_NumberOfCards;

        public CardProblem(int NumberOfCards, int SumTarget, int ProductTarget, 
            double ChanceOfInfection, double ChanceOfMutation)
            : base(ChanceOfInfection, ChanceOfMutation)
        {
            this.m_NumberOfCards = NumberOfCards;
            this.m_SumTarget = SumTarget;
            this.m_ProdTarget = ProductTarget;
        }

        #region Overrides
        #region ChooseWinners
        protected override void ChooseWinners(IGenotype First, IGenotype Second, out IGenotype Winner, out IGenotype Loser)
        {
            CardGenes f = First as CardGenes,
                s = Second as CardGenes;
            double fFitness = Evaluate(f),
                sFitness = Evaluate(s);
            if ( fFitness < sFitness)
            {
                Winner = f;
                Loser = s;
            }
            else
            {
                Winner = s;
                Loser = f;
            }
        }
        #endregion

        #region Evaluate
        protected override bool Evaluate(IGenotype Genes)
        {
            CardGenes g = Genes as CardGenes;
            bool returnVal = Evaluate(g) == 0.0;
            return returnVal;
        }
        #endregion

        #region CreateGenotype
        protected override IGenotype CreateGenotype()
        {
            return new CardGenes(this.m_NumberOfCards);
        }
        #endregion
        
        #endregion

        private double Evaluate(CardGenes f)
        {
            double sumErr, prodErr, combinedErr;
            int sum = 0, prod = 1;

            for (int i = 0; i < f.Genes.Count; i++)
            {
                Gene gene = f.Genes[i];
                if (gene.Value == EGene.On)
                {
                    // On means sum
                    sum += (i + 1);
                }
                else
                {
                    // Off means product
                    prod *= (i + 1);
                }
            }
            sumErr = ((double)(sum - m_SumTarget)) / (double)m_SumTarget;
            prodErr = ((double)(prod - m_ProdTarget)) / (double)m_ProdTarget;
            combinedErr = Math.Abs(sumErr) + Math.Abs(prodErr);
            f.Sum = sum;
            f.Product = prod;
            return combinedErr;
        }

        #region Helpers
        /// <summary>
        /// For debugging purposes. Let's us look at the IGenotypes.
        /// </summary>
        /// <param name="CG"></param>
        /// <returns></returns>
        private string GetResultString(CardGenes CG)
        {
            string returnVal = null;
            StringBuilder sbSum = new StringBuilder(),
                sbProd = new StringBuilder();
            for (int i = 0; i < CG.Genes.Count; i++)
            {
                if (CG.Genes[i].Value == EGene.On)
                {
                    sbSum.AppendFormat("{0} ({1}){2}", 
                        CG.Genes[i].NameString, 
                        CG.Genes[i].Value, 
                        Environment.NewLine);
                }
                else
                {
                    sbProd.AppendFormat("{0} ({1}){2}", 
                        CG.Genes[i].NameString, 
                        CG.Genes[i].Value, 
                        Environment.NewLine);
                }
            }
            returnVal = string.Format("The following are in the sum: {0}{2}"
                + "The following are in the product: {1}{2}",
                sbSum.ToString(), sbProd.ToString(), Environment.NewLine);
            return returnVal;
        }
        #endregion


    }

    public class CardGenes : IGenotype
    {
        #region Sum
        private int m_Sum;
        [Browsable(true)]
        public int Sum
        {
            get { return m_Sum; }
            set { m_Sum = value; }
        }
        #endregion

        #region Product
        private int m_Product;
        [Browsable(true)]
        public int Product
        {
            get { return m_Product; }
            set { m_Product = value; }
        }
        #endregion

        private int m_NumberOfCards;
        #region Constructors / Destructors
        public CardGenes(int NumberOfCards)
        {
            this.m_NumberOfCards = NumberOfCards;
        }
        #endregion
        
        #region IGenotype Members
        private List<Gene> m_Genes;
        public List<Gene> Genes
        {
            get
            {
                if (m_Genes == null)
                {
                    m_Genes = new List<Gene>(m_NumberOfCards);
                    Random r = new Random();
                    for (int i = 0; i < m_NumberOfCards; i++)
                    {
                        int j = i + 1;
                        double curr = r.NextDouble();
                        EGene gene = curr < 0.5 ? EGene.Off : EGene.On;
                        m_Genes.Add(new Gene(j.ToString(), gene));
                    }
                }
                return m_Genes;
            }
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Canada Canada
I am a software developer. I live and work in Toronto. I'm one of the lucky ones: my work is my passion - I code for fun. I enjoy learning new coding techniques and teaching others about software development - I find that the more I teach, the more I learn.
When I'm not coding, you can find me inline skating along Toronto's waterfront or playing Psychonauts or Splinter Cell.

Comments and Discussions