📄 form1.cs
字号:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
namespace tiku2
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.TextBox result_textBox;//显示结果基因
private System.Windows.Forms.TextBox hardlevel_textBox;//输入难度
private System.Windows.Forms.ListBox begin_listBox;//显示初始种群
private System.Windows.Forms.ListBox result_listBox;//显示结果
private System.Windows.Forms.ListBox beginfit_listBox;//显示初始种群适应度
OleDbConnection myConnection; //连接对象
OleDbDataAdapter myAdapter; //数据缓冲池
//OleDbCommand myCmd;
DataSet myDs; //数据记录集
DataTable myTable; //数据缓冲池里的表
DataRow myRow;//表里的一条记录
//int rownumber;
int[,] Gen=new int[100,29];//编码数组,100套初始试卷,每套29道题
int[,] Gen2=new int[100,29];//下一代基因编码数组,用于保存策略
Double begin_fit;//初始种群每个基因适应度寄存变量
Double[,] wheel=new double[100,3];
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button button2;//轮盘赌表数组
int[] G_temp=new int[50];//存放被选中作为父代的基因号,即Gen数组的行号
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
//////////////////////////////// 自定义函数
/// </summary>
/// <returns></returns>
public bool OpenDb()
{
//连接数据库函数
//连接字符串
String ConnectionString = @"User ID=sa;Data Source=FHQLPY;Tag with column collation when possible=False;Initial Catalog=tiku;Use Procedure for Prepare=1;Auto Translate=True;Persist Security Info=False;Provider=""SQLOLEDB.1"";Workstation ID=FHQLPY;Use Encryption for Data=False;Packet Size=4096";
//查询字符串
String SQLstr="";
//查询字符串实例化
SQLstr="select * from tmp03";
try
{
//新建连接
myConnection=new OleDbConnection(ConnectionString);
//打开连接
myConnection.Open();
//建立数据存储池
myAdapter=new OleDbDataAdapter(SQLstr,myConnection);
//建立数据集
myDs=new DataSet();
//填充数据集
myAdapter.Fill(myDs,"tmp03");
//取得表tmp03
myTable=myDs.Tables[0];
//设置行号(随即)
//rownumber=0;
//取得第一行
//myRow=myTable.Rows[rownumber];
//关闭连接
myConnection.Close();
}
catch(Exception e)
{
MessageBox.Show(e.ToString(),"wrong",MessageBoxButtons.OK);
return false;
}
return true;
}//openDb()
//计算知识点覆盖率函数f1
public Double fun_cover(int m)
{
Double sum=0; //此套题包含的知识点
int[] s=new int[100];//共有一百个知识点
int question_num; //题号,也是数据库中的记录号,即recd列
int flag=0; //知识点开始时无重复
int n=0; //s数组下标
for(int i=0;i<29;i++)
{
question_num=Gen[m,i];
myRow=myTable.Rows[question_num];
s[n]=Int32.Parse(myRow[9].ToString());//s数组判断重复,第九列是知识点列
for(int j=0;j<n;j++)
{
if(s[j]==s[n])
{
flag=1;//标识重复知识点
break;
}
}//for(j)
if(flag==0)
{
sum++;
n++;
}//if(!flag)
flag=0;
}//for(i)
return sum/71;//共七十一个知识点
}//fun_cover()函数
//平均难度适应度函数f2
public Double fun_hard(int m)
{
Double hard_level=0;//平均难度
Double sum=0;
int question_num;
for(int i=0;i<29;i++)
{
question_num=Gen[m,i];
myRow=myTable.Rows[question_num];
//**************取双精度数
sum+=Double.Parse(myRow[6].ToString())*Double.Parse(myRow[7].ToString());//d[i]*f[i]求和除以f[i]求和
}
hard_level=sum/100;//总分100
//返回平均难度和指定难度差的倒数
return 1/(Math.Abs(hard_level-Double.Parse(hardlevel_textBox.Text.ToString()))+0.1);
}//fun_hard()
//计算区分度适应度函数
public Double fun_diffi(int m)//m是Gen数组行标
{
Double sum=0;
int question_num;
for(int i=0;i<29;i++)
{
question_num=Gen[m,i];
myRow=myTable.Rows[question_num];
//**************C#取双精度数
sum+=Double.Parse(myRow[12].ToString())*Int32.Parse(myRow[7].ToString());//12是区分度列
}
return sum/100;
}//fun_diffi()
//适应度函数计算加权的适应度
public Double fit(int m)
{ Double w1=0.4,w2=0.2,w3=0.4;//权值
return w1*fun_cover(m)+w2*fun_hard(m)+w3*fun_diffi(m);
}//fit()
//随机选题函数
public void select(int tnum,int tendnum,int ku_star_num,int ku_end_num,int m)
{
int i,j,t,n=0;
//随机函数调用
Random ra=new Random(unchecked((int)DateTime.Now.Ticks));
int[] s=new int[20];//s数组防止选题重复
for(i=tnum;i<=tendnum;i++)
{
Loop:
//随机函数
t=ra.Next(ku_star_num,ku_end_num);
s[n]=t;
for(j=0;j<n;j++)
{
if(s[j]==s[n])//判断是否选过这道题
goto Loop;
}
n++;
Gen[m,i]=t;
}//for(i)
}//select()
//平均难度计算函数
public Double comput_hard_level(int m)
{
int question_num;
Double sum=0;
for(int i=0;i<29;i++)
{
question_num=Gen[m,i];
myRow=myTable.Rows[question_num];
//************C#中取出记录集中的整型数
sum=sum+Int32.Parse(myRow[6].ToString())*Int32.Parse(myRow[6].ToString());
}
return sum/100;//总分100分
}
//产生初始种群函数
public void make_begin_recordset()
{
Double hard_level;
int question_num;
//string[,] begin_view=new string[100,29];
for(int m=0;m<100;m++)
{
select(0,19,1,400,m);//选择题
select(20,24,401,500,m);//填空题
select(25,28,501,756,m);//解答题
hard_level=comput_hard_level(m);//计算平均难度
//*************将输入的文本转换成数字
//若难度不符合要求,则重选
if((Math.Abs(hard_level-Double.Parse(hardlevel_textBox.Text.ToString())))>1)
m--;
else
{
begin_fit=fit(m);
beginfit_listBox.Items.Add(begin_fit);//显示适应度
}
}
//显示初始种群
//*********************c#中使整型数正确输出
for(int i=0;i<100;i++)
{
for(int j=0;j<29;j++)
{
question_num=Gen[i,j];
myRow=myTable.Rows[question_num];
begin_listBox.Items.Add(Int32.Parse(Gen[i,j].ToString()));
}
begin_listBox.Items.Add(" ");//每个基因用空格格开
}
}//make_begin_recordset()
//生成轮盘函数
public void product_wheel()
{
Double sum=0;//适应度乘以概率积的和
Double[] p=new double[100];//概率
Random ra=new Random(unchecked((int)DateTime.Now.Ticks));
//Double test=0;测试变量
//生成轮盘表
for(int m=0;m<100;m++)
{
p[m]=ra.NextDouble();
sum=sum+fit(m)*p[m];
wheel[m,0]=m;
}
for(int m=0;m<100;m++)
{
wheel[m,1]=fit(m)*p[m]/sum;
}
wheel[0,2]=wheel[0,1];
for(int m=1;m<100;m++)
{
wheel[m,2]=wheel[m,1]+wheel[m-1,2];
}
/*测试用
* for(int m=0;m<100;m++)
test+=wheel[m,1];
hardlevel_textBox.Text=test.ToString();
测试用*/
}//product_wheel
//选择算子函数
public void choose_arithmetic_operators()
{
Double t;//随机生成数的存放变量
Random ra=new Random(unchecked((int)DateTime.Now.Ticks));
int j;//基因号存放变量
int flag=0;
int temp;//排序暂存变量
//要选择50个父代基因
for(int i=0;i<50;i++)
{
LOOP:
t=ra.NextDouble();
j=0;
//判断生成的随机数在轮盘哪个范围
while(j<100)//100个基因把轮盘分成100份,逐份查看
{
if(t>wheel[j,2]&&t<wheel[j+1,2])//在范围里
{
//检查是否有重复
for(int k=0;k<i;k++)
{
if(G_temp[k]==j)//若重复
{
flag=1;//标记
i--;//不能作为新的父代
goto LOOP;//重新生成随机数
}
}
if(flag==0)//没有重复
{
G_temp[i]=j;//j号基因入选
break;//不再查看在哪一范围
}//if(flag)
}//if(t)
//下一范围
j++;
}//while(j)
}//for(i)
//对G_temp数组里的元素排序(气泡,有待改进)
for(int i=0;i<49;i++)
for(j=i+1;j<50;j++)
{
if(G_temp[i]>G_temp[j])
{
temp=G_temp[i];
G_temp[i]=G_temp[j];
G_temp[j]=temp;
}
}
/*
* for(i=0;i<9;i++)
for(j=i+1;j<=9;j++)
if(a[i]>a[j])
{temp=a[i];a[i]=a[j];a[j]=temp;}
*/
//复制生成前50个下一代基因
for(int m=0;m<50;m++)
for(int i=0;i<29;i++)
Gen2[m,i]=Gen[G_temp[m],i];
}//choose_arithmetic_operators
//基因交叉杂交函数
public void cross()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -