设计求解AOE网关键路径程序(详细设计,附完整实现代码)

2023-12-30 01:50

本文主要是介绍设计求解AOE网关键路径程序(详细设计,附完整实现代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、课程设计内容

二、课程设计实现功能

三、具体实现功能过程以及可能遇到的问题

四、实现程序功能模块图

五、具体实现代码(完整代码C语言)

六、演示如何操作(注意输入信息,这里以上面AOE网为准输入)

6.1先输入AOE网的顶点个数和边数

6.2输入顶点元素(复制粘贴一下即可)

6.3输入边的信息(复制粘贴即可)

6.5运行结果页面展示

6.5.1AOE输入信息图:

6.5.2图的邻接表示图: 

6.5.3关键路径图和最短总工程时间:

七、总结与心得体会


坚持阅读,才能发现美的存在!

更多精彩等你哦!

一起来场跨时空的交流。

一、课程设计内容

设计内容:某新房精装修项目工作内容主要包括:(A)施工作业场所检验交接;(B)窗橱,门框防护;(C)防水作业;(D)土建改造;(E)防水检验接收;(F)水电检验接收;(G)原始地面防护;(H)铺贴瓷砖作业;(I)厅房吊顶作业;(J)天花吊顶作业;(K)顶棚一次面油;(L)墙面一次面油;(M)橱柜安装;(N)顶棚二次面油;(O)厨卫家电安装;(P)衣橱,门框进场作业;(Q)墙纸或墙面二次面油作业;(R)空调安装;(S)门扇安装;(T)木地板作业;(U)验收及整改;(V)施工完成并交付(将相应说明书的保留及移交物业)。根据以上各项工作内容具体工作时间如下表1所示。请构建本项目的AOE网,求出其关键路径及最短总工期。具体装修项目工期估计如下表1所以:

表1:某装修项目工期估计表

工作名称

工作内容

估计工期(单位:天)

A

施工作业场所检验交接

3

B

窗橱,门框防护

3

C

防水作业

10

D

土建改造

20

E

防水检验接收

3

F

水电检验接收

3

G

原始地面防护

2

H

铺贴瓷砖作业

6

I

厅房吊顶作业

10

J

天花吊顶作业

9

K

顶棚一次面油

14

L

墙面一次面油

10

M

橱柜安装

3

N

顶棚二次面油

10

O

厨卫家电安装

5

P

衣橱,门框进场作业

4

Q

墙纸或墙面二次面油作业

10

R

空调安装

3

S

门扇安装

3

T

木地板作业

10

U

验收及整改

20

V

施工完成并交接交付

17

二、课程设计实现功能

  1. 确定各项工作的先后关系,绘制AOE网络图;
  2. 计算AOE 网络图中的各活动时间;
  3. 确定关键路径;
  4. 计算最短总工期。

三、具体实现功能过程以及可能遇到的问题

1. 构建AOE网:根据用户输入的顶点个数和边数,使用邻接矩阵或邻接表的方式来表示图的结构。为每个顶点分配一个唯一的标识符,并将边的起始顶点和结束顶点添加到图中。可以使用二维数组表示邻接矩阵,或者使用链表表示邻接表。

2. 计算最早开始时间和最早完成时间:使用拓扑排序的方式来确定活动的顺序。从起始顶点开始,按照拓扑排序的顺序依次计算每个活动的最早开始时间和最早完成时间。对于每个活动,需要考虑其前驱活动的最早完成时间。可以使用深度优先搜索或广度优先搜索来进行拓扑排序。

3. 计算最晚开始时间和最晚完成时间:可以使用逆拓扑排序的方式来确定活动的顺序。从终点顶点开始,按照逆拓扑排序的顺序依次计算每个活动的最晚开始时间和最晚完成时间。对于每个活动,需要考虑其后继活动的最晚开始时间。可以使用深度优先搜索或广度优先搜索来进行逆拓扑排序。

4. 输出关键路径和最短总工期:通过比较每个活动的最早完成时间和最晚完成时间,可以确定关键路径上的活动。关键路径上的活动即为最早开始时间和最晚开始时间相等的活动。最短总工期可以通过终点顶点的最早完成时间来确定。

5. 错误处理:需要处理输入错误的情况,例如输入的顶点个数或边数为负数,活动的持续时间为负数等。可以使用条件判断语句来检查输入的有效性,并在出现错误时给出适当的提示信息。

6. 内存管理:在程序结束后,需要释放动态分配的内存,以防止内存泄漏。可以使用`malloc()`函数来分配内存,使用`free()`函数来释放内存。

四、实现程序功能模块图

4.1AOE网络图4.2程序流程图

五、具体实现代码(完整代码C语言)

#include <stdio.h>
#include <stdlib.h>
#define VertexType int //顶点的数据类型(char) 
#define VertexMax 40 //最大顶点个数 
typedef struct ArcNode//边表 
{int adjvex;//存储的是该顶点在顶点数组即AdjList[]中的位置 int weight;//权值 struct ArcNode* next;
}ArcNode;typedef struct VNode //顶单个点 
{VertexType vertex;struct ArcNode* firstarc;
}VNode;typedef struct //顶点表 
{VNode AdjList[VertexMax];//由顶点构成的结构体数组 int vexnum, arcnum; //顶点数和边数 
}ALGraph;int LocateVex(ALGraph* G, VertexType v)
{int i;for (i = 0; i < G->vexnum; i++){if (v == G->AdjList[i].vertex){return i;}}printf("No Such Vertex!\n");return -1;
}//有向图 
void CreateDN(ALGraph* G)
{int i, j;//1.输入顶点数和边数 printf("输入顶点个数和边数:\n");printf("顶点数 n=");scanf("%d", &G->vexnum);printf("边  数 e=");scanf("%d", &G->arcnum);printf("\n");printf("\n");//2.顶点表数据域填值初始化顶点表指针域 printf("输入顶点元素(用空格隔开):");for (i = 0; i < G->vexnum; i++){/*printf("输入第%d个顶点信息:", i + 1);*/scanf(" %d", &G->AdjList[i].vertex);//printf("222%d", G->AdjList[i].vertex);G->AdjList[i].firstarc = NULL;}printf("\n");//3.输入边信息构造邻接表 int n, m;VertexType v1, v2;int weight;ArcNode* p1, * p2;printf("请输入边的信息:\n\n");for (i = 0; i < G->arcnum; i++){   //输入边信息,并确定v1和v2在G中的位置,即顶点在AdjList[]数组中的位置(下标)  printf("输入第%d条边信息:", i + 1);scanf(" %d%d,%d", &v1, &v2, &weight);n = LocateVex(G, v1);m = LocateVex(G, v2);if (n == -1 || m == -1){printf("NO This Vertex!\n");return;}p1 = (ArcNode*)malloc(sizeof(ArcNode));p1->adjvex = m;//填上坐标 p1->weight = weight;//填上权值 p1->next = G->AdjList[n].firstarc;//改链(头插法)  G->AdjList[n].firstarc = p1;}//for  
}void print(ALGraph G)
{int i;ArcNode* p;printf("\n-------------------------------");printf("\n图的邻接表表示:\n");for (i = 0; i < G.vexnum; i++){printf("\n   AdjList[%d]%4d", i, G.AdjList[i].vertex);p = G.AdjList[i].firstarc;while (p != NULL){printf("-->%d(%d)", p->adjvex+1, p->weight);p = p->next;}}printf("\n");printf("\n-------------------------------\n");
}int TopologicalSort(ALGraph* G, int* topo)
{int i;int top = -1;//栈顶指针 int Gettop;//用于存储/获取栈的栈顶元素 int count = 0;//用于统计拓扑排序生成的结点数(若生成结点数 < 图的结点数,则代表图中有环,拓扑排序不成功) int stack[VertexMax] = { 0 };//栈 int indegree[VertexMax] = { 0 };//入度数组 struct ArcNode* p;//临时变量 //1.计算顶点入度,并存入indegree数组中for (i = 0; i < G->vexnum; i++){if (G->AdjList[i].firstarc != NULL){p = G->AdjList[i].firstarc;while (p != NULL){indegree[p->adjvex]++;p = p->next;}}}//2.初始化部分:将初始入度为0的顶点入栈for (i = 0; i < G->vexnum; i++){if (indegree[i] == 0){stack[++top] = i;//先将指针加一在进行存储 }}//3.拓扑排序int m = 0;while (top != -1)//栈不为空 {Gettop = stack[top--];//获取栈顶元素,并且栈顶指针减一 topo[m++] = Gettop;//printf(" %c(%d)",G->AdjList[Gettop].vertex,topo[m-1]);//输出栈顶元素 count++;p = G->AdjList[Gettop].firstarc;while (p != NULL){indegree[p->adjvex]--;if (indegree[p->adjvex] == 0){stack[++top] = p->adjvex;}p = p->next;}}//4.判断拓扑排序是否成功(生成结点数 < 图的结点数,则代表图中有环,拓扑排序不成功) if (count < G->vexnum){printf("TopologicalSort Failed!\n");return 0; //拓扑排序失败 }elsereturn 1; //拓扑排序成功   
}void CriticalPath(ALGraph* G)
{int i;int j, k;// <Vj,Vk>int e, l;//活动最早开始时间/活动最晚开始时间  int topo[VertexMax];//拓扑数组,用于存储拓扑排序结果(存储内容是每个结点的坐标) int ve[VertexMax]; //事件vi的最早发生时间 int vl[VertexMax]; //事件vi的最晚发生时间 struct ArcNode* p;//1.调用拓扑排序,检测图是否存在环 if (!TopologicalSort(G, topo))//若拓扑排序成功,topo数组也将处理完毕 {return;}//2.正拓扑排序,求出事件最早发生时间 for (i = 0; i < G->vexnum; i++)ve[i] = 0;for (i = 0; i < G->vexnum; i++){j = topo[i];//j为起始点,k为终点 p = G->AdjList[j].firstarc;//用指针p去依次寻找j的每一个邻接点 while (p){k = p->adjvex;if (ve[k] < ve[j] + p->weight)//根据j的邻接点k,不断更新ve[]的值(选出最大值,原理类似于选择排序) {ve[k] = ve[j] + p->weight;}p = p->next;}}//3.逆拓扑排序,求出事件最迟发生时间 for (i = 0; i < G->vexnum; i++)vl[i] = ve[G->vexnum - 1];for (i = G->vexnum - 1; i >= 0; i--){j = topo[i];p = G->AdjList[j].firstarc;//让p去依次查找邻接点 while (p){k = p->adjvex;if (vl[j] > vl[k] - p->weight)//根据j的邻接点k,不断更新vl[]的值(选出最小值,原理类似于选择排序){vl[j] = vl[k] - p->weight;}p = p->next;}}//输出ve[i] printf("\tve[i]:");for (i = 0; i < G->vexnum; i++){printf("\t%d", ve[i]);}printf("\n");//输出vl[i]printf("\tvl[i]:");for (i = 0; i < G->vexnum; i++){printf("\t%d", vl[i]);}printf("\n\n");//4.计算e和l,通过判断e是否等于l确定该活动是否是关键活动,从而确定关键路径for (i = 0; i < G->vexnum; i++){p = G->AdjList[i].firstarc;//让p去依次查找邻接点 while (p){j = p->adjvex;e = ve[i];//计算活动最早开始时间 e l = vl[j] - p->weight;//计算活动最晚开始时间 l if (e == l)//如果e=l,说明该活动是关键活动 {printf("\t%d->%d(%d)\n", G->AdjList[i].vertex, G->AdjList[j].vertex, p->weight);}p = p->next;}}printf("最短总工期:%d\n", ve[16]);}int main()
{ALGraph G;//声明顶点表 顶点数和边数 CreateDN(&G);//根据输入顶点数和边,生成有向图 print(G); //打印有向图邻接表 printf("关键路径:\n\n");CriticalPath(&G);  //输出关键路径 正向拓扑排序,逆向拓扑排序,确定关键路径,输出关键路径 system("pause"); return 0;
}

六、演示如何操作(注意输入信息,这里以上面AOE网为准输入)

6.1先输入AOE网的顶点个数和边数

n= 17  

e = 22

6.2输入顶点元素(复制粘贴即可)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

6.3输入边的信息(复制粘贴即可)

1 2,3

2 3,3

3 4,10

3 5,20

4 6,3

5 6,3

6 7,6

6 8,10

6 11,2

7 11,9

8 9,14

8 10,10

9 11,10

10 11,10

11 12,3

11 13,3

11 14,4

12 15,5

13 15,3

14 15,10

15 16,20

16 17,17

 6.5运行结果页面展示
6.5.1AOE输入信息图:

6.5.2图的邻接表示图: 

 

 6.5.3关键路径图和最短总工程时间:

七、总结与心得体会

     在进行AOE拓扑排序程序设计开发过程中,我深刻体会到了以下几点:1. 计划和组织能力的重要性:在开始课程设计之前,我充分意识到了计划和组织的重要性。我制定了详细的计划和时间表,明确了每个阶段的任务和时间节点。我将整个课程设计分解为多个小任务,并合理安排了每个任务的时间和资源。这样,我能够更好地掌握整个项目的进度,及时调整和安排,确保项目的顺利进行。2. 需求分析的重要性:在进行课程设计之前,我进行了充分的需求分析。我与用户和相关人员进行了深入的沟通,了解了他们的需求和期望。我通过用户故事、用户画像等方式,对用户需求进行了详细的描述和分析。这样,我能够更好地理解用户的需求,确定关键功能和优先级,为后续的设计和开发提供了明确的方向。3. 设计思维的应用:在课程设计的过程中,我运用了设计思维的方法和工具。我通过用户故事、用户画像、原型设计等方式,深入理解用户需求,提出创新的解决方案。我将用户体验放在首位,注重用户的感受和需求,设计出更符合用户期望的解决方案。4. 团队合作的重要性:在进行课程设计的过程中,我与团队成员密切合作。我们共同讨论问题,提出解决方案,分工合作,共同努力实现项目的目标。我们通过有效的沟通和协作,解决了许多困难和问题。团队合作的力量是巨大的,它能够激发出团队成员的创造力和潜力,取得更好的成果。5. 测试和调试的重要性:在课程设计完成后,我进行了充分的测试和调试。我对程序进行了功能测试,确保程序的各个功能正常运行。我进行了性能测试,检查程序的性能是否满足需求。我进行了安全测试,确保程序的安全性和稳定性。通过测试和调试,我发现了一些问题,并及时进行了修复和优化,确保程序的正确性和可靠性。

     总之,通过这次课程设计,我不仅学到了专业知识和技能,还培养了自己的计划和组织能力、分析和解决问题的能力、团队合作的能力等。我深刻体会到,课程设计是一个综合能力的考验,需要综合运用各种技能和方法,才能取得好的结果。同时,我也意识到,课程设计是一个不断学习和提升的过程,需要不断反思和总结,不断改进和完善自己。

成功需要付出努力和坚持,不要轻易放弃。

创作不易,感谢各位的支持,你们的点赞和关注是我不竭创作动力哦!互帮互助,成长你我他,小小善举,请相信世界会变得更美好!

 创作不易,如对你有帮助可以请作者喝咖啡哦!谢谢!

 

这篇关于设计求解AOE网关键路径程序(详细设计,附完整实现代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/551342

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo