安排教学计划问题 并提供实验告

img


实验报告包括
1.题目描述;
2.基本思路;
3.详细设计:
设计了哪些模块,模块简要说明,列出每个子程序函数名及功能说明;
4.主要源代码,与设计部分一一对应;
5.测试、运行截图及结果分析
5.测试、运行截图及结果分析。

img


#include<stdio.h>

int maxterm=12,maxclass=100;   //学期上限12,课程最大100 
int allterm,maxxf,num;            //学期总数 学分上限 课程数 
int Graph[100][100]={0};       //邻接矩阵;
int indegree[100]={0};         //入度矩阵 
int visit[100]={0};            //visit数组 
int Q[100];                    //临时队列
int end=0,top=0;               //队列头尾 
int over[100]={0};             //排完的课程 
 
typedef struct class
{
    char name[3];
    int xf;
}class,*pclass;

class CLASS[100];

void creat()        //图的创建 
{
    int i,v;
    char a;
    scanf("%d",&allterm);
    scanf("%d",&maxxf);
    scanf("%d",&num);
    for(i=0;i<num;i++)
    {
        scanf("%s",CLASS[i].name);
        scanf("%d",&CLASS[i].xf);
        while((a=getchar())!='\n')
        {
            a=getchar();
            scanf("%d",&v);
            Graph[v-1][i]=1;
            indegree[i]++;
        }
    }
}

void display()       //画出邻接矩阵 
{
    int i,j;
    printf("————邻接矩阵————\n") ;
    for(i=0;i<num;i++)
    {
        for(j=0;j<num;j++)
        {
            printf("%d%c",Graph[i][j],j==num-1?'\n':' ');
        }
    }
    printf("—————————————\n") ;
}

int front()
{
    return Q[top];
}
void push(int i)
{
    Q[end++]=i;
}

void pop()
{
    top++;
}

int empty()
{
    if(top==end)
        return 1;
    else
        return 0;
}
void top_sort()
{
    int i,j,V,count=0;
    for(i=0;i<num;i++)
    {
        if(indegree[i]==0)
            push(i);
    }
    while(!empty())
    {
        V=front();
        over[count++]=V;
        visit[V]=1;
        pop();
        for(j=0;j<num;j++)
        {    
            if(Graph[V][j]==1)
            {
                indegree[j]--;
                if(indegree[j]==0)
                    push(j);
            }
        }
    }
    for(i=0;i<num;i++)
    {
        if(visit[i]==0)
            printf("课程存在错误\n");
            break;
    }
}

void solve1()
{
    int i,j,one_term,more,mark=0;
    one_term=num/allterm;
    more=num%allterm;
    for(i=0;i<more;i++)
    {
        printf("第%d个学期课程安排:",i+1);
        for(j=0;j<one_term+1;j++)
        {
            printf("%s ",CLASS[over[j+i*(one_term+1)]].name);
        }
        putchar('\n');
    }
    mark=more*(one_term+1)-1;
    for(i;i<allterm;i++)
    {
        printf("第%d个学期课程安排:",i+1);
        for(j=0;j<one_term;j++)
        {
            printf("%s ",CLASS[over[more+j+i*one_term]].name);
        }
        putchar('\n');
    }
}

void solve2()
{
    int i=1,j=0,total;
    while(i<=allterm)
    {
        total=0;
        printf("第%d个学期课程安排:",i);
        while(total<=10 && j<num)
        {
            total+=CLASS[over[j]].xf;
            if(total<=maxxf)
            {
                printf("%s ",CLASS[over[j]].name);
            }
            j++;
        }
        putchar('\n');
        j--;
        i++;
    }
    
}

int main()
{
    int i,j,solve;
    creat();
    display();
    top_sort();
    printf("平均安排输出1,密集安排输入2:");
    scanf("%d",&solve);
    if(solve==1)
        solve1();
    else
        solve2();
    return 0;
}

/*
测试数据
6 10 12
c1 2
c2 3 c1
c3 4 c1 c2
c4 3 c1
c5 2 c3 c4
c6 3 c11
c7 4 c3 c5
c8 4 c3 c6
c9 7
c10 5 c9
c11 2 c9
c12 3 c1 c9 c10
*/码片

C语言实现教学计划安排,一样的

img


解决方法: 构建课程顺序的图结构,进行拓扑排序即可

#include<stdio.h>

int maxterm=12,maxclass=100;   //学期上限12,课程最大100 
int allterm,maxxf,num;            //学期总数 学分上限 课程数 
int Graph[100][100]={0};       //邻接矩阵;
int indegree[100]={0};         //入度矩阵 
int visit[100]={0};            //visit数组 
int Q[100];                    //临时队列
int end=0,top=0;               //队列头尾 
int over[100]={0};             //排完的课程 
 
typedef struct class
{
    char name[3];
    int xf;
}class,*pclass;

class CLASS[100];

void creat()        //图的创建 
{
    int i,v;
    char a;
    scanf("%d",&allterm);
    scanf("%d",&maxxf);
    scanf("%d",&num);
    for(i=0;i<num;i++)
    {
        scanf("%s",CLASS[i].name);
        scanf("%d",&CLASS[i].xf);
        while((a=getchar())!='\n')
        {
            a=getchar();
            scanf("%d",&v);
            Graph[v-1][i]=1;
            indegree[i]++;
        }
    }
}

void display()       //画出邻接矩阵 
{
    int i,j;
    printf("————邻接矩阵————\n") ;
    for(i=0;i<num;i++)
    {
        for(j=0;j<num;j++)
        {
            printf("%d%c",Graph[i][j],j==num-1?'\n':' ');
        }
    }
    printf("—————————————\n") ;
}

int front()
{
    return Q[top];
}
void push(int i)
{
    Q[end++]=i;
}

void pop()
{
    top++;
}

int empty()
{
    if(top==end)
        return 1;
    else
        return 0;
}
void top_sort()
{
    int i,j,V,count=0;
    for(i=0;i<num;i++)
    {
        if(indegree[i]==0)
            push(i);
    }
    while(!empty())
    {
        V=front();
        over[count++]=V;
        visit[V]=1;
        pop();
        for(j=0;j<num;j++)
        {    
            if(Graph[V][j]==1)
            {
                indegree[j]--;
                if(indegree[j]==0)
                    push(j);
            }
        }
    }
    for(i=0;i<num;i++)
    {
        if(visit[i]==0)
            printf("课程存在错误\n");
            break;
    }
}

void solve1()
{
    int i,j,one_term,more,mark=0;
    one_term=num/allterm;
    more=num%allterm;
    for(i=0;i<more;i++)
    {
        printf("第%d个学期课程安排:",i+1);
        for(j=0;j<one_term+1;j++)
        {
            printf("%s ",CLASS[over[j+i*(one_term+1)]].name);
        }
        putchar('\n');
    }
    mark=more*(one_term+1)-1;
    for(i;i<allterm;i++)
    {
        printf("第%d个学期课程安排:",i+1);
        for(j=0;j<one_term;j++)
        {
            printf("%s ",CLASS[over[more+j+i*one_term]].name);
        }
        putchar('\n');
    }
}

void solve2()
{
    int i=1,j=0,total;
    while(i<=allterm)
    {
        total=0;
        printf("第%d个学期课程安排:",i);
        while(total<=10 && j<num)
        {
            total+=CLASS[over[j]].xf;
            if(total<=maxxf)
            {
                printf("%s ",CLASS[over[j]].name);
            }
            j++;
        }
        putchar('\n');
        j--;
        i++;
    }
    
}

int main()
{
    int i,j,solve;
    creat();
    display();
    top_sort();
    printf("平均安排输出1,密集安排输入2:");
    scanf("%d",&solve);
    if(solve==1)
        solve1();
    else
        solve2();
    return 0;
}

/*
测试数据
6 10 12
c1 2
c2 3 c1
c3 4 c1 c2
c4 3 c1
c5 2 c3 c4
c6 3 c11
c7 4 c3 c5
c8 4 c3 c6
c9 7
c10 5 c9
c11 2 c9
c12 3 c1 c9 c10
*/码片


可以使用拓扑排序来安排课程的学习顺序。拓扑排序是一种用于有向无环图(DAG)的节点排序算法,它可以将节点排序成一个线性序列,使得每个节点都在它的前驱节点之后。在这个问题中,每个课程可以看作是图中的一个节点,课程之间的先修关系可以看作是有向边。
实现这个算法的关键是确定每个课程的前驱节点。我们可以使用一个数组来记录每个节点的入度(即有多少个节点指向它),然后在拓扑排序的过程中,每次选择入度为0的节点,将其添加到排序结果中,并将它的后继节点的入度减1。重复这个过程,直到所有节点都被添加到排序结果中或者发现有环(即存在先修关系循环依赖)。
下面是一个使用C语言实现拓扑排序的示例代码,它可以根据用户输入的课程信息生成一个教学计划:


#include <stdio.h>
#include <stdlib.h>

#define MAX_COURSES 100

typedef struct Course {
    int id;
    int credits;
    int prerequisites[MAX_COURSES];
    int num_prerequisites;
    int semester;
} Course;

Course courses[MAX_COURSES];
int num_courses;

int in_degree[MAX_COURSES];

int schedule(int num_semesters, int max_credits, int strategy, const char* output_file) {
    // 初始化入度数组
    for (int i = 0; i < num_courses; i++) {
        in_degree[i] = 0;
    }
    for (int i = 0; i < num_courses; i++) {
        for (int j = 0; j < courses[i].num_prerequisites; j++) {
            int prerequisite = courses[i].prerequisites[j];
            in_degree[prerequisite]++;
        }
    }
    // 拓扑排序
    int* result = (int*)malloc(num_courses * sizeof(int));
    int* result_tail = result;
    int num_added = 0;
    int semester = 1;
    while (num_added < num_courses) {
        int added_in_semester = 0;
        for (int i = 0; i < num_courses; i++) {
            if (in_degree[i] == 0) {
                // 判断当前课程是否超过学分上限
                int credits_in_semester = 0;
                for (int j = 0; j < num_added; j++) {
                    int course_id = result[j];
                    credits_in_semester += courses[course_id].credits;
                }
                if (credits_in_semester + courses[i].credits > max_credits) {
                    continue;
                }
                // 判断当前课程是否可以被放到当前学期
                if (strategy == 2 && courses[i].semester > semester) {
                    continue;
                }
                // 将当前课程添加到排序结果中,并将它的后继节点的入度减1
                *result_tail++ = i;
                num_added++;
                in_degree[i] = -1;
                for (int j = 0; j < courses[i].num_prerequisites; j++) {
                    int prerequisite = courses[i].prerequisites[j];
                    in_degree[prerequisite]--;
                }
                added_in_semester++;
            }
        }
        // 如果当前学期没有添加任何课程,则表示存在循环依赖
        if (added_in_semester == 0) {
            free(result);
            return -1;
        }
        // 如果当前学期添加的课程数量不足,则继续添加下一个学期的课程
        if (added_in_semester < num_courses / num_semesters) {
            semester++;
        }
    }
    // 输出结果到文件
    FILE* fp = fopen(output_file, "w");
    for (int i = 0; i < num_courses; i++) {
        int course_id = result[i];
        fprintf(fp, "第%d学期\t课程%d\t%d学分\n", courses[course_id].semester, courses[course_id].id, courses[course_id].credits);
    }
    fclose(fp);
    free(result);
    return 0;
}

int main() {
    //为了测试这个程序,我们需要先输入课程信息。下面是一个简单的交互式输入方式,允许用户输入每门课程的课程号、学分和直接先修课的课程号:

```c
int main() {
    printf("请输入学期总数:");
    int num_semesters;
    scanf("%d", &num_semesters);
    printf("请输入一学期的学分上限:");
    int max_credits;
    scanf("%d", &max_credits);
    printf("请输入课程数量:");
    scanf("%d", &num_courses);
    printf("请依次输入每门课程的信息:\n");
    for (int i = 0; i < num_courses; i++) {
        printf("课程%d:\n", i);
        printf("课程号:");
        scanf("%d", &courses[i].id);
        printf("学分:");
        scanf("%d", &courses[i].credits);
        printf("先修课程数量:");
        scanf("%d", &courses[i].num_prerequisites);
        printf("请依次输入先修课程的课程号:");
        for (int j = 0; j < courses[i].num_prerequisites; j++) {
            scanf("%d", &courses[i].prerequisites[j]);
        }
        printf("开设学期:");
        scanf("%d", &courses[i].semester);
    }
    // 调用教学计划编制程序
    int result = schedule(num_semesters, max_credits, 2, "教学计划.txt");
    if (result == -1) {
        printf("无法生成教学计划,存在循环依赖。\n");
    } else {
        printf("教学计划已生成到文件教学计划.txt中。\n");
    }
    return 0;
}

实验报告

题目描述:
本次实验的题目是“安排教学计划”。针对大学的每个专业需要制定教学计划的实际需求,要求设计一个教学计划编制程序。该程序需要输入学期总数、一学期的学分上限、每门课程的课程号、学分和直接先修课的课程号,允许两种策略,一是使学生在各学期的学习负担尽量均匀,二是使课程尽量集中在前几个学期。如果根据给定的条件问题无解,则报告适当的信息,否则将教学计划输出到用户指定的文件中。

基本思路:
解决这个问题的基本思路是使用拓扑排序来安排课程的学习顺序。拓扑排序是一种用于有向无环图(DAG)的节点排序算法,它可以将节点排序成一个线性序列,使得每个节点都在它的前驱节点之后。在这个问题中,每个课程可以看作是图中的一个节点,课程之间的先修关系可以看作是有向边。

实现这个算法的关键是确定每个课程的前驱节点。我们可以使用一个数组来记录每个节点的入度(即有多少个节点指向它),然后在拓扑排序的过程中,每次选择入度为0的节点,将其添加到排序结果中,并将它的后继节点的入度减1。重复这个过程,直到所有节点都被添加到排序结果中或者发现有环(即存在先修关系循环依赖)。

详细设计:
本实验的程序设计可以分为以下几个模块:

(1)读取输入数据模块:该模块负责读取用户输入的数据,包括学期总数、一学期的学分上限、每门课程的课程号、学分和直接先修课的课程号等信息。

(2)拓扑排序模块:该模块使用拓扑排序算法来安排课程的学习顺序。它需要对每个节点(即每门课程)记录其入度和后继节点,然后根据入度来选择每次添加的节点,并将其后继节点的入度减1。如果存在循环依赖,则拓扑排序无法完成,需要报告适当的信息。

(3)输出结果模块:该模块负责将教学计划输出到用户指定的文件中。输出的格式可以自行设定,例如按照学期、课程号、学分等信息依次输出。

下面是每个子程序函数名及功能说明:

(1)read_input_data:读取输入数据函数,用于读取用户输入的数据,包括学期总数、一学期的学分上限、每门课程的课程号、学分和直接先修课的课程号等信息。

(2)topological_sort:拓扑排序函数,用于使用拓扑排序算法来安排课程的学习顺序。它需要对每个节点(即每门课程)记录其入度和后继节点,然后根据入度来选择每次添加的节点,并将其后继节点的入度减1。如果存在循环依赖,则拓扑排序无法完成,需要报告适当的信息。

(3)output_result:输出结果函数,用于将教学计划输出到用户指定的文件中。输出的格式可以自行设定,例如按照学期、课程号、学分等信息依次输出。

输出界面你自己运行截图就好啦!

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7543656
  • 你也可以参考下这篇文章:燕山大学课程设计源码______基于单片机试验板设计一个电子跑表系统,用按钮启动和停止,能够实现最多59分59秒的跑表,在数码管上显示当前的跑表时间值;
  • 除此之外, 这篇博客: 西安交通大学915考研编程笔记中的 21.求一个数字是几位数,并将其逆序打印(不多于5位数),并判断这个数字是不是回文数 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    //求一个数字是几位数,并将其逆序打印(不多于5位数)
    //判断这个数字是不是回文数
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int a,b,c,d,e,f;//分别代表个、十、百、千、万
        long x;     //未知数
        cin>>x;
        a=x%10;     //个
        b=(x/10)%10; //十
        c=(x/100)%10; //百
        d=(x/1000)%10; //千
        e=(x/10000)%10; //万
        f=(x/100000)%10; //十万
        if(f!=0)
            cout<<"error"<<endl;
        else if(e!=0)
        {
            cout<<"5位数,逆序为:"<<a<<b<<c<<d<<e<<" ";
            if(a==e&&b==d)
                cout<<"是回文数"<<endl;
            else
                cout<<"不是回文数"<<endl;
        }
    
        else if(d!=0)
        {
            cout<<"4位数,逆序为:"<<a<<b<<c<<d<<" ";
            if(a==d&&b==c)
                cout<<"是回文数"<<endl;
            else
                cout<<"不是回文数"<<endl;
        }
    
        else if(c!=0)
        {
            cout<<"3位数,逆序为:"<<a<<b<<c<<" ";
            if(a==c)
                cout<<"是回文数"<<endl;
            else
                cout<<"不是回文数"<<endl;
        }
        else if(b!=0)
        {
            cout<<"2位数,逆序为:"<<a<<b<<" ";
            if(a==b)
                cout<<"是回文数"<<endl;
            else
                cout<<"不是回文数"<<endl;
        }
    
        else if(a!=0)
        {
            cout<<"1位数,逆序为:"<<a<<" ";
            cout<<"是回文数"<<endl;
        }
        return 0;
    }
    
  • 您还可以看一下 林晓炜老师的白帽子黑客与网络安全工程师带你学习:网络攻防与渗透测试面试练习题课程中的 网络攻防与渗透测试面试练习题【3】小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    针对教学计划和实验报告的设计,需要考虑以下几个方面:

    1. 教学计划的编写

    教学计划是指对课程内容、开课时间、上课安排、作业安排等进行合理规划的一份计划。在制定教学计划时,需要充分考虑学生的学习状况和实际情况,结合教材和教学大纲,按照逻辑顺序进行编排。可以分为章节安排、课时安排和考试安排等。

    1. 实验报告的设计

    实验报告是一份总结和记录实验内容、过程和结果的文档。在实验报告的设计中,可以从以下几个模块进行划分:

    • 实验目的和背景
    • 实验环境和实验工具
    • 实验步骤和方法
    • 实验结果和分析
    • 结论和心得

    在编写实验报告时,需要尽可能详细地记录实验过程中遇到的问题和解决方法,以及自己的感悟和思考。

    1. 主要源代码与设计部分的对应实验报告

    在实验报告中需要包含主要源代码和设计部分的对应部分,以便读者能够清晰地了解实验的实现过程和原理。可以通过引用源代码的方式来实现。

    1. 运行测试的截图和结果分析

    在实验报告中需要包含运行测试的截图和结果分析,以便读者能够直观地看到实验结果和分析。可以通过在实验步骤和方法模块中添加截图和分析部分来实现。

    如果需要将浮点数转化成二进制浮点数,可以按照IEEE 754标准进行转化。将十进制浮点数转化成二进制浮点数的步骤如下:

    1. 将十进制浮点数转化成科学计数法,即$N = a \times 10^b$。

    2. 根据符号位确定 $S$ 的值,如果 $N$ 是正数,则 $S = 0$,如果 $N$ 是负数,则 $S = 1$。

    3. 将 $a$ 转化成二进制,整数部分和小数部分分别转化。

    4. 将转化后的整数部分和小数部分合并,得到 $M$ 的值。

    5. 计算指数 $E$ 的值,$E = n + bias$,其中 $n$ 是 $b$ 的二进制表示,$bias$ 是偏置值,对于单精度浮点数来说,偏置值是 $127$,对于双精度浮点数来说,偏置值是 $1023$。

    6. 将 $S$、$M$、$E$ 分别转化成二进制,合并得到二进制浮点数。

    如果需要将二进制浮点数转化成十进制浮点数,可以按照下面的步骤进行转化:

    1. 根据符号位确定浮点数的正负性。

    2. 计算指数 $E$ 的十进制值,$E = e - bias$,其中 $e$ 是指数部分的二进制表示,$bias$ 如上所述。

    3. 计算尾数 $M$ 的十进制值,$M$ 的值与 $E$ 的计算方式有关。如果位数是 $n$,则 $M$ 的十进制值为 $m \times 2^{n-1}$,其中 $m$ 是 $M$ 的二进制表示。

    4. 根据公式 $N = (-1)^S \times M \times 2^E$ 计算十进制浮点数 $N$ 的值。

    具体实现可以参考 IEEE 754 标准的具体实现方式进行编码。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

参考 https://www.renrendoc.com/paper/194006291.html

关于安排教学计划的课程设计,网上有些资料哦,有源代码的,你可以直接参考下:
C语言实现教学计划课程管理系统:https://peakchen.blog.csdn.net/article/details/131407639
教学计划安排 C语言实现:https://blog.csdn.net/huoshanshaohui/article/details/113245333
或者自己在找找资料

需求具体发我?

引用chatgpt内容作答:
下面是一个使用C++编写的教学计划编制程序的示例代码。它基于输入参数包括学期总数、一学期的学分上限、每门课程的课程号、学分和直接先修课的课程号。程序使用拓扑排序算法来确定课程的安排顺序,并提供两种策略:均匀分配和集中在前几个学期。

#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

struct Course {
    int courseNumber;
    int credits;
    vector<int> prerequisites;
};

vector<Course> courses;
vector<vector<int>> adjacencyList;

// 拓扑排序算法
vector<int> topologicalSort() {
    vector<int> inDegree(courses.size(), 0);
    for (const auto& course : courses) {
        for (int prerequisite : course.prerequisites) {
            inDegree[prerequisite]++;
        }
    }

    queue<int> q;
    for (int i = 0; i < inDegree.size(); i++) {
        if (inDegree[i] == 0) {
            q.push(i);
        }
    }

    vector<int> order;
    while (!q.empty()) {
        int courseNumber = q.front();
        q.pop();
        order.push_back(courseNumber);

        for (int adjacent : adjacencyList[courseNumber]) {
            inDegree[adjacent]--;
            if (inDegree[adjacent] == 0) {
                q.push(adjacent);
            }
        }
    }

    return order;
}

// 生成教学计划
void generateTeachingPlan(int semesters, int creditLimit, bool evenDistribution, const string& outputFilename) {
    ofstream outputFile(outputFilename);
    if (!outputFile) {
        cout << "无法打开输出文件" << endl;
        return;
    }

    vector<int> order = topologicalSort();
    if (order.size() != courses.size()) {
        cout << "无法制定教学计划,存在循环依赖关系" << endl;
        return;
    }

    int totalCredits = 0;
    int currentSemester = 1;
    for (int courseNumber : order) {
        Course course = courses[courseNumber];
        totalCredits += course.credits;

        if (evenDistribution) {
            currentSemester = (totalCredits - 1) / creditLimit + 1;
        } else {
            currentSemester = min(currentSemester, semesters);
        }

        outputFile << "第" << currentSemester << "学期:" << endl;
        outputFile << "课程号:" << course.courseNumber << endl;
        outputFile << "学分:" << course.credits << endl;
        outputFile << endl;
    }

    outputFile.close();
    cout << "教学计划已保存到文件" << endl;
}

int main() {
    // 添加课程信息
    Course course1 = {1, 3, {}};
    Course course2 = {2, 4, {1}};
    Course course3 = {3, 3, {1}};
    Course course4 = {4, 5, {2, 3}};
    // 添加更多课程...

    courses = {course1, course2, course3, course4};
    adjacencyList.resize(courses.size());

    // 构建课程的先修关系图
    for (int i = 0; i < courses.size(); i++) {
        for (int prerequisite : courses[i].prerequisites) {
            adjacencyList[prerequisite].push_back(i);
        }
    }

    // 设置参数
    int semesters = 6;
    int creditLimit = 10;
    bool evenDistribution = true;
    string outputFilename = "teaching_plan.txt";

    // 生成教学计划
    generateTeachingPlan(semesters, creditLimit, evenDistribution, outputFilename);

    return 0;
}

上述代码只是一个示例,你需要根据实际需求进行适当的修改。在示例中,我们添加了四门课程的信息,并手动构建了它们的先修关系图。你可以根据自己的需要扩展代码,添加更多课程和先修关系。在程序中设置了学期总数、学分上限和输出文件名等参数,你可以根据实际情况进行调整。

该程序使用拓扑排序算法确定课程的安排顺序,并根据选定的策略(均匀分配或集中在前几个学期)生成教学计划。教学计划将保存在用户指定的输出文件中。

请注意,在使用此程序之前,你应该根据实际情况修改课程和先修关系的信息,并确保输入的数据符合预期。此外,示例代码中只提供了基本的功能,你可以根据需要进一步完善和优化程序。

对于结果分析部分,请根据生成的教学计划文件进行分析,观察课程的安排顺序是否满足先修关系和选定的策略,并检查是否符合学分上限和学期总数的要求。根据分析结果,你可以对程序进行调整或改进,以获得更满意的教学计划。