• 自动排课思路


    以下为遗传算法自动排课,在生物课上都讲过遗传方面的问题,那么将每一个课程当做一个个体,然后优胜劣汰,最后获得的种群就是我们想要的结果

    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);
    }
    }
    }
    }

    就这样一直筛选下去,直到没有冲突就得到我们想要的结果啦

  • 相关阅读:
    Android 锁屏 临时屏蔽
    单编译framework相关模块
    02
    pad 强制加载 Hdpi资源 (2.3 dpi < 240)
    设置form的默认按钮
    How to Be a Good Graduate Student
    我怕你们急于求成
    希腊字母读音表
    数据库札记(二)
    Ubuntu 9.04下jdk的安装与配置
  • 原文地址:https://www.cnblogs.com/lk2017/p/10107063.html
Copyright © 2020-2023  润新知