C# 实现遗传算法

2019-12-12  本文已影响0人  吵吵人

这里只展示GA相关步骤的C#实现,遗传算法整个流程可参考以下链接,虽然该文是matlab实现的,但是逻辑很清楚:https://www.cnblogs.com/LoganChen/p/7509702.html

chromosome 类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SiteWindows
{
    class chromosome
    {
        public List<int> bits=new List<int>();
        public double fitValue;//适应度
        public double fitValuePercent;//适应度占比
        public double probability;//累积概率上限
        public int length=0;//染色体长度

        public chromosome()
        {
        
        }

        public chromosome(int len)
        {
            this.length=len;
        }

        public chromosome Clone()
        {
            chromosome c = new chromosome();
            for (int i = 0; i < this.length; i++)
            {
                int tmp = this.bits[i];
                c.bits.Add(tmp);
            }
            c.fitValue = this.fitValue;
            c.fitValuePercent = this.fitValuePercent;
            c.probability = this.probability;
            c.length=this.length;
            c.coverageRate = this.coverageRate;
            c.RepetitionRate = this.RepetitionRate;
            return c;
        }
  
    }
}

GA类

初始化

        public void Init()
        {
            
            this.chromosomes.Clear();
            this.toalFitness= 0;

            for (int i = 0; i < this.pop; i++)
            {
                chromosome chromosome = new chromosome(this.staions.Count);
                for (int j = 0; j < chromosome.length; j++)
                {
                    int bitValue = random.Next(0, 2);
                    chromosome.bits.Add(bitValue);
                }

                //计算覆盖率、重复率、适应度
                chromosome.coverageRate = CalculateDemandRate(chromosome);

                chromosome.fitValue=Fitness(chromosome);
                this.chromosomes.Add(chromosome);

                //最优个体
                if(i==0)
                    this.best = chromosome.Clone();
                else
                {
                    if (chromosome.fitValue > this.best.fitValue) 
                        this.best = chromosome.Clone();
                }
            }
        }

适应度函数,每个应用场景不一样

        public double Fitness(chromosome c)
        {
            double fitness=0;
            //根据不同场景去编写
            return fitness;
        }

更新适应度函数

        public void UpdataFitvalue(ref List<chromosome> chromosomes)
        {
            foreach(chromosome item in chromosomes)
            {
                item.fitValue=Fitness(item);

            }
        }

选择操作

        public void Selection()
        {
            this.toalFitness=0;
            for (int i = 0; i < this.chromosomes.Count; i++)
                 this.toalFitness+=this.chromosomes[i].fitValue;

            //算出每个的fit percent;
             for (int i = 0; i < this.chromosomes.Count; i++)
            {
                this.chromosomes[i].fitValuePercent = this.chromosomes[i].fitValue / this.toalFitness ;
            }

            //计算累积概率,就是该染色体所在轮盘的范围上限
            this.chromosomes[0].probability = this.chromosomes[0].fitValuePercent;
            for (int i = 1; i < chromosomes.Count; i++)
            {
                chromosomes[i].probability = chromosomes[i].fitValuePercent + this.chromosomes[i - 1].probability;
            }

            //轮盘赌选择方法,随机选择N条染色体进行繁殖下一代
            if(this.chromosomesChild.Count>0)
            {
                chromosomesChild.Clear();
            }
            for (int i = 0; i < chromosomes.Count; i++)
            {
                //产生0-1之间的随机数;
                double rand = random.NextDouble();
                if (rand < chromosomes[0].probability)
                {
                    chromosomesChild.Add(chromosomes[0].Clone());
                }
                else
                {
                    for (int j = 1; j < chromosomes.Count; j++)
                    {
                        if (chromosomes[j-1].probability <= rand && rand <= chromosomes[j].probability)
                        {
                            chromosome tmp = new chromosome();
                            tmp = chromosomes[j].Clone();
                            chromosomesChild.Add(tmp);
                        }
                    }
                }
            }

            //已经选择
            for (int i = 0; i < chromosomes.Count; i++)
            {
                chromosomes[i] = chromosomesChild[i].Clone();
            }
        }

交叉操作

        public void CrossOperate()
        {

            int rand1 = random.Next(0, this.chromosomes[0].bits.Count);
            int rand2 = random.Next(0, this.chromosomes[0].bits.Count);
            if (rand1 > rand2)
            {
                var t = rand1;
                rand1 = rand2;
                rand2 = t;
            }

            for (int j = 0; j < this.chromosomes.Count; j = j + 2)
            {
                for (int i = rand1; i <= rand2; i++)
                {
                    var t = this.chromosomes[j].bits[i];
                    this.chromosomes[j].bits[i] = this.chromosomes[j + 1].bits[i];
                    this.chromosomes[j + 1].bits[i] = t;
                }
                this.chromosomes[j].fitValue = this.Fitness(this.chromosomes[j]);
                this.chromosomes[j + 1].fitValue = this.Fitness(this.chromosomes[j + 1]);
            }
        }

变异操作

        public  void VariationOperate()
        {
            int rand = random.Next(0, this.chromosomes.Count);
            if (rand < this.chromosomes.Count*0.01)                       //1/50 = 0.02的概率进行变异;rand==25;
            {
                int chromIndex = random.Next(0, this.chromosomes.Count);
                int bitIndex = random.Next(0, this.chromosomes[chromIndex].length);


                if (this.chromosomes[chromIndex].bits[bitIndex] == 0)
                {
                    this.chromosomes[chromIndex].bits[bitIndex] = 1;
                }
                else
                {
                   this.chromosomes[chromIndex].bits[bitIndex] = 0;
                }
                this.chromosomes[chromIndex].fitValue = Fitness(this.chromosomes[chromIndex]);
            }
        }

挑选最好的

        public void ChooseBest()
        {
            foreach(chromosome item in chromosomes)
            {
                if (item.fitValue > best.fitValue)
                    best = item.Clone();
            }
        }

参考主函数:

上一篇下一篇

猜你喜欢

热点阅读