<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      實(shí)例講解遺傳算法——基于遺傳算法的自動(dòng)組卷系統(tǒng)【實(shí)踐篇】

            上一篇實(shí)例講解遺傳算法——基于遺傳算法的自動(dòng)組卷系統(tǒng)【理論篇】講了遺傳算法的原理及在自己動(dòng)組卷系統(tǒng)中的應(yīng)用,本篇將給出上一篇中所述理論的實(shí)踐。

            先上兩張運(yùn)行后的效果圖吧:

       

       基于遺傳算法的自動(dòng)組卷系統(tǒng)運(yùn)行效果圖(1)

       

      基于遺傳算法的自動(dòng)組卷系統(tǒng)運(yùn)行效果圖(2) 

       一、準(zhǔn)備工作

      1、問題實(shí)體

            問題實(shí)體包含編號(hào)、類型(類型即題型,分為五種:?jiǎn)芜x,多選,判斷,填空,問答, 分別用1、2、3、4、5表示)、分?jǐn)?shù)、難度系數(shù)、知識(shí)點(diǎn)。一道題至少有一個(gè)知識(shí)點(diǎn),為簡(jiǎn)單易懂,知識(shí)點(diǎn)用List<int> 表示(知識(shí)點(diǎn)編號(hào)集合)。

            代碼如下:

      public class Problem 
      {
          public Problem()
          {
              ID 
      = 0;
              Type 
      = 0;
              Score 
      = 0;
              Difficulty 
      = 0.00;
              Points 
      = new List<int>();
          }

          
      public Problem(Problem p)
          {
              
      this.ID = p.ID;
              
      this.Type = p.Type;
              
      this.Score = p.Score;
              
      this.Difficulty = p.Difficulty;
              
      this.Points = p.Points;
          }

          
      /// <summary>
          
      /// 編號(hào)
          
      /// </summary>
          public int ID { getset; }

          
      /// <summary>
          
      /// 題型(1、2、3、4、5對(duì)應(yīng)單選,多選,判斷,填空,問答)
          
      /// </summary>
          public int Type { getset; }

          
      /// <summary>
          
      /// 分?jǐn)?shù)
          
      /// </summary>
          public int Score { getset; }

          
      /// <summary>
          
      /// 難度系數(shù)
          
      /// </summary>
          public double Difficulty { getset; }

          
      /// <summary>
          
      /// 知識(shí)點(diǎn)
          
      /// </summary>
          public List<int> Points { getset; }

       } 

       

      2、題庫(kù)

            為了簡(jiǎn)單,這里沒有用數(shù)據(jù)庫(kù),題目信息臨時(shí)創(chuàng)建,保存在內(nèi)存中。因?yàn)閷?duì)不同層次的考生一道題目在不同試卷中的分?jǐn)?shù)可能不一樣,因此題目分?jǐn)?shù)一般是老師出卷時(shí)定的,不保存在題庫(kù)中。且單選,多選,判斷題每題分?jǐn)?shù)應(yīng)該相同,填空題一般根據(jù)空數(shù)來定分?jǐn)?shù),而問答題一般根據(jù)題目難度來定的,因此這里的單選、多選、判斷分?jǐn)?shù)相同,填空空數(shù)取1-4間的隨機(jī)數(shù),填空題分?jǐn)?shù)即為空數(shù),問答題即為該題難度系數(shù)*10取整。這里各種題型均為1000題,具體應(yīng)用時(shí)改為數(shù)據(jù)庫(kù)即可。

            代碼如下:

      public class DB
      {
          
      /// <summary>
          
      /// 題庫(kù)
          
      /// </summary>
          public List<Problem> ProblemDB;

          
      public DB()
          {
              ProblemDB 
      = new List<Problem>();
              Problem model;
              Random rand 
      = new Random();
              List
      <int> Points;
              
      for (int i = 1; i <= 5000; i++)
              {
                  model 
      = new Problem();
                  model.ID 
      = i;

                  
      //試題難度系數(shù)取0.3到1之間的隨機(jī)值
                  model.Difficulty = rand.Next(30100* 0.01;

                  
      //單選題1分
                  if (i < 1001)
                  {
                      model.Type 
      = 1;
                      model.Score 
      = 1;
                  }

                  
      //單選題2分
                  if (i > 1000 && i < 2001)
                  {
                      model.Type 
      = 2;
                      model.Score 
      = 2;
                  }

                  
      //判斷題2分
                  if (i > 2000 && i < 3001)
                  {
                      model.Type 
      = 3;
                      model.Score 
      = 2;
                  }

                  
      //填空題1—4分
                  if (i > 3000 && i < 4001)
                  {
                      model.Type 
      = 4;
                      model.Score 
      = rand.Next(15);
                  }

                  
      //問答題分?jǐn)?shù)為難度系數(shù)*10
                  if (i > 4000 && i < 5001)
                  {
                      model.Type 
      = 5;
                      model.Score 
      = model.Difficulty > 0.3 ? (int)(double.Parse(model.Difficulty.ToString("f1")) * 10) : 3;
                  }

                  Points 
      = new List<int>();
                  
      //每題1到4個(gè)知識(shí)點(diǎn)
                  int count = rand.Next(15);
                  
      for (int j = 0; j < count; j++)
                  {
                      Points.Add(rand.Next(
      1100));
                  }
                  model.Points 
      = Points;
                  ProblemDB.Add(model);
              }
          }

      } 

      3、 試卷實(shí)體

            試卷一般包含試卷編號(hào),試卷名稱,考試時(shí)間,難度系數(shù),知識(shí)點(diǎn)分布,總題數(shù), 總分?jǐn)?shù),各種題型所占比率等屬性,這里為簡(jiǎn)單去掉了試卷名稱跟考試時(shí)間。其中的知識(shí)點(diǎn)分布即老師出卷時(shí)選定本試卷要考查的知識(shí)點(diǎn),這里用List<int>(知識(shí)點(diǎn)編號(hào)集合)表示。

            代碼如下:

      public class Paper
      {
          
      /// <summary>
          
      /// 編號(hào)
          
      /// </summary>
          public int ID { getset; }

          
      /// <summary>
          
      /// 總分
          
      /// </summary>
          public int TotalScore { getset; }

          
      /// <summary>
          
      /// 難度系數(shù)
          
      /// </summary>
          public double Difficulty { getset; }

          
      /// <summary>
          
      /// 知識(shí)點(diǎn)
          
      /// </summary>
          public List<int> Points { getset; }

          
      /// <summary>
          
      /// 各種題型題數(shù)
          
      /// </summary>
          public int[] EachTypeCount { getset; }

      } 

       二、開始遺傳算法組卷之旅

            準(zhǔn)備工作已經(jīng)OK,下面就按上一篇介紹的流程進(jìn)行操作啦!

      1、產(chǎn)生初始種群

            這里保證題數(shù)跟總分達(dá)到出卷要求即可,但為操作方便,這里再定義一個(gè)種群個(gè)體實(shí)體類Unit,包含編號(hào)、適應(yīng)度、題數(shù)、總分、難度系數(shù)、知識(shí)點(diǎn)分布、包含的題目等信息(也可以修改一下試卷實(shí)體,用試卷實(shí)體表示):

      public class Unit

      {
          public Unit()
          {
              ID 
      = 0;
              AdaptationDegree 
      = 0.00;
              KPCoverage 
      = 0.00;
              ProblemList 
      = new List<Problem>();
          }

          
      /// <summary>
          
      /// 編號(hào)
          
      /// </summary>
          public int ID { getset; }

          
      /// <summary>
          
      /// 適應(yīng)度
          
      /// </summary>
          public double AdaptationDegree { getset; }

          
      /// <summary>
          
      /// 難度系數(shù)(本試卷所有題目分?jǐn)?shù)*難度系數(shù)/總分)
          
      /// </summary>
          public double Difficulty
          {
              
      get
              {
                  
      double diff = 0.00;
                  ProblemList.ForEach(
      delegate(Problem p)
                  {
                      diff 
      += p.Difficulty * p.Score;
                  });
                  
      return diff / SumScore;
              }
          }

          
      /// <summary>
          
      /// 題目數(shù)量
          
      /// </summary>
          public int ProblemCount
          {
              
      get
              {
                  
      return ProblemList.Count;
              }
          }

          
      /// <summary>
          
      /// 總分
          
      /// </summary>
          public int SumScore
          {
              
      get
              {
                  
      int sum = 0;
                  ProblemList.ForEach(
      delegate(Problem p)
                  {
                      sum 
      += p.Score;
                  });
                  
      return sum;
              }
          }

          
      /// <summary>
          
      /// 知識(shí)點(diǎn)分布
          
      /// </summary>
          public double KPCoverage { getset; }

          
      /// <summary>
          
      /// 題目
          
      /// </summary>
          public List<Problem> ProblemList { getset; }
      }

             下面即來產(chǎn)生初始種群,按個(gè)體數(shù)量,期望試卷知識(shí)點(diǎn)分布,各類型題目數(shù)等限制產(chǎn)生初始種群:

          /// <summary>
          
      /// 初始種群
          
      /// </summary>
          
      /// <param name="count">個(gè)體數(shù)量</param>
          
      /// <param name="paper">期望試卷</param>
          
      /// <param name="problemList">題庫(kù)</param>
          
      /// <returns>初始種群</returns>
          public List<Unit> CSZQ(int count, Paper paper, List<Problem> problemList)
          {
              List
      <Unit> unitList = new List<Unit>();
              
      int[] eachTypeCount = paper.EachTypeCount;
              Unit unit;
              Random rand 
      = new Random();
              
      for (int i = 0; i < count; i++)
              {
                  unit 
      = new Unit();
                  unit.ID 
      = i + 1;
                  unit.AdaptationDegree 
      = 0.00;

                  
      //總分限制
                  while (paper.TotalScore != unit.SumScore)
                  {
                      unit.ProblemList.Clear();

                      
      //各題型題目數(shù)量限制
                      for (int j = 0; j < eachTypeCount.Length; j++)
                      {
                          List
      <Problem> oneTypeProblem = problemList
                              .Where(o 
      => o.Type == (j + 1))
                              .Where(p 
      => IsContain(paper, p))
                              .ToList();
                          Problem temp 
      = new Problem();
                          
      for (int k = 0; k < eachTypeCount[j]; k++)
                          {
                              
      //選擇不重復(fù)的題目
                              int index = rand.Next(0, oneTypeProblem.Count - k);
                              unit.ProblemList.Add(oneTypeProblem[index]);
                              temp 
      = oneTypeProblem[oneTypeProblem.Count - 1 - k];
                              oneTypeProblem[oneTypeProblem.Count 
      - 1 - k] = oneTypeProblem[index];
                              oneTypeProblem[index] 
      = temp;
                          }
                      }
                  }
                  unitList.Add(unit);
              }

              
      //計(jì)算知識(shí)點(diǎn)覆蓋率及適應(yīng)度
              unitList = GetKPCoverage(unitList, paper);
              unitList 
      = GetAdaptationDegree(unitList, paper, kpcoverage, difficulty);

              
      return unitList;

          } 

      2、計(jì)算種群個(gè)體的適應(yīng)度

            在上面的代碼中最后調(diào)用了兩個(gè)方法,GetKPCoverage跟GetAdaptationDegree,這兩個(gè)方法分別是計(jì)算種群中個(gè)體的知識(shí)點(diǎn)覆蓋率跟適應(yīng)度。

            關(guān)于種群個(gè)體的知識(shí)點(diǎn)覆蓋率在上一篇文章中已經(jīng)說過了(知識(shí)點(diǎn)分布用一個(gè)個(gè)體知識(shí)點(diǎn)的覆蓋率來衡量,例如期望本試卷包含N個(gè)知識(shí)點(diǎn),而一個(gè)個(gè)體中所有題目知識(shí)點(diǎn)的并集中包含M個(gè)(M<=N),則知識(shí)點(diǎn)的覆蓋率為M/N。),具體算法如下: 

          /// <summary>

          /// 計(jì)算知識(shí)點(diǎn)覆蓋率
          
      /// </summary>
          
      /// <param name="unitList">種群</param>
          
      /// <param name="paper">期望試卷</param>
          
      /// <returns>List</returns>
          public List<Unit> GetKPCoverage(List<Unit> unitList, Paper paper)
          {
              List
      <int> kp;
              
      for (int i = 0; i < unitList.Count; i++)
              {
                  kp 
      = new List<int>();
                  unitList[i].ProblemList.ForEach(
      delegate(Problem p)
                  {
                      kp.AddRange(p.Points);
                  });

                  
      //個(gè)體所有題目知識(shí)點(diǎn)并集跟期望試卷知識(shí)點(diǎn)交集
                  var common = kp.Intersect(paper.Points);
                  unitList[i].KPCoverage 
      = common.Count() * 1.00 / paper.Points.Count;
              }
              
      return unitList;
          }

            適應(yīng)度方法的確定上一篇文章里已經(jīng)說過,即:

      f=1-(1-M/N)*f1-|EP-P|*f2 

            其中M/N為知識(shí)點(diǎn)覆蓋率,EP為期望難度系數(shù),P為種群個(gè)體難度系數(shù),f1為知識(shí)點(diǎn)分布的權(quán)重,f2為難度系數(shù)所占權(quán)重。當(dāng)f1=0時(shí)退化為只限制試題難度系數(shù),當(dāng)f2=0時(shí)退化為只限制知識(shí)點(diǎn)分布。 實(shí)現(xiàn)代碼如下:

          /// <summary>

          /// 計(jì)算種群適應(yīng)度
          
      /// </summary>
          
      /// <param name="unitList">種群</param>
          
      /// <param name="paper">期望試卷</param>
          
      /// <param name="KPCoverage">知識(shí)點(diǎn)分布在適應(yīng)度計(jì)算中所占權(quán)重</param>
          
      /// <param name="Difficulty">試卷難度系數(shù)在適應(yīng)度計(jì)算中所占權(quán)重</param>
          
      /// <returns>List</returns>
          public List<Unit> GetAdaptationDegree(List<Unit> unitList, Paper paper, double KPCoverage, double Difficulty)
          {
              unitList 
      = GetKPCoverage(unitList, paper);
              
      for (int i = 0; i < unitList.Count; i++)
              {
                  unitList[i].AdaptationDegree 
      = 1 - (1 - unitList[i].KPCoverage) * KPCoverage - Math.Abs(unitList[i].Difficulty - paper.Difficulty) * Difficulty;
              }
              
      return unitList;
          }

      3、選擇算子

            這里選擇算子采用輪盤賭選擇法,即適應(yīng)度越大的被選擇到的概率越大。比如說種群中有20個(gè)個(gè)體,那么每個(gè)個(gè)體的適應(yīng)度除以20個(gè)個(gè)體適應(yīng)度的和得到的就是該個(gè)體的被選擇的概率。輪盤賭選擇時(shí),每個(gè)個(gè)體類似于輪盤中的一小塊扇形,扇形的大小與該個(gè)體被選擇的概率成正比。那么,扇形越大的個(gè)體被選擇的概率越大。這就是輪盤賭選擇法。 算法實(shí)現(xiàn)代碼如下:

          /// <summary>
          
      /// 選擇算子(輪盤賭選擇)
          
      /// </summary>
          
      /// <param name="unitList">種群</param>
          
      /// <param name="count">選擇次數(shù)</param>
          
      /// <returns>進(jìn)入下一代的種群</returns>
          public List<Unit> Select(List<Unit> unitList, int count)
          {
              List
      <Unit> selectedUnitList = new List<Unit>();

              
      //種群個(gè)體適應(yīng)度和
              double AllAdaptationDegree = 0;
              unitList.ForEach(
      delegate(Unit u)
              {
                  AllAdaptationDegree 
      += u.AdaptationDegree;
              });

              Random rand 
      = new Random();
              
      while (selectedUnitList.Count != count)
              {
                  
      //選擇一個(gè)0—1的隨機(jī)數(shù)字
                  double degree = 0.00;
                  
      double randDegree = rand.Next(1100* 0.01 * AllAdaptationDegree;

                  
      //選擇符合要求的個(gè)體
                  for (int j = 0; j < unitList.Count; j++)
                  {
                      degree 
      += unitList[j].AdaptationDegree;
                      
      if (degree >= randDegree)
                      {
                          
      //不重復(fù)選擇
                          if (!selectedUnitList.Contains(unitList[j]))
                          {
                              selectedUnitList.Add(unitList[j]);
                          }
                          
      break;
                      }
                  }
              }
              
      return selectedUnitList;

          } 

       4、交叉算子

            交叉算子在上一篇也做了說明,寫程序時(shí)為方便略做了一點(diǎn)更改,即把多點(diǎn)交叉改為單點(diǎn)交叉。在交叉過程在有幾個(gè)地方需要注意,一是要保正總分不變,二是保證交叉后沒有重復(fù)個(gè)體,算法實(shí)現(xiàn)如下:

          /// <summary>

          /// 交叉算子
          
      /// </summary>
          
      /// <param name="unitList">種群</param>
          
      /// <param name="count">交叉后產(chǎn)生的新種群個(gè)體數(shù)量</param>
          
      /// <param name="paper">期望試卷</param>
          
      /// <returns>List</returns>
          public List<Unit> Cross(List<Unit> unitList, int count, Paper paper)
          {
              List
      <Unit> crossedUnitList = new List<Unit>();
              Random rand 
      = new Random();
              
      while (crossedUnitList.Count != count)
              {
                  
      //隨機(jī)選擇兩個(gè)個(gè)體
                  int indexOne = rand.Next(0, unitList.Count);
                  
      int indexTwo = rand.Next(0, unitList.Count);
                  Unit unitOne;
                  Unit unitTwo;
                  
      if (indexOne != indexTwo)
                  {
                      unitOne 
      = unitList[indexOne];
                      unitTwo 
      = unitList[indexTwo];

                      
      //隨機(jī)選擇一個(gè)交叉位置
                      int crossPosition = rand.Next(0, unitOne.ProblemCount - 2);

                      
      //保證交叉的題目分?jǐn)?shù)合相同
                      double scoreOne = unitOne.ProblemList[crossPosition].Score + unitOne.ProblemList[crossPosition + 1].Score;
                      
      double scoreTwo = unitTwo.ProblemList[crossPosition].Score + unitTwo.ProblemList[crossPosition + 1].Score;
                      
      if (scoreOne == scoreTwo)
                      {
                          
      //兩個(gè)新個(gè)體
                          Unit unitNewOne = new Unit();
                          unitNewOne.ProblemList.AddRange(unitOne.ProblemList);
                          Unit unitNewTwo 
      = new Unit();
                          unitNewTwo.ProblemList.AddRange(unitTwo.ProblemList);

                          
      //交換交叉位置后面兩道題
                          for (int i = crossPosition; i < crossPosition + 2; i++)
                          {
                              unitNewOne.ProblemList[i] 
      = new Problem(unitTwo.ProblemList[i]);
                              unitNewTwo.ProblemList[i] 
      = new Problem(unitOne.ProblemList[i]);
                          }

                          
      //添加到新種群集合中
                          unitNewOne.ID = crossedUnitList.Count;
                          unitNewTwo.ID 
      = unitNewOne.ID + 1;
                          
      if (crossedUnitList.Count < count)
                          {
                              crossedUnitList.Add(unitNewOne);
                          }
                          
      if (crossedUnitList.Count < count)
                          {
                              crossedUnitList.Add(unitNewTwo);
                          }

                      }
                  }

                  
      //過濾重復(fù)個(gè)體
                  crossedUnitList = crossedUnitList.Distinct(new ProblemComparer()).ToList();
              }

              
      //計(jì)算知識(shí)點(diǎn)覆蓋率及適應(yīng)度
              crossedUnitList = GetKPCoverage(crossedUnitList, paper);
              crossedUnitList 
      = GetAdaptationDegree(crossedUnitList, paper, kpcoverage, difficulty);

              
      return crossedUnitList;
          }

            上面過濾重復(fù)個(gè)體中用到了ProblemComparer類,這是一個(gè)自定義的比較類,代碼如下:

       public class ProblemComparer : IEqualityComparer<Unit>

      {
          public bool Equals(Unit x, Unit y)
          {
              
      bool result = true;
              
      for (int i = 0; i < x.ProblemList.Count; i++)
              {
                  
      if (x.ProblemList[i].ID != y.ProblemList[i].ID)
                  {
                      result 
      = false;
                      
      break;
                  }
              }
              
      return result;
          }
          
      public int GetHashCode(Unit obj)
          {
              
      return obj.ToString().GetHashCode();
          }
      }

      5、 變異算子

            在變異過程中主要是要保證替換題目至少包含一個(gè)被替換題的有效知識(shí)點(diǎn)(期望試卷中也包含此知識(shí)點(diǎn)),并要類型相同,分?jǐn)?shù)相同而題號(hào)不同。 算法實(shí)現(xiàn)代碼如下:

          /// <summary>
          
      /// 變異算子
          
      /// </summary>
          
      /// <param name="unitList">種群</param>
          
      /// <param name="problemList">題庫(kù)</param>
          
      /// <param name="paper">期望試卷</param>
          
      /// <returns>List</returns>
          public List<Unit> Change(List<Unit> unitList, List<Problem> problemList, Paper paper)
          {
              Random rand 
      = new Random();
              
      int index = 0;
              unitList.ForEach(
      delegate(Unit u)
              {
                  
      //隨機(jī)選擇一道題
                  index = rand.Next(0, u.ProblemList.Count);
                  Problem temp 
      = u.ProblemList[index];

                  
      //得到這道題的知識(shí)點(diǎn)
                  Problem problem = new Problem();
                  
      for (int i = 0; i < temp.Points.Count; i++)
                  {
                      
      if (paper.Points.Contains(temp.Points[i]))
                      {
                          problem.Points.Add(temp.Points[i]);
                      }
                  }

                  
      //從數(shù)據(jù)庫(kù)中選擇包含此題有效知識(shí)點(diǎn)的同類型同分?jǐn)?shù)不同題號(hào)試題
                  var otherDB = from a in problemList
                                
      where a.Points.Intersect(problem.Points).Count() > 0
                                select a;

                  List
      <Problem> smallDB = otherDB.Where(p => IsContain(paper, p)).Where(o => o.Score == temp.Score && o.Type == temp.Type && o.ID != temp.ID).ToList();

                  
      //從符合要求的試題中隨機(jī)選一題替換
                  if (smallDB.Count > 0)
                  {
                      
      int changeIndex = rand.Next(0, smallDB.Count);
                      u.ProblemList[index] 
      = smallDB[changeIndex];
                  }
              });

              
      //計(jì)算知識(shí)點(diǎn)覆蓋率跟適應(yīng)度
              unitList = GetKPCoverage(unitList, paper);
              unitList 
      = GetAdaptationDegree(unitList, paper, kpcoverage, difficulty);
              
      return unitList;

          } 

      6、調(diào)用示例

            遺傳算法主要算法上面都已實(shí)現(xiàn),現(xiàn)在就是調(diào)用了。調(diào)用過程按如下流程圖進(jìn)行:

       

       基于遺傳算法的自動(dòng)組卷系統(tǒng)流程圖

            這里初始種群大小設(shè)定為20,最大迭代次數(shù)為500,適應(yīng)度為0.98,選擇算子選擇次數(shù)為10次,交叉算子產(chǎn)生的個(gè)體數(shù)量為20,期望試卷難度系數(shù)為0.72,總分為100分,各種題型題數(shù)為:20(單選), 5(多選), 10(判斷), 7(填空), 5(問答),包含的知識(shí)點(diǎn)為:1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81。代碼如下:

          /// <summary>
          
      /// 調(diào)用示例
          
      /// </summary>
          public void Show()
          {
              
      //題庫(kù)
              DB db = new DB();

              
      //期望試卷
              Paper paper = new Paper()
              {
                  ID 
      = 1,
                  TotalScore 
      = 100,
                  Difficulty 
      = 0.72,
                  Points 
      = new List<int>() { 13579111315171921232527293133353739414345474951535557596163656769717375777981 },
                  EachTypeCount 
      = new[] { 2051075 }
              };

              
      //迭代次數(shù)計(jì)數(shù)器
              int count = 1;

              
      //適應(yīng)度期望值
              double expand = 0.98;

              
      //最大迭代次數(shù)
              int runCount = 500;

              
      //初始化種群
              List<Unit> unitList = CSZQ(20, paper, db.ProblemDB);
              Console.WriteLine(
      "\n\n      -------遺傳算法組卷系統(tǒng)(http://www.rzrgm.cn/durongjian/)---------\n\n");
              Console.WriteLine(
      "初始種群:");
              ShowUnit(unitList);
              Console.WriteLine(
      "-----------------------迭代開始------------------------");

              
      //開始迭代
              while (!IsEnd(unitList, expand))
              {
                  Console.WriteLine(
      "在第 " + (count+++ " 代未得到結(jié)果");
                  
      if (count > runCount)
                  {
                      Console.WriteLine(
      "計(jì)算 " + runCount + " 代仍沒有結(jié)果,請(qǐng)重新設(shè)計(jì)條件!");
                      
      break;
                  }

                  
      //選擇
                  unitList = Select(unitList, 10);

                  
      //交叉
                  unitList = Cross(unitList, 20, paper);

                  
      //是否可以結(jié)束(有符合要求試卷即可結(jié)束)
                  if (IsEnd(unitList, expand))
                  {
                      
      break;
                  }

                  
      //變異
                  unitList = Change(unitList, db.ProblemDB, paper);
              }
              
      if (count <= runCount)
              {
                  Console.WriteLine(
      "在第 " + count + " 代得到結(jié)果,結(jié)果為:\n");
                  Console.WriteLine(
      "期望試卷難度:" + paper.Difficulty + "\n");
                  ShowResult(unitList, expand);
              }

          } 

            最后在控制臺(tái)中調(diào)用此方法即可。 

      7、其他輔助方法

            在上面的代碼中還調(diào)用了幾個(gè)輔助方法,下面一并給出:

          #region 是否達(dá)到目標(biāo)
          
      /// <summary>
          
      /// 是否達(dá)到目標(biāo)
          
      /// </summary>
          
      /// <param name="unitList">種群</param>
          
      /// <param name="endcondition">結(jié)束條件(適應(yīng)度要求)</param>
          
      /// <returns>bool</returns>
          public bool IsEnd(List<Unit> unitList, double endcondition)
          {
              
      if (unitList.Count > 0)
              {
                  
      for (int i = 0; i < unitList.Count; i++)
                  {
                      
      if (unitList[i].AdaptationDegree >= endcondition)
                      {
                          
      return true;
                      }
                  }
              }
              
      return false;
          }
          
      #endregion

          
      #region 顯示結(jié)果
          
      /// <summary>
          
      /// 顯示結(jié)果
          
      /// </summary>
          
      /// <param name="unitList">種群</param>
          
      /// <param name="expand">期望適應(yīng)度</param>
          public void ShowResult(List<Unit> unitList, double expand)
          {
              unitList.OrderBy(o 
      => o.ID).ToList().ForEach(delegate(Unit u)
              {
                  
      if (u.AdaptationDegree >= expand)
                  {
                      Console.WriteLine(
      "" + u.ID + "套:");
                      Console.WriteLine(
      "題目數(shù)量\t知識(shí)點(diǎn)分布\t難度系數(shù)\t適應(yīng)度");
                      Console.WriteLine(u.ProblemCount 
      + "\t\t" + u.KPCoverage.ToString("f2"+ "\t\t" + u.Difficulty.ToString("f2"+ "\t\t" + u.AdaptationDegree.ToString("f2")+"\n\n");
                  }
              });
          }
          
      #endregion

          
      #region 顯示種群個(gè)體題目編號(hào)
          
      /// <summary>
          
      /// 顯示種群個(gè)體題目編號(hào)
          
      /// </summary>
          
      /// <param name="u">種群個(gè)體</param>
          public void ShowUnit(Unit u)
          {
              Console.WriteLine(
      "編號(hào)\t知識(shí)點(diǎn)分布\t難度系數(shù)");
              Console.WriteLine(u.ID 
      + "\t" + u.KPCoverage.ToString("f2"+ "\t\t" + u.Difficulty.ToString("f2"));
              u.ProblemList.ForEach(
      delegate(Problem p)
              {
                  Console.Write(p.ID 
      + "\t");
              });
              Console.WriteLine();
          }

          #endregion 

            經(jīng)園友提醒,少了一個(gè)方法,這里補(bǔ)上:

          #region 題目知識(shí)點(diǎn)是否符合試卷要求
          
      /// <summary>
          
      /// 題目知識(shí)點(diǎn)是否符合試卷要求
          
      /// </summary>
          
      /// <param name="paper">期望試卷</param>
          
      /// <param name="problem">一首試題</param>
          
      /// <returns>bool</returns>
          private bool IsContain(Paper paper, Problem problem)
          {
              
      for (int i = 0; i < problem.Points.Count; i++)
              {
                  
      if (paper.Points.Contains(problem.Points[i]))
                  {
                      
      return true;
                  }
              }
              
      return false;
          }

          #endregion

       后記

            大功告成啦,運(yùn)行效果在文章開頭已經(jīng)給出。 當(dāng)然,由于題庫(kù)每次運(yùn)行都不同,因此每次運(yùn)行的結(jié)果也都不同。文中適應(yīng)度函數(shù)用的是線性的,也可以根據(jù)運(yùn)行情況進(jìn)行適當(dāng)調(diào)整,優(yōu)化,歡迎大家提出不同意見。

      posted @ 2011-05-20 18:27  artwl  閱讀(19239)  評(píng)論(98)    收藏  舉報(bào)

      個(gè)人簡(jiǎn)介

      var ME = {
      	"name": "土豆/Artwl",
      	"job": "coding",
      	"languages": [
      		"JS", "HTML",
                      "CSS", "jQuery"
      		"MVC",".NET",
      		"設(shè)計(jì)模式"
      	],
      	"hobby": [
      		"閱讀", "旅游",
      		"音樂", "電影"
      	]
      }
      
      TOP
      主站蜘蛛池模板: 人妻少妇久久久久久97人妻| 四虎精品视频永久免费| 国产熟女一区二区三区蜜臀| 日韩欧美视频一区二区三区| 鹤峰县| 日本三级香港三级人妇99| 日韩无专区精品中文字幕| 国产一卡2卡三卡4卡免费网站| 北岛玲亚洲一区二区三区| 人妻放荡乱h文| 国产精品自拍午夜福利| 亚洲热无码av一区二区东京热av| 亚洲国产成人无码av在线播放| 国产午夜福利在线视频| 在线欧美中文字幕农村电影| 亚洲成人av在线高清| 亚洲国产区男人本色| 成人国产精品中文字幕| 在线日韩日本国产亚洲| 根河市| 视频一区二区三区四区五区| 精品国产一区二区三区av性色| 婷婷成人丁香五月综合激情| 国产av亚洲精品ai换脸电影| 亚洲精品在线视频自拍| 免费高清特级毛片A片| 五级黄高潮片90分钟视频| 高清不卡一区二区三区| 国产一区二区三区不卡视频| 一个人免费观看WWW在线视频| 一区二区福利在线视频| 亚洲av伦理一区二区| 亚洲男女羞羞无遮挡久久丫| 色一情一区二区三区四区| 欧美日韩精品一区二区在线观看 | 18国产午夜福利一二区| 国产好大好硬好爽免费不卡| 新田县| julia无码中文字幕一区| 免费无码观看的AV在线播放| 国产美女在线精品免费观看|