读书人

C语言写的验证程序用来排课的回溯算

发布时间: 2012-05-05 17:21:10 作者: rapoo

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;    } 

读书人网 >软件架构设计

热点推荐