项目描述
智能组卷平台(遗传算法)
分为3个端:管理员端,老师端,学生端
主要功能包括 登录,学生管理,老师管理,题目管理,试卷管理,
知识管理。任务管理,教育管理,试卷管理,批卷管理,
运行环境
jdk8+redis+mysql+IntelliJ IDEA+maven
项目技术
springboot+layui+vue
项目截图
老师端
学生端
部分代码
遗传算法的使用
/**
* 遗传算法
*/
public class GAUtil {
//编译概率
private static final double mutationRate = 0.085;
//精英主义
private static final boolean elitism = true;
//淘汰数组大小
private static final int tournamentSize = 5;
/**
* 种群进化
* @param pop 种群对象
* @param rule 进化规则
* @return
*/
public static Population evolvePopulation(Population pop, Rule rule,QuestionService questionService){
Population newPop = new Population(pop.getLength());
int elitismOffset;
//精英主义
if(elitism){
elitismOffset = 1;
//保留上一代最优秀的个体
ExamPaperAlgotithmBean fitness = pop.getFitness();
fitness.setId(0);
newPop.setPaper(0,fitness);
}
//种群交叉操作,从当前的种群pop来创建下一代种群newPop
for (int i = elitismOffset; i < newPop.getLength(); i++){
//得到两个较优选择
ExamPaperAlgotithmBean parent1 = select(pop);
ExamPaperAlgotithmBean parent2 = select(pop);
//保持连个选择不同
while (parent1.getId() == parent2.getId()){
parent2 = select(pop);
}
//交叉
ExamPaperAlgotithmBean child = crossover(parent1, parent2, rule,questionService);
child.setId(i);
newPop.setPaper(i,child);
}
//种群变异操作
ExamPaperAlgotithmBean tmpPeper;
for (int i = elitismOffset; i < newPop.getLength(); i++){
tmpPeper = newPop.getPaper(i);
mutate(tmpPeper,questionService);
//计算知识点覆盖率和适应度
tmpPeper.setChapterCoverage(rule);
tmpPeper.setAdaptationDegree(rule, ExamPaperWeightEnum.CHAPTER_WEIGHT,ExamPaperWeightEnum.DIFFICULTY_WEIGHT);
}
return newPop;
}
/**
* 选择算子:得到最优个体
* @param population
* @return
*/
public static ExamPaperAlgotithmBean select(Population population){
Population pop = new Population(tournamentSize);
for (int i = 0; i < tournamentSize; i++){
pop.setPaper(i,population.getPaper((int)(Math.random()*population.getLength())));
}
return pop.getFitness();
}
/**
* 交叉算子:
* @param parent1
* @param parent2
* @param rule
* @return
*/
public static ExamPaperAlgotithmBean crossover(ExamPaperAlgotithmBean parent1,ExamPaperAlgotithmBean parent2,Rule rule,QuestionService questionService){
ExamPaperAlgotithmBean child = new ExamPaperAlgotithmBean(parent1.getQuestionSize());
int s1 = (int) Math.random() * parent1.getQuestionSize();
int s2 = (int) Math.random() * parent1.getQuestionSize();
// parent1的startPos、endPos之间的序列,会被遗传到下一代
int startPos = s1 < s2 ? s1 : s2;
int endPos = s1 > s2 ? s1 : s2;
for (int i = startPos; i < endPos; i++){
child.saveQuestion(i,parent1.getQuestions().get(i));//parent1遗传给下一代的序列
}
List<Integer> chapterList = rule.getChapters();
for (int i = 0; i < startPos; i++){
if (!child.containsQuestion(parent2.getQuestions().get(i))){
child.saveQuestion(i,parent2.getQuestions().get(i));
}else {
//如果出现相同题目,重新查找一题题目类型、知识点相同的题目
Integer type = parent2.getQuestions().get(i).getQuestionType();
List<Question> questions = questionService.selectByLevelTypeChapters(type, chapterList);
child.saveQuestion(i,questions.get((int) Math.random()*questions.size()));
}
}
for (int i = endPos; i < parent2.getQuestionSize(); i++){
if (!child.containsQuestion(parent2.getQuestions().get(i))){
child.saveQuestion(i,parent2.getQuestions().get(i));
}else {
//如果出现相同题目,重新查找一题题目类型、知识点相同的题目
Integer type = parent2.getQuestions().get(i).getQuestionType();
List<Question> questions = questionService.selectByLevelTypeChapters(type, chapterList);
child.saveQuestion(i,questions.get((int) Math.random()*questions.size()));
}
}
return child;
}
/**
* 突变算子 每个个体的每个基因都有可能突变 每个基因变异的概率大概为0.085,小于等于时可以变异
* @param paper
*/
public static void mutate(ExamPaperAlgotithmBean paper,QuestionService questionService){
Question tmpQuestion;
List<Question> list;
int index;
for (int i = 0;i < paper.getQuestionSize(); i++){
if (Math.random() <= mutationRate){
//进行突变
tmpQuestion = paper.getQuestions().get(i);
//从题库中获取和变异的题目类型一样分数相同的的题目(不包含编译题目)
Integer type = paper.getQuestions().get(i).getQuestionType();
Integer chapterId = paper.getQuestions().get(i).getChapterId();
List<Integer> chapterIds = new ArrayList<>();
chapterIds.add(chapterId);
list = questionService.selectByLevelTypeChapters(type, chapterIds);
if (list.size() > 0){
index = (int) Math.random()*list.size();
paper.saveQuestion(i,list.get(index));
}
}
}
}
}
智能组卷
/**
* 随机生成试卷题目id列表
* @param model
* @param user
* @return
*/
private List<Integer> getRandomQuetionIds(ExamPaperAttrVM model, User user){ ;
List<Integer> errorIds = examPaperQuestionCustomerAnswerService.selectErrorIdList(user.getId());
ExamPaperQuestionsAttrVM questionsAttrVM = new ExamPaperQuestionsAttrVM(model.getSubjectId(), model.getDifficult(), errorIds);
List<Integer> newIds = questionMapper.selectNotErrorQuestionIds(questionsAttrVM);
Integer errorNum = model.getErrorQuestionNum();
Integer newNum = model.getNewQuestionNum();
List<Integer> ids = ExamUtil.randomNewErrorQuestionIds(errorNum, newNum, errorIds, newIds);
return ids;
}
/**
* 生成试卷请求编辑vo -- 用于生成试卷对象 -- 智能训练
* @param model
* @return
*/
@Override
public ExamPaperEditRequestVM getExamPaperEditRequestVM(ExamPaperAttrVM model){
User user = webContext.getCurrentUser();
List<Integer> Ids = getRandomQuetionIds(model,user);
List<Question> questions = questionService.selectQuestionsByIds(Ids);
String totalScore = ExamUtil.scoreToVM(questions.stream().mapToInt(q -> q.getScore()).sum());//试卷总分
List<Integer> qTypes = questions.stream().map(q ->
q.getQuestionType()).distinct().collect(Collectors.toList());//试卷所有类型题名(单选、多选..)
List<ExamPaperTitleItemVM> titleItems = qTypes.stream().map(qt -> {
List<Question> titleQuestions =
questions.stream().filter(q -> q.getQuestionType() == qt).collect(Collectors.toList());//试卷每个小标题下的题目列表
List<QuestionEditRequestVM> titleQuestionEditRequestVMs = titleQuestions.stream().map(q -> {
QuestionEditRequestVM titleQuestionEditRequestVM = questionService.getQuestionEditRequestVM(q);
return titleQuestionEditRequestVM;
}).collect(Collectors.toList());//将Quetion转换为vo对象
ExamPaperTitleItemVM examPaperTitleItemVM = new ExamPaperTitleItemVM();//生产试卷
examPaperTitleItemVM.setName(QuestionTypeEnum.fromCode(qt).getName());
examPaperTitleItemVM.setQuestionItems(titleQuestionEditRequestVMs);
return examPaperTitleItemVM;
}).collect(Collectors.toList());
ExamPaperEditRequestVM vm = new ExamPaperEditRequestVM();
vm.setName(ExamPaperTypeEnum.TelligentTrain.getName() + count.incrementAndGet());
vm.setLevel(user.getUserLevel());
vm.setSubjectId(model.getSubjectId());
vm.setScore(totalScore);
vm.setPaperType(ExamPaperTypeEnum.TelligentTrain.getCode());
vm.setSuggestTime(ExamUtil.getExamPaperSuggestTime(questions));
vm.setTitleItems(titleItems);
return vm;
}
/**
* 智能组卷
* @param model
* @return
*/
@Override
public ExamPaperEditRequestVM getExamPaperEditRequestVM(ExamPaperRuleVM model) {
User user = webContext.getCurrentUser();
ExamPaperEditRequestVM vm = getIntelligenceExamPaper(model, user, ExamPaperWeightEnum.runCount, ExamPaperWeightEnum.population_size, ExamPaperWeightEnum.expectAdapter);
return vm;
}
/**
* 智能组卷
* @param model
* @param user
* @param runCount
* @param populationSize
* @param expectAdapter
* @return
*/
private ExamPaperEditRequestVM getIntelligenceExamPaper(ExamPaperRuleVM model, User user, int runCount, int populationSize,double expectAdapter ){
Rule rule = getRuleFromVM(model);
if (rule == null){
throw new RuntimeException();
}
List<List<Question>> lists = getQuestionsByLevelAndChapters(rule.getChapters());
ExamPaperAlgotithmBean fitness = getFitnessFromPopulation(rule, lists, true, runCount, populationSize, expectAdapter);
List<Question> questions = fitness.getQuestions();
String totalScore = ExamUtil.scoreToVM(questions.stream().mapToInt(q -> q.getScore()).sum());
List<Integer> qTypes = questions.stream().map(q ->
q.getQuestionType()).distinct().collect(Collectors.toList());
List<ExamPaperTitleItemVM> titleItems = qTypes.stream().map(qt -> {
List<Question> titleQuestions =
questions.stream().filter(q -> q.getQuestionType() == qt).collect(Collectors.toList());
List<QuestionEditRequestVM> titleQuestionEditRequestVMs = titleQuestions.stream().map(q -> {
Chapter chapter = chapterMapper.selectByPrimaryKey(q.getChapterId());
TextContent textContent = textContentService.selectById(q.getInfoTextContentId());
QuestionObject questionObject = JsonUtil.toJsonObject(textContent.getContent(), QuestionObject.class);
QuestionEditRequestVM titleQuestionEditRequestVM = questionService.getQuestionEditRequestVM(q);
titleQuestionEditRequestVM.setTitle(questionObject.getTitleContent() + "(" + chapter.getName() + ")");
return titleQuestionEditRequestVM;
}).collect(Collectors.toList());//将Quetion转换为vo对象
ExamPaperTitleItemVM examPaperTitleItemVM = new ExamPaperTitleItemVM();//生产试卷
examPaperTitleItemVM.setName(QuestionTypeEnum.fromCode(qt).getName());
examPaperTitleItemVM.setQuestionItems(titleQuestionEditRequestVMs);
return examPaperTitleItemVM;
}).collect(Collectors.toList());
ExamPaperEditRequestVM vm = new ExamPaperEditRequestVM();
vm.setName(ExamPaperTypeEnum.TelligentExam.getName() + count.incrementAndGet());
vm.setLevel(user.getUserLevel());
vm.setSubjectId(model.getSubjectId());
vm.setScore(totalScore);
vm.setPaperType(ExamPaperTypeEnum.TelligentExam.getCode());
vm.setSuggestTime(ExamUtil.getExamPaperSuggestTime(questions));
vm.setTitleItems(titleItems);
return vm;
}
/**
* 得到不同类型题chapters知识点内的题目,然后添加到列表中
* @param chapters
* @return
*/
private List<List<Question>> getQuestionsByLevelAndChapters(List<Integer> chapters){
List<List<Question>> questions = new ArrayList<>(5);
for (int i = QuestionTypeEnum.SingleChoice.getCode();i <= QuestionTypeEnum.ShortAnswer.getCode(); i++){
questions.add(questionService.selectByLevelTypeChapters(i,chapters));
}
return questions;
}
private Rule getRuleFromVM(ExamPaperRuleVM model){
Rule rule = modelMapper.map(model, Rule.class);
double difficulty = rule.getDifficulty();
rule.setDifficulty(difficulty * 1.5 / 5);//不限、简单、中等、困难 * 1.5
Integer total = ExamUtil.getExpectTotalScore(rule);
rule.setTotalScore(total);
return rule;
}
/**
* 种群进化选出最优个体
* @param rule
* @param lists
* @param initFlag
* @param runCount
* @param populationSize
* @param expectAdapter
* @return
*/
private ExamPaperAlgotithmBean getFitnessFromPopulation(Rule rule,List<List<Question>> lists,boolean initFlag,int runCount,int populationSize,double expectAdapter){
int initCount = 0;
Population population = new Population(populationSize,true,rule,lists);
System.out.println("---------------------------------------");
int index = 0;
for (ExamPaperAlgotithmBean e: population.getPapers()){
System.out.println("个体:" + ++index + "适应度为:" + e.getAdaptationDegree() + "难度为:" + e.getDifficulty() + "知识点覆盖率为:" + e.getChapterCoverage());
}
System.out.println("初始适应度:" + population.getFitness().getAdaptationDegree());
while (initCount < runCount && population.getFitness().getAdaptationDegree() < expectAdapter){
initCount++;
GAUtil.evolvePopulation(population,rule,questionService);
System.out.println("第 " + initCount + " 次进化,适应度为:" + population.getFitness().getAdaptationDegree());
}
System.out.println("进化次数:" + initCount);
System.out.println(population.getFitness().getAdaptationDegree());
ExamPaperAlgotithmBean fitness = population.getFitness();
return fitness;
}
版权声明:本文为qq_2537071370原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。