1. 功能设计
-
自动组卷
根据设置的题型、题量、难度、考查的知识点等属性自动组合成一张试卷
难度可以选择简单、普通、困难
可以添加各种题库(章节)
在每个题库中可以输入每种题型的数量
以上面的选择为依据使用算法生成一张测试试卷
-
审核组卷
老师可对系统生成的试卷进行人工审核、修改、打印和存档
- 比如:删除题目、替换题目、审核通过自动生成的试卷、将试卷下载下来
- 安全性:只有老师或者管理员能使用该部分功能
2. 数据库设计
本部分涉及到的数据表有
-
题库表 repository
参数 类型 描述 非空 id varchar(64) 题库id 是 user_id varchar(64) 教师/超管id 是 title varchar(255) 题库标题 是 remark varchar(255) 题库描述 否 multi_count int(11) 多选题数量 是 judge_count int(11) 判断题数量 是 radio_count int(11) 单选题数量 是 saq_count int(11) 简答题数量 是 applied_count int(11) 应用题数量 是 aap_count int(11) 算法分析题数量 是 adp_count int(11) 算法设计题数量 是 create_time datetime 创建时间 是 update_time datetime 更新时间 是 -
试题表 question
参数 类型 描述 非空 id varchar(64) 试题id 是 user_id varchar(64) 教师/超管 id 是 question_type int(11) 题目类型,比如1:单选,2:多选 是 level int(11) 难度等级。比如:1 简单,2:普通,3:难 是 content varchar(2000) 题目内容 是 analysis varchar(2000) 整题解析 否 create_time datetime 创建时间 是 update_time datetime 更新时间 是 -
试题题库表 qu_repo
参数 类型 描述 非空 id varchar(64) 试题题库id 是 qu_id varchar(64) 试题id 是 repo_id varchar(64) 试题归属题库id 是 qu_type int(11) 题目类型 是 -
试题答案表 qu_answer
参数 类型 描述 非空 id varchar(64) 答案id 是 qu_id varchar(64) 试题id 是 is_right tinyint(3) 是否正确 0错误 1正确 是 1_content varchar(5000) 答案内容(单选,多选,判断) 是 analysis varchar(5000) 答案分析 否 2_content MEDIUMBLOB 答案内容(简答题,应用题,算法分析题,算法设计题) 是 -
试卷表 testpaper
参数 类型 描述 非空 id varchar(64) 试卷id 是 title varchar(64) 试卷标题,如:树章节测试 是 create_time datetime 创建时间 是 -
试卷题目表 testpapermx
参数 类型 描述 非空 id varchar(64) 试卷题目id 是 testpaper_id varchar(64) 试卷id 是 selected_qu varchar(64) 选择的题目id 是
3. 接口设计
智能组卷
-
功能说明
根据组卷算法生成一套试卷
-
接口说明
请求方式:POST
请求地址:http://ip:port/test/generateexamination
请求参数:ave_level,repository,*_count
-
请求参数
参数名 类型 说明 ave_level int(11) 试卷难度 repository Object 选择的题库 multi_selectedcount int(11) 输入的多选题数量 judge_selectedcount int(11) 输入的判断题数量 … -
返回参数
参数名 类型 说明 data Object 题目集合 status String 状态:1-成功,0-失败 httpCode String Http返回码 errCode String 错误码 errMessage String 错误信息 data:
参数名 类型 说明 testpaper_id varchar(64) 试卷id question List 题目集合
-
示例:
{ "status": 1, "data": { "testpaper_id", "question":{ "question{$num}":[ "qu_id", "question_type", "level", "content", "analysis", ], "question{$num}":[ "qu_id", "question_type", "level", "content", "analysis", ], ... } }, "httpCode": 200, "errCode": 0, "errMessage": "" }
4. 算法设计
准备使用遗传算法
/*遗传算法
* 入参:
* questionsDB题库
* expectedExam:期望试题
* 出参:
* TempExam resultUnit最终试题
* */
public TempExam geneticAlgorithm(List<Questions> questionsDB,TempExam expectedExam) {
//最终试题
TempExam resultUnit=null,resultUnitTemp=null;
//迭代次数计数器
int count=1;
//初始化种群
List<TempExam> unitList=generatePaperService.cszq(20, expectedExam, questionsDB);
resultUnitTemp=getMaxAdapterUnit(unitList);
System.out.println("----------------遗传算法组卷---------------------------------------");
System.out.println("初始种群-------------");
showUnit(unitList);
System.out.println("-----------------------开始迭代-------------------------");
boolean flag=false;
while(!generatePaperService.isEnd(unitList, Constants.EXPAND_ADATPER)) {
System.out.println("在"+(count++)+"代未得到结果----------"+unitList.size()+"------------------");
if(count>Constants.RUN_Count) {
System.out.println("计算"+Constants.RUN_Count+"代仍没有结果,请重新设置条件");
break;
}
//经过选择、交叉后种群数量只剩1或只剩0退出
if(unitList.size()<=1) {
System.out.println("没有结果");
flag=true;
break;
}
//选择--个数一定小于初始化种群
unitList=generatePaperService.select(unitList, 10);
//交叉
unitList=generatePaperService.cross(unitList, 20, expectedExam);
//判断是否可以结束
if(generatePaperService.isEnd(unitList, Constants.EXPAND_ADATPER)) {
break;
}
//变异
unitList=generatePaperService.change(unitList, questionsDB, expectedExam);
}
if(count<=Constants.RUN_Count&&flag==false) {
System.out.println("在第"+count+"代得到结果,结果为:**********************************");
System.out.println("期望难度系数:"+expectedExam.getDifficultyLevel());
showResult(unitList,Constants.EXPAND_ADATPER);
//如果有多个,取适应度最大的
if(unitList.size()>=1) {
resultUnit=getMaxAdapterUnit(unitList);
}
}else {
//没有得到结果,取初始群种中适应度最大的
resultUnit=resultUnitTemp;
}
//最终结果试题
System.out.println("------------------最终试题---------------------");
if(resultUnit!=null) {
System.out.println("试卷id:"+resultUnit.geteId());
System.out.println("题目数量\t知识点分布\t\t难度系数\t\t适应度");
System.out.println(resultUnit.getQuestionList().size()+"\t"+resultUnit.getKpCoverage()+"\t"+resultUnit.getDifficultyLevel()+"\t"+resultUnit.getAdapterDegree());
}
return resultUnit;
}