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

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

下面的图是运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值