ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关键路径(AOE网)

2022-01-30 07:31:07  阅读:219  来源: 互联网

标签:vexnum AOE ve int 路径 vl vex ++ 关键


求解步骤:

1.对顶点进行拓扑排序,求出每个事件(顶点)的最早发生时间(ve);

2.按照顶点的逆拓扑排序,求出每个事件的最晚发生时间(vl);

3.计算每个活动(弧)的最早开始时间(ee)和最晚开始时间(el);

4.找出关键活动,即 ee = el 的弧。

思考:

1.事件最早发生时间 = Max(前一事件最早发生时间 + 活动持续时间(dul));

2.事件最迟发生时间 = Min(后一事件最迟发生时间 + 活动持续时间);

3.活动最早开始时间 = 前一事件的最早发生时间;

4.活动最迟开始时间 = 后一事件的最迟发生时间 - 活动持续时间。

核心代码:

CriticalPath函数

 1 void CriticalPath(OLGraph* G)
 2 {
 3     int i = 0, j = 0, k = 0;
 4     int dut = 0;//活动持续时间
 5     int el = 0;//活动最迟开始时间
 6     int ee = 0;//活动最早开始时间
 7     int vl[MAXVEX] = { 0 };//事件最迟发生时间
 8     int ve[MAXVEX] = { 0 };//事件最早发生时间
 9     ArcNode* P = NULL;
10     SeqStack T;
11 
12     T.top = -1;
13     TopoSort(G, &T, ve);
14 
15     for (i = 0; i < G->vexnum; i++)
16     {
17         vl[i] = ve[G->vexnum - 1];
18     }
19 
20     while (T.top != -1)
21     {
22         PopStack(&T, &i);
23         //按拓扑逆序求各顶点的vl值
24         for (P = G->vex[i].tail; P; P = P->tnext)
25         {
26             j = P->headvex;
27             dut = P->weight;
28             if (vl[j] - dut < vl[i])//事件 i 最迟发生时间
29             {
30                 vl[i] = vl[j] - dut;
31             }
32         }
33     }
34 
35     printf("关键路径:\n");
36     for (i = 0; i < G->vexnum; i++)
37     {
38         P = G->vex[i].tail;
39         while (P)
40         {
41             k = P->headvex;
42             ee = ve[i];
43             el = vl[k] - P->weight;
44             if (ee == el)
45             {
46                 printf("%c--%c\n", G->vex[i].vexdata, G->vex[k].vexdata);
47             }
48             P = P->tnext;
49         }
50     }
51 }

 TopoSort函数

 1 void TopoSort(OLGraph* G, SeqStack* T, int* ve)
 2 {
 3     int i = 0, j = 0, count = 0;
 4     int indegree[MAXVEX] = { 0 };
 5     ArcNode* P = NULL;
 6     SeqStack S;
 7 
 8     //degree数组存放各顶点入度
 9     for (i = 0; i < G->vexnum; i++)
10     {
11         P = G->vex[i].head;
12         while (P)
13         {
14             indegree[i]++;
15             P = P->hnext;
16         }
17     }
18 
19     S.top = -1;//栈初始化
20     for (i = 0; i < G->vexnum; i++)
21     {
22         if (indegree[i] == 0)
23         {
24             PushStack(&S, i);
25         }
26     }
27 
28     while (S.top != -1)    //拓扑排序
29     {
30         count++;
31         PopStack(&S, &i);
32         PushStack(T, i);
33         for (P = G->vex[i].tail; P; P = P->tnext)
34         {
35             j = P->headvex;
36             if (--indegree[j] == 0)
37             {
38                 PushStack(&S, j);
39             }
40             if ((ve[i] + P->weight) > ve[j])//事件 j 的最早发生时间
41             {
42                 ve[j] = ve[i] + P->weight;
43             }
44         }
45     }
46 
47     if (count < G->vexnum)
48     {
49         printf("该有向图有回路");
50         exit(1);
51     }
52 }

源代码:

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #define MAXVEX 20
  5 
  6 typedef struct ArcNode
  7 {
  8     int weight;
  9     int tailvex, headvex;
 10     struct ArcNode *tnext, *hnext;
 11 }ArcNode;
 12 
 13 typedef struct VexNode
 14 {
 15     char vexdata;
 16     ArcNode *tail, *head;
 17 }VexNode;
 18 
 19 typedef struct
 20 {
 21     int vexnum, arcnum;
 22     VexNode vex[MAXVEX];
 23 }OLGraph;//十字链表
 24 
 25 typedef struct
 26 {
 27     int top;
 28     int elem[MAXVEX];
 29 }SeqStack;//定长顺序栈
 30 
 31 void PushStack(SeqStack* S, int vex)
 32 {
 33     if (S->top == MAXVEX - 1)
 34     {
 35         printf("栈满");
 36         exit(1);
 37     }
 38     else
 39     {
 40         S->top++;
 41         S->elem[S->top] = vex;
 42     }
 43 }
 44 
 45 void PopStack(SeqStack* S, int* vex)
 46 {
 47     if (S->top == -1)
 48     {
 49         printf("空栈");
 50         exit(1);
 51     }
 52     else
 53     {
 54         (*vex) = S->elem[S->top];
 55         S->top--;
 56     }
 57 }
 58 
 59 void TopoSort(OLGraph* G, SeqStack* T, int* ve)
 60 {
 61     int i = 0, j = 0, count = 0;
 62     int indegree[MAXVEX] = { 0 };
 63     ArcNode* P = NULL;
 64     SeqStack S;
 65 
 66     //degree数组存放各顶点入度
 67     for (i = 0; i < G->vexnum; i++)
 68     {
 69         P = G->vex[i].head;
 70         while (P)
 71         {
 72             indegree[i]++;
 73             P = P->hnext;
 74         }
 75     }
 76 
 77     S.top = -1;//栈初始化
 78     for (i = 0; i < G->vexnum; i++)
 79     {
 80         if (indegree[i] == 0)
 81         {
 82             PushStack(&S, i);
 83         }
 84     }
 85 
 86     while (S.top != -1)    //拓扑排序
 87     {
 88         count++;
 89         PopStack(&S, &i);
 90         PushStack(T, i);
 91         for (P = G->vex[i].tail; P; P = P->tnext)
 92         {
 93             j = P->headvex;
 94             if (--indegree[j] == 0)
 95             {
 96                 PushStack(&S, j);
 97             }
 98             if ((ve[i] + P->weight) > ve[j])//事件 j 的最早发生时间
 99             {
100                 ve[j] = ve[i] + P->weight;
101             }
102         }
103     }
104 
105     if (count < G->vexnum)
106     {
107         printf("该有向图有回路");
108         exit(1);
109     }
110 }
111 
112 void CriticalPath(OLGraph* G)
113 {
114     int i = 0, j = 0, k = 0;
115     int dut = 0;//活动持续时间
116     int el = 0;//活动最迟开始时间
117     int ee = 0;//活动最早开始时间
118     int vl[MAXVEX] = { 0 };//事件最迟发生时间
119     int ve[MAXVEX] = { 0 };//事件最早发生时间
120     ArcNode* P = NULL;
121     SeqStack T;
122 
123     T.top = -1;
124     TopoSort(G, &T, ve);
125 
126     for (i = 0; i < G->vexnum; i++)
127     {
128         vl[i] = ve[G->vexnum - 1];
129     }
130 
131     while (T.top != -1)
132     {
133         PopStack(&T, &i);
134         //按拓扑逆序求各顶点的vl值
135         for (P = G->vex[i].tail; P; P = P->tnext)
136         {
137             j = P->headvex;
138             dut = P->weight;
139             if (vl[j] - dut < vl[i])//事件 i 最迟发生时间
140             {
141                 vl[i] = vl[j] - dut;
142             }
143         }
144     }
145 
146     printf("关键路径:\n");
147     for (i = 0; i < G->vexnum; i++)
148     {
149         P = G->vex[i].tail;
150         while (P)
151         {
152             k = P->headvex;
153             ee = ve[i];
154             el = vl[k] - P->weight;
155             if (ee == el)
156             {
157                 printf("%c--%c\n", G->vex[i].vexdata, G->vex[k].vexdata);
158             }
159             P = P->tnext;
160         }
161     }
162 }
163 
164 //返回图G中顶点vex的位置
165 int LocateVex(OLGraph* G, char vex)
166 {
167     int i = 0;
168     for (i = 0; i < G->vexnum; i++)
169     {
170         if (G->vex[i].vexdata == vex)
171         {
172             return i;
173         }
174     }
175     return -1;
176 }
177 
178 void Create(OLGraph* G)
179 {
180     int weight = 0;
181     int i = 0, j = 0, k = 0;
182     char vex1 = 0, vex2 = 0;
183     ArcNode *P = NULL, * Pre = NULL;
184 
185     printf("请输入顶点数和边数(逗号分隔):");
186     scanf("%d%*c%d", &G->vexnum, &G->arcnum);
187     for (i = 0; i < G->vexnum; i++)
188     {
189         printf("请输入第%d个顶点:", i + 1);
190         scanf(" %c", &G->vex[i].vexdata);
191         G->vex[i].head = G->vex[i].tail = NULL;
192     }
193     for (k = 0; k < G->arcnum; k++)
194     {
195         printf("请输入第%d条边的弧尾、头和权值(逗号分隔):", k + 1);
196         scanf(" %c%*c%c%*c%d", &vex1, &vex2, &weight);
197         i = LocateVex(G, vex1);
198         j = LocateVex(G, vex2);
199         P = (ArcNode*)calloc(1, sizeof(ArcNode));
200         P->tailvex = i;
201         P->headvex = j;
202         P->weight = weight;
203         //在 j 为弧头的链表尾链接上P结点
204         if (!G->vex[j].head)
205         {
206             G->vex[j].head = P;
207         }
208         else
209         {
210             Pre = G->vex[j].head;
211             while (Pre->hnext)
212             {
213                 Pre = Pre->hnext;
214             }
215             Pre->hnext = P;
216         }
217         //在 i 为弧尾的链表尾链接上P结点
218         if (!G->vex[i].tail)
219         {
220             G->vex[i].tail = P;
221         }
222         else
223         {
224             Pre = G->vex[i].tail;
225             while (Pre->tnext)
226             {
227                 Pre = Pre->tnext;
228             }
229             Pre->tnext = P;
230         }
231     }
232 }
233 
234 int main(void)
235 {
236     OLGraph G;
237     Create(&G);
238     CriticalPath(&G);
239     system("pause");
240     return 0;
241 }
源代码

 

标签:vexnum,AOE,ve,int,路径,vl,vex,++,关键
来源: https://www.cnblogs.com/lvhui123/p/15856297.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有