• 黄聪:遗传算法实现自动组卷、随机抽题


    using System;
    using System.Windows.Forms;
    using System.IO;

    namespace GA
    {
    public partial class Form1 : Form
    {
    TTm[] TP;
    int _ts = 0;
    int n = 10;
    int m = 12;
    int Pc = 50; //杂交的概率
    int Pm = 80; //变异的概率
    decimal _nd = 2;
    int[] Fs = { 2, 2, 2, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 15, 20, 20, 20, 20 }; //题目分数
    int[] Nd = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5 }; //题目难度
    public Form1()
    {
    InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    n
    = Fs.Length;
    m
    = Fs.Length;
    TP
    = new TTm[n];
    var P
    = TP;
    int E, t;
    for (int i = 0; i < n; i++)
    {
    P[i].T
    = new KT[m];
    }
    Initialize(P);
    if (!textBox4.Text.Equals(""))
    _nd
    = decimal.Parse(textBox4.Text);
    t
    = 0;
    E
    = Evaluate(P);
    decimal _result = 0;
    while (P[E].f < 100 || _ts < 12 || Math.Round((decimal)P[E].nd / _ts, 2) < _nd) //分数小于100或者题数小于12或者难度小于2继续循环
    {
    Crossover(P);
    //杂交
    Mutation(P);//变异
    E = Evaluate(P);//评估种群
    t = t + 1;
    textBox1.Text
    = t.ToString();
    textBox2.Text
    = P[E].f.ToString();
    Print(P[E]);
    //输出
    if (_ts != 0)
    {
    _result
    = Math.Round((decimal)P[E].nd / _ts, 2);
    textBox4.Text
    = _result.ToString();//(P[E].nd /_ts)
    }
    Application.DoEvents();
    //使程序响应事件,避免假死无法退出现象
    if (P[E].f == 100 && _ts >= 12 && _result >= _nd) //总分等于100并且题数大于等于12并且难度系数大于等于2停止循环
    {
    _ts
    = 0;
    break;
    }
    Select(P);
    //择优
    }
    }

    /// <summary>
    /// 初始化种群
    /// </summary>
    /// <param name="P"></param>
    private void Initialize(TTm[] P)
    {
    int i, j, G;
    for (i = 0; i < n; i++)
    {
    for (j = 0; j < m; j++)
    {
    P[i].T[j].Fs
    = Fs[j];
    P[i].T[j].nd
    = Nd[j];
    P[i].T[j].Se
    = 0;
    }
    }
    Random rnd
    = new Random();
    int temp = rnd.Next(m);
    for (i = 0; i < n; i++)
    {
    G
    = 0;
    while (Math.Abs(G - 105) > 10 && G < 130)
    {
    if (P[i].T[temp].Se == 0)
    {
    P[i].T[temp].Se
    = 1;
    G
    = G + P[i].T[temp].Fs;
    P[i].T[temp].Se
    = 0;
    }
    }
    }

    }

    /// <summary>
    /// 评估种群
    /// </summary>
    /// <param name="P"></param>
    private int Evaluate(TTm[] P)
    {
    int i, j, G, D = 0, result = 0;
    for (i = 0; i < n; i++)
    {
    G
    = 0;
    for (j = 0; j < m; j++)
    {
    if (P[i].T[j].Se == 1)
    {
    G
    = G + P[i].T[j].Fs;
    D
    = D + P[i].T[j].nd;
    }
    }
    P[i].f
    = 100 - Math.Abs(G - 100);
    P[i].nd
    = D;
    if (P[i].f > P[result].f && P[i].nd > P[result].nd)
    result
    = i;
    }
    return result;
    }

    /// <summary>
    /// 杂交
    /// </summary>
    /// <param name="P"></param>
    private void Crossover(TTm[] P)
    {
    int i = 0, j = 1, k, t;
    Random rnd
    = new Random();
    while (i < n - 1)
    {
    if (rnd.Next(101) > Pc)
    {
    //for (k = rnd.Next(m); k < m; k++)//一点杂交
    for (k = rnd.Next(m); k <= rnd.Next(m); k++)//两点杂交
    {
    t
    = P[i].T[k].Se;
    P[i].T[k].Se
    = P[j].T[k].Se;
    P[j].T[k].Se
    = t;
    }
    }
    i
    += 2; j += 1;
    }
    }

    /// <summary>
    /// 变异
    /// </summary>
    /// <param name="P"></param>
    private void Mutation(TTm[] P)
    {
    int i;
    Random rnd
    = new Random();
    for (i = 0; i < n; i++)
    {
    if (rnd.Next(101) > Pm)
    {
    P[i].T[rnd.Next(m)].Se
    = Convert.ToInt32(!Convert.ToBoolean(P[i].T[rnd.Next(m)].Se));
    }
    }
    }

    /// <summary>
    /// 择优
    /// </summary>
    /// <param name="P"></param>
    private void Select(TTm[] P)
    {
    int i, j;
    TTm Tm;
    for (i = 0; i < n - 1; i++) //对种群按优劣排序
    {
    for (j = i + 1; j < n; j++)
    {
    if (P[i].f > P[j].f)
    {
    Tm
    = P[i];
    P[i]
    = P[j];
    P[j]
    = Tm;
    }
    }
    }
    for (i = 0; i <= (n - 1) / 2; i++) //淘汰50%劣等品种
    {
    P[n
    - 1 - i] = P[i];
    }
    }

    /// <summary>
    /// 输出
    /// </summary>
    /// <param name="Tm"></param>
    private void Print(TTm Tm)
    {
    string s1, s2;
    int i;
    _ts
    = 0;
    s1
    = "题号:";
    s2
    = "分值:";
    for (i = 0; i < m; i++)
    {
    if (Tm.T[i].Se == 1)
    {
    s1
    = s1 + (i+1) + " ";
    s2
    = s2 + Tm.T[i].Fs + " ";
    _ts
    ++;
    }
    }
    textBox3.Text
    = s1 + "\r\n" + s2 + "\r\n题数:" + _ts;
    }
    }

    public struct KT
    {
    public int Fs;
    public int nd;
    public int Se;
    }

    public struct TTm
    {
    public KT[] T;
    public int f;
    public int nd;
    }
    }

    下面的图是运行结果:

  • 相关阅读:
    2009年度最佳jQuery插件
    转:Jeff Dean的Stanford演讲
    Zookeeper的RPC框架
    转:电商推荐技术
    NoSQL设计思想(从辅到主)
    工作一年小结
    转:MySQL索引背后的数据结构
    java多线程并发,java的几种状态
    转发:Linux Socket编程
    几个linux shell的讲解网站
  • 原文地址:https://www.cnblogs.com/huangcong/p/1864772.html
Copyright © 2020-2023  润新知