以下为遗传算法自动排课,在生物课上都讲过遗传方面的问题,那么将每一个课程当做一个个体,然后优胜劣汰,最后获得的种群就是我们想要的结果
1.首先创建一个数据,相当于初始化一个种群
1 public class TSPDATA 2 { 3 4 public static int SPECIES_Num = 200; //种群数 5 public static readonly int Develop_Num = 1000; //进化代数 6 public static readonly float pcl = 0.7f, pch = 0.95f;//交叉概率 7 public static readonly float pm = 0.4f; //变异概率 8 public static readonly string[] Course= { "00150","00230","00340","00450","00560","00660","00760" };//课程集合 9 public static readonly string[] Room= { "00150", "00230", "00340", "00450", "00560", "00660", "00760" }; //教室集合 10 public static string[] Classm= {"001","002","003","004","005","006" }; //班级集合 11 public static readonly string[] Teacher= {"001","002","003","004" }; //教师集合 12 public static readonly string[] Time ={"11","12","13","14","21","22","31","41","43","51","52" }; //时间集合 13 public static readonly int LessonNum = Room.Length * Time.Length; 14 } 15 16 public class Lesson:TSPDATA 17 { 18 public string course; 19 public string room; 20 public string classm; 21 public string time; 22 public string teacher; 23 24 public string Course { get => course; set => course = value; } 25 public string Room { get => room; set => room = value; } 26 public string Classm { get => @classm; set => classm = value; } 27 public string Time { get => time; set => time = value; } 28 public string Teacher { get => teacher; set => teacher = value; } 29 30 31 }
简历基因序列,初始化种群
public class SpeciesIndividual
{
public string[,] genes;//基因序列
public int[] fitness;//适应度
public SpeciesIndividual()
{
//初始化
this.genes = new string[TSPDATA.SPECIES_Num, TSPDATA.LessonNum];
this.fitness = new int[TSPDATA.SPECIES_Num];
for (int i = 0; i < TSPDATA.SPECIES_Num; i++)
{
this.fitness[i] = 100;
}
}
//初始物种基因(随机)
public void CreateByRandomGenes()
{
int temp;
Random rand = new Random();
for (int i = 0; i < TSPDATA.SPECIES_Num; i++)
{
temp = 0;
for (int j = 0; j < TSPDATA.Time.Length; j++)
{
for (int k = 0; k < TSPDATA.Room.Length; k++)
{
Lesson lesson = new Lesson();
lesson.Classm = rand.Next(TSPDATA.Classm.Length);
lesson.Course = rand.Next(TSPDATA.Course.Length);
lesson.Room = k;
lesson.Teacher = rand.Next(TSPDATA.Teacher.Length);
lesson.Time = j;
genes[i, temp] = Lesson.Getstr(lesson);
temp++;
}
}
}
}
根据冲突得到适应度函数,将适应度给为100,每当课程冲突时,便减少
public void CalFitness()
{
for (int j = 0; j < fitness.Length; j++)
{
fitness[j] = 100;
}
for(int i=0;i<TSPDATA.SPECIES_Num;i++)
{
for (int j = 0; j < TSPDATA.LessonNum-1;j++)
{
Lesson le = Lesson.GetLesson(genes[i, j]);
Lesson lec = Lesson.GetLesson(genes[i, j+ 1]);
if(le.Time.Equals(lec.Time)&&le.Course!=9)
{
if(le.Teacher.Equals(lec.Teacher)||le.Course.Equals(lec.Course)||le.Classm.Equals(lec.Classm))
{
fitness[i]--;
}
}
}
}
选择优秀物种(轮盘赌),选择适应度高的个体
public void Select()
{
string[,] demogenes = new string[TSPDATA.SPECIES_Num, TSPDATA.LessonNum];//存储新的genes
int u = Convert.ToInt32(TSPDATA.SPECIES_Num * 0.7);
Random rand = new Random();
//最大适应度
int cal_temp = Convert.ToInt32(fitness[0]);
int cal_flag = 0;
double[] temp = new double[fitness.Length];
double sum = 0.0d;
for (int i = 0; i < fitness.Length; i++)
{
sum += fitness[i];
}
//由适应度计算概率
for (int j = 0; j < fitness.Length; j++)
{
//找到适应度最高
if (Convert.ToInt32(fitness[j]) > cal_temp)
{
cal_temp = Convert.ToInt32(fitness[j]);
cal_flag = j;
}
temp[j] = fitness[j] / sum;
}
交叉,在种群繁衍过程中会出现基因交叉与变异
public void Crossover()
{
Random rand = new Random();
for (int i = 0; i < TSPDATA.SPECIES_Num; i++)
{
float rate = (float)rand.NextDouble();
for (int j = 0; j < TSPDATA.LessonNum-1; j++)
{
if (rate > TSPDATA.pcl && rate < TSPDATA.pch)
{
//string str = genes[i+1, j];
Lesson le1 = Lesson.GetLesson(genes[i, j]);
Lesson le2 = Lesson.GetLesson(genes[i, j+1]);
if (le1.Time != -1 && le2.Time != -1)
{
int s, k, g;
s = le1.Teacher;
k = le1.Course;
g = le1.Classm;
le1.Teacher = le2.Teacher;
le1.Course = le2.Course;
le1.Classm = le2.Classm;
le2.Classm = g;
le2.Course = k;
le2.Teacher = s;
genes[i, j] = Lesson.Getstr(le1);
genes[i, j + 1] = Lesson.Getstr(le2);
}
}
}
}
}
变异
public void Mutate()
{
Random rand = new Random();
float rate = (float)rand.NextDouble();
for (int i = 0; i < TSPDATA.SPECIES_Num; i++)
{
for (int j = 0; j < TSPDATA.LessonNum - 1; j++)
{
if (rate < TSPDATA.pm)
{
Lesson l1 = Lesson.GetLesson(genes[i, j]);
l1.Teacher = rand.Next(TSPDATA.Teacher.Length);
l1.Course = rand.Next(TSPDATA.Course.Length);
l1.Classm = rand.Next(TSPDATA.Classm.Length);
genes[i, j] = Lesson.Getstr(l1);
}
}
}
}
就这样一直筛选下去,直到没有冲突就得到我们想要的结果啦