在题库题目数量增多时,抽题组卷可能会导致速度下降,所以使用自适应遗传算法
当题库中题目数量增多保证抽题速度:
–遗传算法是根据自然法则从群体中选择适应性更大的个体,从而得到最优解,具有自组织、自适应和自学习等智能特征。
–出题时可以考虑难度覆盖度、难度、题目的曝光度不断地调整从题库中抽取的题目。使得每道题目出现的次数、抽取的题目难度更加稳定
(1)初始化群体:随机产生一组介于最小题号和最大鹰 号之间的题号作为染色体,将所有的染色体不经编码直接联 系在一起,构成一个个体。
(2)确定适应函数:将试题的难度系数与该题型的期望
(3)根据相对适应度,使用标准转盘式选择策略从当代中选取两个个体
(4)按概率对选出的两个父体进行杂交操作
(5)利用自适应概率对两个child进行变异操作
/**
* 遗传算法进行组卷
*
* @return
*/
@SuppressWarnings("unchecked")
public List<QuestionDTO> autoPaper(int question_category,int level) throws Exception {
// HttpServletRequest request = ServletActionContext.getRequest();
Logger logger = Logger.getRootLogger();
long start = System.currentTimeMillis();
int userType = 10;// 用户选择的category 每次出10道题
// 生成存放相应题型的List,存放从数据库中选择的数据
//List<QuestionDTO> typeName = questionDao.selectQuestion_category(question_category);// typeName 中存从数据库中取出的category的所有试题
List<QuestionDTO> typeName;
if (question_category==1)
typeName = questionDao.selectQuestion_life();
else if (question_category==2)
typeName = questionDao.selectQuestion_literature();
else
typeName = questionDao.selectQuestion_video();
// 计算被选中的category共有多少道题(数据库中的)
int questionCount = typeName.size();//数据库category对应的试题总数。
//int level = Integer.parseInt(difficulty);
int popNum = Data.POP_NUM;// 初始种群数
Individual[] population = new Individual[popNum]; // 存入染色体
double maxFitness = 0;
for (int i = 0; i < popNum; i++) {// 初始化染色体组
// 生成一个染色体;
Individual ind = new Individual(typeName, questionCount, userType, level);
population[i] = ind;
if (maxFitness < ind.getFitness()) {
maxFitness = ind.getFitness();
}
}
// 计算相对适应度Pi
// logger.info("maxFitness" + maxFitness + "-----++++++++++++----");
Utility.calcPi(popNum, population, maxFitness);
// 通过选择算子,选择出两个染色体进行交叉
int finalPopNum = Data.FINAL_POP_NUM;
Individual[] finalPopulation = new Individual[finalPopNum]; // 存放被选择出的染色体
for (int i = 0; i < finalPopNum; i++) {
finalPopulation[i] = Utility.selection(population);// 可能会有一样的染色体
}
int tt = 0;// 控制循环总次数
double minFit = 20.0;
Individual bestInd = new Individual();
do {
// 交叉操作
Utility.crossover(finalPopulation);
// 变异操作
// Utility.mutation(finalPopulation, questionCount, userType);
// 调整被初始化的染色体,并计算Fitness
for (int i = 0; i < finalPopNum; i++) {
Individual ind = finalPopulation[i];
ind.resetIndiWithChro(typeName, questionCount, userType,level);
double tmpFit = ind.getFitness();
if (tmpFit < minFit) {
minFit = tmpFit;
bestInd = (Individual)finalPopulation[i].deepClone();
System.out.println("这个执行了。。。。。。。。。。。。。");
logger.info("最优解:-----------:"
+ bestInd.calcualateFitness(level));
logger.info("和最优解得一样------------:"
+ finalPopulation[i].calcualateFitness(level));
}
}
logger.info("aaaaaaaaaaaaaaaaaaaaa\n"
+ bestInd.calcualateFitness(level));
logger.info(tt + "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
tt++;
} while (tt != 200);
logger.info("以下是最优解:");
bestInd.resetIndiWithChro(typeName, questionCount, userType,level);
double f = bestInd.calcualateFitness(level);
logger.info("fintess:" + f);
logger.info("minFit:" + minFit + "$$");
//把最优解持久化
List<QuestionDTO> qList = bestInd.getList();//最终出的题
long end = System.currentTimeMillis();
return qList;
}
}