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

    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 = { 2223335555555510101010151515151520202020 };  //题目分数
            int[] Nd = { 111111222222223333444445555 };  //题目难度
            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 + " " + s2 + " 题数:" + _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;
        }
    }

     

    下面的图是运行结果:

     

  • 相关阅读:
    吸烟的女人有着一种让人心动的美
    怎么样的女人让男人不变心
    姐妹们!一起来做狐狸精!
    清华图书馆机器人
    大地实习程序
    《非2》里的两首诗
    GIS拓扑生成
    一点小发现
    directX下的三维坐标系
    Let&#39;s start from here
  • 原文地址:https://www.cnblogs.com/this-543273659/p/3351857.html
Copyright © 2011-2022 走看看