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();
}
}
参考主函数: