C语言写的验证程序,用来排课的回溯算法,但是输出不对,还望大牛们指点一下
代码如下:
- C/C++ code
#include<stdio.h>#include<process.h>#include<time.h>#include<stdlib.h>#define randomize() srand((unsigned)time(NULL)) //定义randomize()用以产生随机数#define M 5 //定义教室数量#define N 5 //定义时间片数量#define X 25 //定义有需求的“班级-课程”数量/*************************************结构体列表******************************************************/struct Room_Time //定义资源“教室-时间片”的单位结构体,包含待分配的课程ID和班级ID,表示一个单位资源{ int RT_ClassID; int RT_LessonID;};struct Class_Lesson //定义需求“班级-课程”的单位结构体,包含需要分配的班级ID和课程ID,表示一个单位的需求{ int CL_ClassID; int CL_LessonID;};/**************************************函数列表********************************************************/void Initialize_Judge(bool J[M][N]); //初始化Judge[M][N]void Initialize_RT(Room_Time R[M][N]); //初始化教室-时间表,每个资源单位的RT_ClasssID,RT_LessonID都为0void Initialize_CL(Class_Lesson D[X]); //初始化需求集合CL,可以手工输入信息也可以随即产生void Output(Room_Time R[M][N]); //输出资源表,即输出总课表void Find(bool J[M][N],Room_Time R[M][N],Class_Lesson D[X],int x,int CLnum);//表示前x-1个CL中的元素已经得到合法分陪//并为第x个需求分配一个合法的资源//CLnum表示有效的资源个数,当x==CLnum时候表示已经找到一个解了//int GetLegalLocationN(bool J[M][N],Room_Time R[M][N],Class_Lesson D[X],int x);//在J[M][N]中查找到的第一个可用单位,返回该单位的N值//int GetLegalLocationM(bool J[M][N],Room_Time R[M][N],Class_Lesson D[X],int x);//在J[M][N]中查找到的第一个可用单位,返回该单位的N值bool Check(bool J[M][N],Room_Time R[M][N],Class_Lesson D[X],int x,int m,int n);//检查当前的的位置是否合法/*****************************************************************************************************/void main(){ bool Judge[M][N]; //与RT对应的判断表,判断当前RT表中某一位置是否可用 Room_Time RT[M][N]; //定义资源二维数组,得到一个表,行表示有M个教室,列表示N个时间片 Class_Lesson CL[X]; //定义需求集合,一次填入RT表中,得到一个总课表 int CLnum=0; Initialize_Judge(Judge); //初始化Judge数组 Initialize_RT(RT); //初始化RT资源数组 Initialize_CL(CL); //初始化CL需求数组,所有非空的元素从第0号开始排列直到所有非空元素进入数组 while(CL[CLnum].CL_ClassID!=0) //求出最后一个非空元素的序号 { CLnum++; } Find(Judge,RT,CL,0,CLnum);}/*****************资源的状态初始化*****************/void Initialize_Judge(bool J[M][N]) //初始化Judge[M][N]{ char c; int i=0,j=0,flag=1; for(i=0;i<M;i++) for(j=0;j<N;j++) J[i][j]=true; printf("Is there unuseable Room-Time unit(Y/N)?\n"); scanf("%c",&c); getchar(); if(c=='Y'||c=='y') { flag=1; while(flag!=-1) { printf("Pleas input unuseable unit's Rommnum and Timenum(r,t,flag)(end by input flag==-1):\n"); scanf("%d,%d,%d",&i,&j,&flag); getchar(); J[i][j]=false; } }}/***********对教室时间片数组初始化*************/void Initialize_RT(Room_Time R[M][N]) //初始化教室-时间表,每个资源单位的RT_ClasssID,RT_LessonID都为0{ int i,j; for(i=0;i<M;i++) { for(j=0;j<N;j++) { R[i][j].RT_ClassID=0; R[i][j].RT_LessonID=0; } } /*for(i=0;i<M;i++) { for(j=0;j<N;j++) { printf("ClassID is %d,Lesson ID is %d",R[i][j].RT_ClassID,R[i][j].RT_LessonID); } }*/}/*****对班级课程数组初始化***************/void Initialize_CL(Class_Lesson D[X]) //初始化需求集合CL,可以手工输入信息也可以随即产生{ int i=0,j=0,k=0,TC=0,TL=0; int flag=0; char c; printf("Rand date or input date?(R/I)\n"); scanf("%c",&c); getchar(); if(c=='R'||c=='r') { randomize(); //产生随机种子 for(i=0;i<X;i++) { D[i].CL_ClassID=rand()%10+1; //产生随机的ClassID,范围在1~10间 D[i].CL_LessonID=rand()%12+1; //产生随机的LessonID,范围在1~12间 } /*for(i=0;i<X;i++) { printf("the ClassID is %d and the LessonID is %d\n",D[i].CL_ClassID,D[i].CL_LessonID); }*/ /* 一般地,M,N是整数,且M<N,获取从M到N的随机数可以这么写 1)先用srand产生种子 2)再象下面调用函数rand rand()%(N-M+1)+M */ } else { i=0; while(flag!=-1) { printf("Pleas input ClassID and required LessonID:\n"); scanf("%d,%d",&TC,&TL); printf("Please input it's times,end by input flag==-1:\n"); scanf("%d,%d",&k,&flag); for(j=i;j<i+k;j++) { D[j].CL_ClassID=TC; D[j].CL_LessonID=TL; } i=j-1; j=0; i++; } while(i<X) //将余下的空单位赋值为0 { D[i].CL_ClassID=0; D[i].CL_LessonID=0; i++; } /*for(i=0;i<X;i++) { printf("the ClassID is %d and the LessonID is %d\n",D[i].CL_ClassID,D[i].CL_LessonID); }*/ }}/*************************************输出课程表**************************************************/void Output(Room_Time R[M][N]){ int i,j; printf("ClassID\t\tLessonID\tRoomID\t\tTimeID\n"); for(i=0;i<M;i++) { for(j=0;j<N;j++) { printf("%d\t\t%d\t\t%d\t\t%d\n",R[i][j].RT_ClassID,R[i][j].RT_LessonID,i+1,j+1); } printf("\n\r"); } system("Pause"); //暂停}/*********************************检查当前位置是否合法****************************************/bool Check(bool J[M][N],Room_Time R[M][N],Class_Lesson D[X],int x,int m,int n) //检查从GetLegalLocation获得的位置是否合法//合法条件是R[M][N]中同列中不存在和CL[x].CL_ClassID相同的元素{ bool Ccheck=true; int i; int ID; if(J[m][n]==false) //如果在Judge中是不可用位置,则返回false { Ccheck=false; return Ccheck; } ID=D[x].CL_ClassID; for(i=0;i<M;i++) { if(R[i][n].RT_ClassID==ID) //如果遇到了同列中有ClassID相等的元素,说明冲突,Ccheck赋值false,打断循环 { Ccheck=false; break; } } return Ccheck;}/*********对第x个需求元素在资源表中找到合法位置************/void Find(bool J[M][N],Room_Time R[M][N],Class_Lesson D[X],int x,int CLnum){ int i,j; bool flag,check; if(x==CLnum) //回溯结束,输出结果 { Output(R); return; } for(i=0;i<=M;i++) //遍历整张资源表, { flag=true; //先设置成功找到位置 for(j=0;j<N;j++) { check=Check(J,R,D,x,i,j); //如果当前找到的位置不合法,退出本次循环,找下一个位置 if(check==false) { flag=false; break; } } if(flag=true) //如果找到的位置合法,将资源分配给需求 { R[i][j].RT_ClassID=D[x].CL_ClassID; R[i][j].RT_LessonID=D[x].CL_LessonID; J[i][j]=false; Find(J,R,D,x+1,CLnum); //对需求中的下一个元素进行在资源表中的查找 R[i][j].RT_ClassID=0; //释放资源单位,便于下一轮的回溯 R[i][j].RT_LessonID=0; J[i][j]=true; } }}
调试的输出总是不对,自己找不到错在哪里了,各位牛人指点一下吧
[解决办法]
没仔细的去了解你的代码,也不清楚你到底在讲些什么,你的注释太少,讲的不够明白,我这边运行的时候输入都会出问题。帮你改了一点代码,另外建议你写函数的时候不要老是用VOID 还是又返回值的比较好
- C/C++ code
void Initialize_Judge(bool J[M][N]) if(c=='Y'||c=='y') { flag=1; while(flag!=-1) { printf("Pleas input unuseable unit's Rommnum and Timenum(r,t,flag)(end by input flag==-1):\n"); fflush(stdin); //scanf("%d,%d,%d",&i,&j,&flag); /*scanf有时在处理多个数据输入的时候会出问题 所以建议采用下面的写法 scanf("%d",&i); scanf("%d",&j); scanf("%d",&flag);*/ /*也可以使用C++的流操作运算,头文件使用iostream,下面就直接cin就可以了,这样做错误少点*/ std::cin>>i>>j>>flag; //getchar(); //fflush(stdin); J[i][j]=false; } return; }