且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

遗传算法实现自动组卷、随机抽题

更新时间:2022-09-06 22:00:35

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)
{
= Fs.Length;
= 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);
= 0;
= 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);//变异
= Evaluate(P);//评估种群
= 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++)
{
= 0;
while (Math.Abs(G - 105> 10 && G < 130)
{
if (P[i].T[temp].Se == 0)
{
P[i].T[temp].Se 
= 1;
= 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++)
{
= 0;
for (j = 0; j < m; j++)
{
if (P[i].T[j].Se == 1)
{
= G + P[i].T[j].Fs;
= 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++)//两点杂交
{
= P[i].T[k].Se;
P[i].T[k].Se 
= P[j].T[k].Se;
P[j].T[k].Se 
= t;
}
}
+= 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;
}
}
遗传算法实现自动组卷、随机抽题

下面的图是运行结果:

遗传算法实现自动组卷、随机抽题




本文转自黄聪博客园博客,原文链接:http://www.cnblogs.com/huangcong/archive/2010/10/29/1864772.html,如需转载请自行联系原作者