//简化版高校自动排课系统//排课任务简化后包含:年级专业(教学班级,如计科13)、课程名称、任课教师、上课地点和时间//教学班级简化为不分人数,不分专业方向。//上课教室简化为不分理论课、实验课,不分教室容纳人数,不分是否多媒体。//上课时段简化为:一周五天,周一到周五,白天上课,上午四节,下午四节,//1~2(8:00~9:400)、3~4(10:00~11:40)、5~6(14:00~15:40)、7~8(16:00~17:40)//为了便于处理,将五天的所有上课时段用数字0~19表示//上课地点和时间组合成一个整数数组(位集,bitset),每20个为1组为一个教室的上课时段安排//约束条件:1、教学班级的上课时间不能冲突//2、每个教室不能同时安排多个教学班级上课//3、任课教师的上课时间不能冲突//#includeiostream#includefstream#includesstream#includestring#includevector#includebitset#includerandom#includeiomanipusingnamespacestd;//原始数据文件中的每一行数据的数据结构structschedule{stringgrade_special;//年级专业stringcourse;//课程名称stringteacher;//任课教师stringtotal_hour;//总学时stringteach_hour;//讲课学时stringexperiment_hour;//实验学时stringpractice_hour;//课程实践学时stringcredit;//学分stringweek_hour;//周学时stringstart_stop;//起止周stringspeciality_orientation;//专业方向stringperson_num;//人数};//排课任务的数据结构structarrange{arrange(stringgs,stringc,stringt,intct=-1):grade_special(gs),course(c),teacher(t),classroom_time(ct){}stringgrade_special;//年级专业stringcourse;//课程名称stringteacher;//任课教师//stringclassroom;//上课地点//stringtime;//上课时间intclassroom_time;//上课地点、时间};//教师倒排表数据结构,通过教师姓名找到该教师的排课情况structteacher_inverted{teacher_inverted(stringtea,intcl=-1,intar=-1):teacher(tea),class_loc(cl),arrange_loc(ar){}stringteacher;intclass_loc;intarrange_loc;};//教室倒排表数据结构,通过教室名称查找该教室的排课情况structclassroom_inverted{classroom_inverted(stringcr,intcl=-1,intar=-1):classroom(cr),class_loc(cl),arrange_loc(ar){}stringclassroom;intclass_loc;intarrange_loc;};intmain(intargc,char**argv){if(argc!=3){cout程序调用格式错误!\n调用格式:csp排课计划文件可用教室文件\n;return0;}ifstreaminfile(argv[1]);vectorscheduleplan;strings;getline(infile,s);while(getline(infile,s)){schedulesch;istringstreamrecord(s);recordsch.grade_specialsch.coursesch.teachersch.total_hoursch.teach_hoursch.experiment_hoursch.practice_hoursch.creditsch.week_hoursch.start_stopsch.speciality_orientationsch.person_num;plan.push_back(sch);}infile.close();vectorvectorarrangearranges;//整个系的排课安排vectorarrangearr;//一个班的排课安排stringgs();//教学班级for(autoit=plan.begin();it!=plan.end();++it){if(gs!=it-grade_special){if(!arr.empty()){arranges.push_back(arr);//教学计划按教学班级顺序排列arr.clear();}gs=it-grade_special;}arr.push_back(arrange(it-grade_special,it-course,it-teacher));}arranges.push_back(arr);vectorvectorteacher_invertedteachers;//教师数组for(unsignedi=0;iarranges.size();++i){for(unsignedj=0;jarranges[i].size();++j){stringtea=arranges[i][j].teacher;if(tea==未定)continue;unsignedk=0;for(;kteachers.size();++k){if(teachers[k][0].teacher==tea){teachers[k].push_back(teacher_inverted(tea,i,j));break;}}if(k==teachers.size()){vectorteacher_invertedti;//一个教师的排课信息倒排表ti.push_back(teacher_inverted(tea,i,j));teachers.push_back(ti);}}}constintN=256;bitsetNct;//教室时段的分配状况infile.open(argv[2]);;vectorstringclassrooms;//教室数组while(getline(infile,s)){classrooms.push_back(s);}infile.close();unsignedarrange_num=plan.size();//待排课数目unsignedclass_num=arranges.size();//教学班级数目unsignedclassroom_num=classrooms.size();//教室数目uniform_int_distributionunsignedu(0,classroom_num*20-1);//为教室时段分配随机数default_random_enginee(time(0));vectorunsignedclass_loc(class_num,0);//教学班级已分配状况unsignedclass_cur=0;//待分配的教学班级序号,轮流为每个班级排课,一次安排一个班的一门课for(unsignedn=0;narrange_num;++n){unsignedk=u(e);//如果某个班级的排课任务已经分配完成,则选择下一个班级继续排课while(class_loc[class_cur]==arranges[class_cur].size()){class_cur=(class_cur+1)%class_num;}//找到待排课任务的对应教师stringtea=arranges[class_cur][class_loc[class_cur]].teacher;unsignedi=0;for(;iteachers.size();++i){if(tea==teachers[i][0].teacher)break;}//找出与该教师无时间冲突的时段do{do{while(ct.test(k)){k=(k+1)%(classroom_num*20);}unsignedm=0;for(;mclass_loc[class_cur];++m){if(arranges[class_cur][m].classroom_time%20==k%20)break;}if(m==class_loc[class_cur])break;//如果与前面已安排的该班级时间无冲突,则k可用k=(k+1)%(classroom_num*20);//如果有冲突则检查下一个教室时段是否可用}while(1);if(i==teachers.size())break;//教师未定unsignedj=0;for(;jteachers[i].size();++j){intm=arranges[teachers[i][j].class_loc][teachers[i][j].arrange_loc].classroom_time;if(m!=-1&&(m%20==k%20))break;}if(j==teachers[i].size())break;//如果与该教师的时间无冲突,则k可用k=(k+1)%(classroom_num*20);//如果有冲突则检查下一个教室时段是否可用}while(1);//排课arranges[class_cur][class_loc[class_cur]].classroom_time=k;ct.set(k);//将当前班级的排课号+1++class_loc[class_cur];//将待排课班级号+1class_cur=(class_cur+1)%class_num;}loop://输出cout\t\t高校自动排课系统\n;cout选择查询条件:1.按班级2.按教师3.按教室\n;cout请输入查询序号:(输入-1退出系统);unsignedchoice=0;cinchoice;if(-1==choice){cout正常退出系统\n;return0;}elseif(1==choice){unsignedi=0,j=0;for(;iarranges.size();++i){couti.arranges[i][0].grade_special\t;if((i+1)%4==0)cout\n;}cout\n;do{cout\n请输入待查询班级的序号:(输入-1结束查询);cini;if(i==-1){break;}elseif(i=arranges.size()){cout非法选择\n;continue;}intclass_table[4][5];for(unsignedm=0;m4;++m)for(unsignedn=0;n5;++n)class_table[m][n]=-1;for(j=0;jarranges[i].size();++j){unsignedm=arranges[i][j].classroom_time%20;class_table[m/5][m%5]=j;}stringtime_slot[4]={8:00-9:40,10:00-11:40,14:00-15:40,16:00-17:40};coutsetiosflags(ios_base::left);coutsetw(54)arranges[i][0].grade