1、试题库问题,0403201,问题描述,假设一个试题库中有n 道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算法。 数据输入:由文件input.txt 提供输入数据。文件第1 行有2 个正整数n 和k (2 =k= 20, k=n= 1000) k 表示题库中试题类型总数,n 表示题库中试题总数。第2 行有k 正整数,第i 个正整数表示要选出的类型i 的题数。这k 个数相加就是要选出的总题数m。接下来的n 行给出了题库中每个试题的类型信息。每行的第1 个正整数p 表明该题可以属于p 类,接着的
2、p 个数是该题所属的类型号。,输入输出示例,input.txt output.txt 3 15 1: 1 6 8 3 3 4 2: 7 9 10 2 1 2 3: 2 3 4 5 1 3 1 3 1 3 1 3 3 1 2 3 2 2 3 2 1 3 1 2 1 2 2 1 2 2 1 3 2 1 2 1 1 3 1 2 3,主要内容,算法描述 数据结构 预流推进策略 无解情况分析 实例演示,算法描述,采用预流推进算法 把n个题目,k个题型都在网络图上用顶点表示,增加两个虚拟的节点,源和汇。,源,1,2,1,3,2,4,n,汇,k,m,题型,题目,11,1,容量为题目给 定的该题型需 要的题目
3、数,数据结构,题型顶点结构 class Style public:int id;int cap;/该题型可以选择的题目数int flow;/该题型已经选择的题目数int sqNum;/该题型需要但未选择的题目数int inQueue;/是否在活顶点队列中int pri;/活顶点优先级Style(); ; 用数组q来存储所有题型节点 Question *q=new QuestionqSize+1; Qi存储id为i的结点,题目顶点结构 class Question public:int id;int sNum;bool used;/该题目是否以被某一个类型选中Question(); ; 用数组s
4、来存储所有题目节点 Style *s=new StylesSize+1; si存储id为i的结点,数据结构,题型题目边采用二维数组来存储边sq; Sqij=0表示题型顶点i与题目顶点j之间没有边 Sqij=1表示题型顶点i与题目顶点j之间有边 Sqij=2表示题型顶点i与题目顶点j之间的边有流经过 Sqij=3表示题型顶点i与题目顶点j之间的边曾有流经过,但最后流取消经过该边 活顶点优先队列 顶点:活顶点优先队列中存着等待流推进的题型顶点(题目顶点一成为活顶点就立刻进行流的推进,不需要队列来存储。) 优先级别:题型顶点的pri属性,初始值 si.pri=si.cap-si.sqNum; 初始化
5、时,将所有的题型顶点都添加进优先队列,优先队列采用最小堆实现,,预流推进策略,题型顶点选取题目顶点增流选取可以增流的顶点进行增流,如果已无可以增流的顶点(与该题型顶点连接的题目顶点都已经被用过了),选取一个顶点进行回流操作(一次只能对一条边回流,如果利用回流操作来增流仍不能满足流量平衡约束,则再次将该顶点加入优先队列。int ChooseQue(Style 题型顶点i选取一个顶点,对应的边进行增流,flow+,pri-,当回流操作选中该顶点sqNum+,pri-,无解情况分析,先天不足,要求题型i需要有t道题目,但是只有不到t个的题目属于i。解决方案:在从输入文件中输入数据的时候就可以进行统计
6、题型i的可选题目个数,当初始化优先队列时就可以判断出这种No Solution情况。 题目资源独占,题型选择冲突。可能存在两个题型都要求选择某题目,否则无法满足给定的题数要求。解决方案:设置一个变量flowback来统计回流边的个数,当flowback的值大于图的边的个数的时候,表示题目中可以增流的边都增流过了,但是仍旧没有找到解决方案,也就是存在独占冲突,于是就可以输出No Solution了。,实例演示,源,1,2,3,1,2,3,4,5,6,汇,2,2,2,1,1,1,1,1,1,3 6 2 2 2 2 1 2 1 3 1 2 1 1 2 2 3 3 1 2 3,6,源,1,2,3,1,
7、2,3,4,5,6,汇,1,1,1,1,1,1,1 3 2,PQ,6,实例演示,3 6 2 2 2 2 1 2 1 3 1 2 1 1 2 2 3 3 1 2 3,源,1,2,3,1,2,3,4,5,6,汇,2,2,2,1,1,1,1,1,1,3 2,PQ,6,实例演示,3 6 2 2 2 2 1 2 1 3 1 2 1 1 2 2 3 3 1 2 3,源,1,2,3,1,2,3,4,5,6,汇,2,2,2,1,1,1,1,1,1,2,PQ,3,6,实例演示,3 6 2 2 2 2 1 2 1 3 1 2 1 1 2 2 3 3 1 2 3,源,1,2,3,1,2,3,4,5,6,汇,2,2,2,1,1,1,1,1,1,3,3,PQ,2,5,6,实例演示,3 6 2 2 2 2 1 2 1 3 1 2 1 1 2 2 3 3 1 2 3,源,1,2,3,1,2,3,4,5,6,汇,2,2,2,1,1,1,1,1,1,3,优先队列为空,PQ,6,实例演示,3 6 2 2 2 2 1 2 1 3 1 2 1 1 2 2 3 3 1 2 3,1:1 4 2:3 5 3:2 6,输出,