zoukankan      html  css  js  c++  java
  • (转)遗传算法实现自动组卷、随机抽题

    原文:http://www.cnblogs.com/huangcong/archive/2010/10/29/1864772.html

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

    下面的图是运行结果:

    版权说明:作者:张颖希PocketZ's Blog
    出处:http://www.cnblogs.com/PocketZ
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    若本文为翻译内容,目的为练习英文水平,如有雷同,纯属意外!有不妥之处,欢迎拍砖

  • 相关阅读:
    责任链简单解析
    mysql实践一:SQL基础
    Aix6.1下su命令不能切换环境变量的问题
    maven 打包错误 Cannot access central in offline mode
    登陆并访问k8s的apiserver
    kubernetes 实践五:Service详解
    kubernetes1.16 配置 metrics-server
    kubernetes 实践四:Pod详解
    kubernetes 实践三:使用kubeadm安装k8s1.16.0
    kubernetes 实践二:kubectl命令使用
  • 原文地址:https://www.cnblogs.com/PocketZ/p/1865233.html
Copyright © 2011-2022 走看看