430佘江维教学计划编制问题.docx
《430佘江维教学计划编制问题.docx》由会员分享,可在线阅读,更多相关《430佘江维教学计划编制问题.docx(40页珍藏版)》请在冰豆网上搜索。
430佘江维教学计划编制问题
目录
摘要1
前言2
正文3
1.采用类c语言定义相关的数据类型3
2.各模块的伪码算法6
3.函数的调用关系图15
4.调试分析18
5.测试结果19
6.源程序(带注释)22
总结33
参考文献34
致谢35
附件Ⅰ部分源程序代码36
摘要
大学的每个专业都要编制教学计划。
假设任何专业都有固定的学习年限,每学年含两学期,每学期的时间长度和学分上限都相等。
每个专业开设的课程都是确定的,而且课程的开设时间的安排必须满足先修关系。
每个课程的先修关系都是确定的,可以有任意多门,也可以没有。
每一门课程恰好一个学期。
试在这样的情况下设置一个教学计划编制程序。
在大学的某个专业中选取几个课程作为顶点,通过各门课的先修关系来构建个图,该图用邻接表来存储,邻接表的头结点存储每门课的信息。
关键词:
教学计划;编制;培养目标;管理;
前言
教学计划是学校保证教学质量和人才培养的关键,也是组织教学过程、安排教学过程、安排教学任务、确定教学编制的基本依据和课程安排的具体形式。
是稳定教学秩序、提高教学质量的重要保证。
从教学计划的设计、实施等方面,阐明了如何搞好教学管理,从而为提高教学质量提供保证。
随着教育改革的不断深入和社会发展的需要,原旧的教学计划在定位上的方向性偏差,已经不再适应社会的需求。
因此,应重视教学计划的改革和修订工作,以确保教育教学质量,提高教育教学水平。
教学计划编制中的思路:
一是明确培养目标;二是注重学科设置的整体性、统一性和灵活性、全面性;三是与学分制改革有机结合.
教学计划是高校实施常规教学活动的基本管理文档,由于传统的手工编制方式存在诸多弊端,开发基于Web应用程序形式的教学计划编制系统具有很好的应用价值。
使用C程序设计语言,研究开发教学计划编制系统Web应用系统。
近代以来,特别是在实行学科课程的条件下,教学计划主要是学科的计划,或只是学科表。
随着社会经济和科学技术的新发展,教育结构不断发生变革,现代教育和教学理论主张对教学计划的结构实行改革。
除了教学以外,生产劳动、科技活动、发展体力和增进健康的活动、艺术活动和社会活动等也应列入教学计划。
下面就利用对此进行程序设计,已达到预期的目的。
正文
1.采用类c语言定义相关的数据类型
(1)、主程序:
intmain() //主函数
{
intnumterm; //学期总数
intuplcredit;//一个学期的学分上限
intselectway;
ALGraphG;
printf("请输入学期总数:
\n");
scanf("%d",&numterm);
printf("请输入一个学期的学分上限:
\n");
scanf("%d",&uplcredit);
CreatGraph(&G);
printf("请选择编排策略:
1.课程尽可能集中到前几个学期;2.课程尽量均匀分布\n");
scanf("%d",&selectway);
if(selectway==1)
TopologicalSort_1(G,numterm,uplcredit);
if(selectway==2)
TopologicalSort_2(G,numterm,uplcredit);
system("pause");
return0;
}
(2)、头结点,表结点,邻接表的定义:
#defineMAX_VERTEX_NUM100//最大课程总数
typedefstructArcNode{
intadjvex;
structArcNode*nextarc;
}ArcNode;
typedefstructVNode{
charname[24]; //课程名
intclassid; //课程号
intcredit; //课程的学分
intindegree; //该结点的入度
intstate; //该节点的状态
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VEXTEX_NUM];
typedefstruct{
AdjListvertices;
intvexnum,arcnum;
}ALGraph;
邻接表的基本操作:
voidCreatGraph(ALGraph*);
创建邻接表
voidFindInDegree(ALGraph,int*);
求一个结点的入度
voidTopologicalSort_1(ALGraphG,intnumterm,intmaxcredit);
拓扑排序来编排课程
voidTopologicalSort_2(ALGraphG,intnumterm,intmaxcredit);
拓扑排序来编排课程
(3)、栈的定义:
#defineSTACk_INIT_SIZE100//存储空间的初时分配量
#defineSTACKINCREMENT10 //存储空间的分配增量
typedefintElemType;
typedefstruct{
AdjListvertices;
intvexnum,arcnum;
}ALGraph;
基本操作:
voidInitStack(SqStack*S);
栈的初始化
intStackEmpty(SqStackS);
判断栈是否为空
voidPush(SqStack*S,int);
入栈操作
intPop(SqStack*S,int*e);
出栈操作
2.各模块的伪码算法
图的相关算法:
typedefintInfoType;
typedefstructArcNode
{
intadjvex;/*该弧所指向的顶点的位置*/
structArcNode*nextarc;/*指向下一条弧的指针*/
InfoType*info;/*网的权值指针)*/
}ArcNode;/*表结点*/3.函数的调用关系图
typedefenum{DG}GraphKind;/*{有向图,有向网,无向图,无向网}*/
typedefstruct
{
AdjListvertices,verticestwo;
intvexnum,arcnum;/*图的当前顶点数和弧数*/
intkind;/*图的种类标志*/
}ALGraph;
voidCreatGraph(ALGraph*G)//构造图
{inti,m,n;
ArcNode*p;
printf("请输入需要编排课程总数:
\t\t");
scanf("%d",&G->vexnum);
printf("请依次输入课程名、课程号、课程学分\n\n");
printf("\t课程名\t\t课程号\t\t课程学分\n\n");
printf("\t");
for(i=1;i<=G->vexnum;i++)/*构造顶点向量*/
{
scanf("%s%d%d",&G->vertices[i].name,&G->vertices[i].classid,&G->vertices[i].credit);
printf("\t");
G->vertices[i].indegree=0;
G->vertices[i].state=0;
G->vertices[i].firstarc=NULL;
}
printf("请输入课程先修关系总数:
");
scanf("%d",&G->arcnum);
printf("请顺序输入每个课程先修关系(先修课程在前并以逗号作为间隔):
\n");
for(i=1;i<=G->arcnum;i++)
{
printf("\n请输入存在先修关系的两个课程的序号:
");
scanf("%d,%d",&n,&m);
while(n<0||n>G->vexnum||m<0||m>G->vexnum)
{
printf("输入的顶点序号不正确请重新输入:
");
scanf("%d,%d",&n,&m);
}
p=(ArcNode*)malloc(sizeof(ArcNode));
if(p==NULL)
{
printf("memoryallocationfailed,goodbey");
exit
(1);
}
p->adjvex=m;
p->nextarc=G->vertices[n].firstarc;
G->vertices[n].firstarc=p;
}
printf("\n建立的邻接表为:
\n");//输出建立好的邻接表
for(i=1;i<=G->vexnum;i++)
{
printf("%d:
->",G->vertices[i].classid);
for(p=G->vertices[i].firstarc;p!
=NULL;p=p->nextarc)
printf("%d->",p->adjvex);
printf("NULL");
printf("\n");
}
}
voidFindInDegree(ALGraphG,intindegree[])//求图中各节点的入度
{
inti;
ArcNode*p;
for(i=1;i<=G.vexnum;i++)
indegree[i]=0;//赋初值
for(i=1;i<=G.vexnum;i++)
{
p=G.vertices[i].firstarc;
while(p)
{indegree[p->adjvex]++;
p=p->nextarc;
}
}
}
voidTopologicalSort_1(ALGraphG,intnumterm,intuplcredit)//拓扑排序算法1
{
FILE*fp;
fp=fopen("bianpai.txt","w");
ArcNode*p;
SqStackS;
intindegree[MAX_VERTEX_NUM];//存放各节点的入度
inti,j,k;
intcount;//课程编排数目计数器
intsumcredit;//每个学期的课程学分累加器
FindInDegree(G,indegree);
for(i=1;i<=G.vexnum;i++)
G.vertices[i].indegree=indegree[i];
InitStack(&S);
count=0;
k=0;
while(count!
=G.vexnum&&k<=numterm)
{
sumcredit=0;
for(i=1;i<=G.vexnum;i++)//入度为零的节点入栈,即无先修的课程入栈
if((G.vertices[i].indegree==0)&&(G.vertices[i].state==0))
{
Push(&S,i);
G.vertices[i].state=1;//避免入度为零节点重复入栈
}
if(!
StackEmpty(&S)&&(sumcredit<=uplcredit))
{
k=k+1;
printf("\n");
printf("第%d个学期学得课程有:
\n",k);
sumcredit=0;
for(i=1;i<=G.vexnum;i++)//入度为零的节点入栈,即无先修的课程入栈
if((G.vertices[i].indegree==0)&&(G.vertices[i].state==0))
Push(&S,i);
while((!
StackEmpty(&S))&&(sumcredit{
Pop(&S,&j);
sumcredit=sumcredit+G.vertices[j].credit;
if(sumcredit<=uplcredit)
{
printf("%s",G.vertices[j].name);
fprintf(fp,"%s",G.vertices[j].name);
count++;
for(p=G.vertices[j].firstarc;p;p=p->nextarc)//对j号顶点每个邻接点的入度减一
G.vertices[p->adjvex].indegree--;
}
elsePush(&S,j);//将未输出的节点重新压入栈
}
}
fprintf(fp,"\n");
}
printf("\n");
if(countprintf("\n课程编排出错\n");
else
{
printf("\n课程编排成功\n");
}
fclose(fp);
}
voidTopologicalSort_2(ALGraphG,intnumterm,intuplcredit)//拓扑排序算法2
{FILE*fp;
fp=fopen("bianpai2.txt","w");
ArcNode*p;
SqStackS;
intindegree[MAX_VERTEX_NUM];
inti,j,k,m,n;
intmaxnum;
intsumnum;
intcount;//课程编排数目计数器
intsumcredit;//每个学期的课程学分累加器
FindInDegree(G,indegree);
for(i=1;i<=G.vexnum;i++)
G.vertices[i].indegree=indegree[i];
InitStack(&S);
count=0;
k=0;
maxnum=G.vexnum/numterm+1;
sumnum=0;
while(count!
=G.vexnum&&k<=numterm)
{
for(i=1;i<=G.vexnum;i++)
if((G.vertices[i].indegree==0)&&(G.vertices[i].state==0))
{
Push(&S,i);
G.vertices[i].state=1;
}
if(!
StackEmpty(&S)&&(sumcredit<=uplcredit)&&(sumnum<=maxnum))
{
k=k+1;
/*printf("\n");*/
printf("第%d个学期学得课程有:
",k);
sumcredit=0;
sumnum=0;
for(i=1;i<=G.vexnum;i++)//入度为零的节点入栈,即无先修的课程入?
if((G.vertices[i].indegree==0)&&(G.vertices[i].state==0))
Push(&S,i);
while((!
StackEmpty(&S))&&(sumcredit{
Pop(&S,&j);//出栈
sumcredit=sumcredit+G.vertices[j].credit;
sumnum=sumnum+1;
if((sumcredit<=uplcredit)&&(sumnum<=maxnum))
{
printf("%s\n",G.vertices[j].name);
fprintf(fp,"%s\n",G.vertices[j].name);
count++;
for(p=G.vertices[j].firstarc;p;p=p->nextarc)//对j号顶点每个邻接点的入度减一
G.vertices[p->adjvex].indegree--;
}
else
Push(&S,j);
}
}
fprintf(fp,"\n");
}
printf("\n");
if(countprintf("课程编排出错\n");
else
{
printf("课程编排成功\n");
}
fclose(fp);
}
栈的相关算法:
#defineSTACk_INIT_SIZE100//存储空间的初时分配量
#defineSTACKINCREMENT10//存储空间的分配增量
typedefintElemType;
typedefstruct
{
ElemType*top;
ElemType*base;
intstacksize;
}SqStack;
voidInitStack(SqStack*S)//栈的初始化
{
S->base=(int*)malloc(STACk_INIT_SIZE*sizeof(int));
if(!
S->base)
{
printf("ERROR");
exit
(1);
}
S->top=S->base;
S->stacksize=STACk_INIT_SIZE;
}
intStackEmpty(SqStack*S)//判断栈是否为空
{
if(S->top==S->base)
returnOK;
else
returnERROR;
}
voidPush(SqStack*S,inte)//入栈操作
{
if(S->top-S->base>=S->stacksize)
{
S->base=(int*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(int));
if(!
S->base)
{
printf("ERROR");
exit
(1);
}
S->top=S->base+S->stacksize;
S->stacksize+=STACKINCREMENT;
}
*S->top++=e;
}
intPop(SqStack*S,int*e)//出栈操作
{
if(S->top==S->base)exit
(1);
*e=*--S->top;
return0;
}
3.函数的调用关系图
流程图如下所示:
(1)、voidFindInDegree(ALGraphG,intindegree[])
//求图中各节点的入度(如图1)
voidCreatGraph(ALGraph*G)
//构件图(如图2)
图1图2
(2)、voidTopologicalSort_1(ALGraphG,intnumterm,intuplcredit)
//有向图G采用邻接表存储结构(如图3)
voidTopologicalSort_2(ALGraphG,intnumterm,intuplcredit)
//有向图G采用邻接表存储结构(如图4)
图3图4
(3)、voidmain()
//主函数(如图5)
主函数:
voidmain()
图5
4.调试分析
a、调试中遇到的问题及对问题的解决方法
我在实验过程中遇到的最大难题是两个课程排序算法的编写。
刚开始的时候没有任何的思路,网上也只有拓扑排序的算法,对于课程设计要求的排序算法没有任何头绪。
经过请教老师和同学以及翻阅了一些相关书籍,并在网上的搜索有了排序算法的大体思路。
经过三天的修改,终于写出了符合要求的排序算法。
b、算法的时间复杂度和空间复杂度
算法的时间复杂度是指算法编程后在机器中所耗费的时间。
该程序在图的构造算法中的时间复杂度为O(G->vexnum)+O(G->arcnum),在求节点入度的算法的时间复杂度为O((G.vexnum)2),拓扑排序算法中的时间复杂度为O((G.vexnum)2)。
算法的空间复杂度是指算法编程后在机器中所占的存储量。
该程序中所要存储的变量为G->vertices[i].name,G->vertices[i].classid,
G->vertices[i].credit,则其空间复杂度为S(G->vexnum)。
5.测试结果
使用VC++,打开教学计划编制问题.cpp文件,接着编译,无错误,然后重建也没有错误,最后执行该文件。
要求输入学期总数、一个学期的学分上限、需要编排课程总数、课程名、课程号、该课程的学分,按照出现的每一步来输入该课程设计所提供的相关数据。
然后还要输入课程先修课程总数,可以算出有16种关系,分别输出。
接着程序会根据这些数据,自动生成建立好的邻接表,用户可以根据系统显示的选择编排策略进行选择,有两种编排策略,最后结果体现在实验的正确测试结果里。
显示如下图a、b:
图a
图b
编排策略1(课程竟可能集中到前几个学期)编排成功结果如下图所示:
编排策略2(课程尽量均匀分布)编排成功结果如下图所示:
6.源程序(带注释)
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"math.h"
#include"malloc.h"
#include"ctype.h"
#include"limits.h"
#include"io.h"
#include"process.h"
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
typedefintInfoType;
#defineMAX_VERTEX_NUM100
typedefstructArcNode
{
int