C语言写的验证程序,用来排课的回溯算法,但是输出不对,还望大牛们指点一下

ynnulyy0101001 2012-05-03 11:17:06
代码如下:

#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都为0
void 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;
}
}
}

调试的输出总是不对,自己找不到错在哪里了,各位牛人指点一下吧
...全文
211 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
LoveYouSelf 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
引用 4 楼 的回复:
引用 2 楼 的回复:
引用 1 楼 的回复:
没仔细的去了解你的代码,也不清楚你到底在讲些什么,你的注释太少,讲的不够明白,我这边运行的时候输入都会出问题。帮你改了一点代码,另外建议你写函数的时候不要老是用VOID 还是又返回值的比较好

C/C++ code

void Initialize_Judge(bool J[M][N])
if(c=='Y'||……
[/Quote]

这个我真的无能无力了!
ynnulyy0101001 2012-05-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
引用 2 楼 的回复:
引用 1 楼 的回复:
没仔细的去了解你的代码,也不清楚你到底在讲些什么,你的注释太少,讲的不够明白,我这边运行的时候输入都会出问题。帮你改了一点代码,另外建议你写函数的时候不要老是用VOID 还是又返回值的比较好

C/C++ code

void Initialize_Judge(bool J[M][N])
if(c=='Y'||c=='y')
{
f……
[/Quote]

嗯,思路就是这样了,就是一张表,向里面填东西,规则是同一列不能出现两个ClassID相同的元素
ynnulyy0101001 2012-05-05
  • 打赏
  • 举报
回复
把教室和时间看做资源,将时间分片,每个课时一片,做一个表格,表格的行代表教室的编号,表格的列表示对应的时间片编号,Room_Time结构体,就是这个资源表,再将班级和需要上的课程看做资源,比如说1班要上第二种课3节每个星期,那就有三个在Class_Lesson CL[X]中对应的元素,每个元素的ClassID=1,LessonID=2,将CL这个资源集合中的元素,填入资源表中就进行了排课。
我排课的想法是每一次找到一个合法的位置(合法是指同一列不能有ClassID相同的元素),用回溯法做的,就是回溯这里出了问题吧应该,所以请各位帮忙看看,我已经想不出来了
LoveYouSelf 2012-05-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
引用 1 楼 的回复:
没仔细的去了解你的代码,也不清楚你到底在讲些什么,你的注释太少,讲的不够明白,我这边运行的时候输入都会出问题。帮你改了一点代码,另外建议你写函数的时候不要老是用VOID 还是又返回值的比较好

C/C++ code

void Initialize_Judge(bool J[M][N])
if(c=='Y'||c=='y')
{
flag=1;
……

……
[/Quote]

你先大体讲讲你的思路,不然我看起来会很累。

scanf当中用逗号隔开这我知道,但是当Scanf遇到多个输入的时候就会出错,可能跟计算机有关系,
在我这边运行代码的时候,是不能进行输入的 即使我输入了flag = -1 也退不出来!
ynnulyy0101001 2012-05-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
没仔细的去了解你的代码,也不清楚你到底在讲些什么,你的注释太少,讲的不够明白,我这边运行的时候输入都会出问题。帮你改了一点代码,另外建议你写函数的时候不要老是用VOID 还是又返回值的比较好

C/C++ code

void Initialize_Judge(bool J[M][N])
if(c=='Y'||c=='y')
{
flag=1;
……
[/Quote]

另外,输入的时候用逗号隔开就行了,C的scanf函数里面说得很清楚
ynnulyy0101001 2012-05-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
没仔细的去了解你的代码,也不清楚你到底在讲些什么,你的注释太少,讲的不够明白,我这边运行的时候输入都会出问题。帮你改了一点代码,另外建议你写函数的时候不要老是用VOID 还是又返回值的比较好

C/C++ code

void Initialize_Judge(bool J[M][N])
if(c=='Y'||c=='y')
{
flag=1;
……
[/Quote]

谢谢你的意见,我觉得主要问题出现在Find的回溯上,自己已经陷进思维怪圈去了,想不出错在哪里,能不能帮我看看Find的回溯是不是错了?
LoveYouSelf 2012-05-03
  • 打赏
  • 举报
回复
没仔细的去了解你的代码,也不清楚你到底在讲些什么,你的注释太少,讲的不够明白,我这边运行的时候输入都会出问题。帮你改了一点代码,另外建议你写函数的时候不要老是用VOID 还是又返回值的比较好

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

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧