图的其他相关知识点和源码分享可以参考之前的博客:
《数据结构与算法基础-学习-23-图之邻接矩阵与邻接表》,
《数据结构与算法基础-学习-24-图的遍历之DFS(深度优先搜索)和BFS(广度优先搜索)》,
《数据结构与算法基础-学习-25-图之MST(最小代价生成树)之Prim(普利姆)算法》,
《数据结构与算法基础-学习-26-图之MST(最小代价生成树)之Kluskal(克鲁斯卡尔)算法》,
《数据结构与算法基础-学习-27-图之最短路径之Dijkstra(迪杰斯特拉)算法》,
《数据结构与算法基础-学习-28-图之拓扑排序》
1、把工程计划表示为边表示活动的网络,即AOE网,用顶点表示事件,弧表示活动,弧的权表示活动持续时间。
2、事件表示在它之前的活动已经完成,在它之后的活动可以开始。
3、关键路径:路径长度最长的路径。
4、路径长度:路径上个活动持续时间之和。
1、关键路径表示一个工程的话,例如做饭,开始做饭表示整个工程开始,结束做饭表示整个工程结束,也就是说只一个起点或者叫源点(入度为0的顶点),只有一个终点或者叫汇点(出度为0的顶点)。
2、我们在进行关键路径计算时,需要判断:
(1)这是不是一个有向图。
(2)是不是无环(可以通过拓扑排序来判断)。
(3)是不是只有一个源点和一个终点。
1、完成整项工程至少需要花费多少时间。
2、哪些活动是影响工程进度的关键。
名称 | 描述 |
ve(vj) | 表示事件(顶点)vj的最早发生时间。 |
vl(vj) | 表示事件(顶点)vj的最迟发生时间。 |
e(i) | 表示活动(弧)ai的最早开始时间。 |
l(i) | 表示活动(弧)ai的最迟开始时间。 |
1、ve(j) = Max(ve(i) + w(i,j)),表示i->j的情况下。
2、vl(i) = Min(vl(j) - w(i,j)),表示i->j的情况下。
3、e(i) = ve(j),表示j->k,第i各活动的情况下。
4、l(i) = vl(k) - w(j,k),表示j->k,第i各活动的情况下。
我这边是结合邻接矩阵实现的,生成邻接矩阵如下:
2023-8-23 9:33:49--[ Debug ]--Printf AMGraph :
VertexArray : [0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ]
ArcArray :
0 : [32767 ,6 ,4 ,5 ,32767 ,32767 ,32767 ,32767 ,32767 ]
1 : [32767 ,32767 ,32767 ,32767 ,1 ,32767 ,32767 ,32767 ,32767 ]
2 : [32767 ,32767 ,32767 ,32767 ,1 ,32767 ,32767 ,32767 ,32767 ]
3 : [32767 ,32767 ,32767 ,32767 ,32767 ,2 ,32767 ,32767 ,32767 ]
4 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,9 ,7 ,32767 ]
5 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,4 ,32767 ]
6 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,2 ]
7 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,4 ]
8 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ]
InduityArray : [0 ,1 ,1 ,1 ,2 ,1 ,1 ,2 ,2 ]
OutdegreeArray : [3 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,0 ]
CurVertexNum : 9
CurArcNum : 11
在之前分享的邻接矩阵代码的基础上增加了入度InduityArray和出度OutdegreeArray,为了方便计算。
2023-8-23 9:46:19--[ Debug ]--SqQueue Data :
Data : [ 0 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
初始化一个事件最早发生的队列,不一定是队列,数组也行。源点的最早发生时间是0,填入到队列中,其他值还不确定所以先初始化-1。
2023-8-23 9:56:37--[ Debug ]--Printf SqStack
Data : [ 0 ]
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf HashTable
DataNum : 1 , [ (0,(nil)) ]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
TotalDataNum : 1
ArrayMaxLen : 9
还需要两个访问数组,分别是用哈希表和栈实现的,为什么要用两个呢,因为一个用来快速访问节点是否访问过。一个用来进行节点回溯。后面看着看着就会领悟的。我们先把访问过的源点0压入两个访问数组中。
进入一个大循环,循环退出条件为所有节点都被访问过。
栈中压出第一个节点0,然后我们在邻接矩阵中扫描第0行。我们可以扫描到三个边a1、a2、a3,且他们对应的终点V1、V2、V3的入度都是1,根据公式ve(j) = Max(ve(i) + w(i,j))。
(1)0->1,ve(1) = Max(ve(0) + w(0,1)) = 0 + 6 = 6
(2)0->2,ve(2) = Max(ve(0) + w(0,2)) = 0 + 4 = 4
(3)0->3,ve(3) = Max(ve(0) + w(0,3)) = 0 + 5 = 5
这三个点都访问过,我们都压入访问数组中,具体如下:
2023-8-23 9:56:37--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,4 ,5 ,-1 ,-1 ,-1 ,-1 ,-1 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf SqStack
Data : [ 1 ,2 ,3 ]
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf HashTable
DataNum : 1 , [ (0,(nil)) ]
DataNum : 1 , [ (1,(nil)) ]
DataNum : 1 , [ (2,(nil)) ]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
TotalDataNum : 4
ArrayMaxLen : 9
第0行都已经遍历完,我们压出栈的下一个元素3,然后我们在邻接矩阵中扫描第3行。
我们可以扫描到边a6,且对应的终点V6的入度是1,根据公式ve(j) = Max(ve(i) + w(i,j))。
(1)3->5,ve(5) = Max(ve(3) + w(3,5)) = 5 + 2 = 7
这个点访问过,我们压入访问数组中,具体如下:
2023-8-23 9:56:37--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,4 ,5 ,-1 ,7 ,-1 ,-1 ,-1 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf SqStack
Data : [ 1 ,2 ,5 ]
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf HashTable
DataNum : 1 , [ (0,(nil)) ]
DataNum : 1 , [ (1,(nil)) ]
DataNum : 1 , [ (2,(nil)) ]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 0 , [(nil)]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
TotalDataNum : 5
ArrayMaxLen : 9
第3行都已经遍历完,我们压出栈的下一个元素5,然后我们在邻接矩阵中扫描第5行。
我们可以扫描到边a9,且对应的终点V7的入度是2,且V7的另一条入度边a8的起点V4没有访问过,所以不能计算V7的事件最早发生时间。
具体如下:
2023-8-23 9:56:37--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,4 ,5 ,-1 ,7 ,-1 ,-1 ,-1 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf SqStack
Data : [ 1 ,2 ]
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf HashTable
DataNum : 1 , [ (0,(nil)) ]
DataNum : 1 , [ (1,(nil)) ]
DataNum : 1 , [ (2,(nil)) ]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 0 , [(nil)]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
TotalDataNum : 5
ArrayMaxLen : 9
第5行都已经遍历完,我们压出栈的下一个元素2,然后我们在邻接矩阵中扫描第2行。
我们可以扫描到边a5,且对应的终点V4的入度是2,V4入度边的起点V1和V2我们都是访问过的,可以计算事件最早发生时间,根据公式ve(j) = Max(ve(i) + w(i,j))。
(1)1->4,2->4,ve(4) = Max(ve(1) + w(1,4),ve(2) + w(2,4)) = Max(6 +1,4 + 1) = Max(7,5) = 7
这个点访问过,我们压入访问数组中,具体如下:
2023-8-23 9:56:37--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,4 ,5 ,7 ,7 ,-1 ,-1 ,-1 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf SqStack
Data : [ 1 ,4 ]
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf HashTable
DataNum : 1 , [ (0,(nil)) ]
DataNum : 1 , [ (1,(nil)) ]
DataNum : 1 , [ (2,(nil)) ]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 1 , [ (4,(nil)) ]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
TotalDataNum : 6
ArrayMaxLen : 9
第2行都已经遍历完,我们压出栈的下一个元素4,然后我们在邻接矩阵中扫描第4行。
我们可以扫描到边a7,a8,V6的入度是1我们可以直接计算事件最早发生,a8对应的终点V7的入度是2,V7入度边的起点V4和V5我们都是访问过的,可以计算事件最早发生时间,根据公式ve(j) = Max(ve(i) + w(i,j))。
(1)4->6,ve(6) = Max(ve(4) + w(4,6)) = Max(7 + 9) = 16
(2)4->7,5->7,ve(7) = Max(ve(4) + w(4,7),ve(5) + w(5,7)) = Max(7 +7,7 + 4) = Max(14,11) = 14
这些点访问过,我们压入访问数组中,具体如下:
2023-8-23 9:56:37--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,4 ,5 ,7 ,7 ,16 ,14 ,-1 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf SqStack
Data : [ 1 ,6 ,7 ]
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf HashTable
DataNum : 1 , [ (0,(nil)) ]
DataNum : 1 , [ (1,(nil)) ]
DataNum : 1 , [ (2,(nil)) ]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 1 , [ (4,(nil)) ]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 1 , [ (6,(nil)) ]
DataNum : 1 , [ (7,(nil)) ]
DataNum : 0 , [(nil)]
TotalDataNum : 8
ArrayMaxLen : 9
第4行都已经遍历完,我们压出栈的下一个元素7,然后我们在邻接矩阵中扫描第7行。
我们可以扫描到边a11,V8入度边的起点V6和V7我们都是访问过的,可以计算事件最早发生时间,根据公式ve(j) = Max(ve(i) + w(i,j))。
(1)6->8,7->8,ve(8) = Max(ve(6) + w(6,8),ve(7) + w(7,8)) = Max(16 +2,14 + 4) = Max(18,18) = 18
这些点访问过,我们压入访问数组中,具体如下:
2023-8-23 9:56:37--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,4 ,5 ,7 ,7 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf SqStack
Data : [ 1 ,6 ,8 ]
Flag : INT_TYPE_FLAG
2023-8-23 9:56:37--[ Debug ]--Printf HashTable
DataNum : 1 , [ (0,(nil)) ]
DataNum : 1 , [ (1,(nil)) ]
DataNum : 1 , [ (2,(nil)) ]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 1 , [ (4,(nil)) ]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 1 , [ (6,(nil)) ]
DataNum : 1 , [ (7,(nil)) ]
DataNum : 1 , [ (8,(nil)) ]
TotalDataNum : 9
ArrayMaxLen : 9
所有点被访问完了,事件最早发生时间也就被算出来了。
事件最迟发生时间和事件最早发生时间的计算上的区别:
1、事件最早发生时间是从起点到源点,事件最迟发生时间反之从源点到起点。
2、事件最早发生时间是横向扫描邻接矩阵,事件最迟发生时间反之是纵向扫描。
3、事件最早发生时间是根据入度进行相关判断,事件最迟发生时间反之是根据出度判断。
源点的事件最迟发生时间和起点是一样的,都是18,我们先填入18和节点8,如下:
2023-8-23 14:6:28--[ Debug ]--SqQueue Data :
Data : [ -1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf SqStack
Data : [ 8 ]
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf HashTable
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 1 , [ (8,(nil)) ]
TotalDataNum : 1
ArrayMaxLen : 9
进入循环,我们从栈中压出节点8,开始纵向扫描节点8,发现6和7节点,且他们的出度都是1,根据公式vl(j) = Min(vl(j) - w(i,j)),进行计算:
(1)6->8,vl(6) = Min(vl(8) - w(6,8)) = Min(18 - 2) = 16
(2)7->8,vl(7) = Min(vl(8) - w(7,8)) = Min(18 - 4) = 14
这些点访问过,我们压入访问数组中,具体如下:
2023-8-23 14:6:28--[ Debug ]--SqQueue Data :
Data : [ -1 ,-1 ,-1 ,-1 ,-1 ,-1 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf SqStack
Data : [ 6 ,7 ]
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf HashTable
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 1 , [ (6,(nil)) ]
DataNum : 1 , [ (7,(nil)) ]
DataNum : 1 , [ (8,(nil)) ]
TotalDataNum : 3
ArrayMaxLen : 9
继续进入循环,我们从栈中压出节点7,开始纵向扫描节点7,发现4和5节点,5的出度是1,可以直接计算,4的出度是2,且节点6和7都已经访问过了,也可以计算,根据公式vl(j) = Min(vl(j) - w(i,j)),进行计算:
(1)4->6,4->7,vl(4) = Min(vl(6) - w(4,6),vl(7) - w(4,7)) = Min(16 - 9,14 - 7) = 7
(2)5->7,vl(5) = Min(vl(7) - w(5,7)) = Min(14 - 4) = 10
这些点访问过,我们压入访问数组中,具体如下:
2023-8-23 14:6:28--[ Debug ]--SqQueue Data :
Data : [ -1 ,-1 ,-1 ,-1 ,7 ,10 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf SqStack
Data : [ 6 ,4 ,5 ]
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf HashTable
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 1 , [ (4,(nil)) ]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 1 , [ (6,(nil)) ]
DataNum : 1 , [ (7,(nil)) ]
DataNum : 1 , [ (8,(nil)) ]
TotalDataNum : 5
ArrayMaxLen : 9
继续进入循环,我们从栈中压出节点5,开始纵向扫描节点5,发现3节点,3的出度是1,可以直接计算,根据公式vl(j) = Min(vl(j) - w(i,j)),进行计算:
(1)3->5,vl(3) = Min(vl(5) - w(3,5)) = Min(10 - 2) = 8
这些点访问过,我们压入访问数组中,具体如下:
2023-8-23 14:6:28--[ Debug ]--SqQueue Data :
Data : [ -1 ,-1 ,-1 ,8 ,7 ,10 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf SqStack
Data : [ 6 ,4 ,3 ]
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf HashTable
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 1 , [ (4,(nil)) ]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 1 , [ (6,(nil)) ]
DataNum : 1 , [ (7,(nil)) ]
DataNum : 1 , [ (8,(nil)) ]
TotalDataNum : 6
ArrayMaxLen : 9
继续进入循环,我们从栈中压出节点3,开始纵向扫描节点3,发现0节点,0的出度是3,发现1号点没有访问过直接退出当前循环,后面的2,3不需要扫描,因为一个没访问就不可以进行计算。
具体如下:
2023-8-23 14:6:28--[ Debug ]--SqQueue Data :
Data : [ -1 ,-1 ,-1 ,8 ,7 ,10 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf SqStack
Data : [ 6 ,4 ]
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf HashTable
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 0 , [(nil)]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 1 , [ (4,(nil)) ]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 1 , [ (6,(nil)) ]
DataNum : 1 , [ (7,(nil)) ]
DataNum : 1 , [ (8,(nil)) ]
TotalDataNum : 6
ArrayMaxLen : 9
继续进入循环,我们从栈中压出节点4,开始纵向扫描节点4,发现1,2节点,且出度都是1,可以直接计算,根据公式vl(j) = Min(vl(j) - w(i,j)),进行计算:
(1)1->4,vl(1) = Min(vl(4) - w(1,4)) = Min(7 - 1) = 6
(2)2->4,vl(2) = Min(vl(4) - w(2,4)) = Min(7 - 1) = 6
这些点访问过,我们压入访问数组中,具体如下:
2023-8-23 14:6:28--[ Debug ]--SqQueue Data :
Data : [ -1 ,6 ,6 ,8 ,7 ,10 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf SqStack
Data : [ 6 ,1 ,2 ]
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf HashTable
DataNum : 0 , [(nil)]
DataNum : 1 , [ (1,(nil)) ]
DataNum : 1 , [ (2,(nil)) ]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 1 , [ (4,(nil)) ]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 1 , [ (6,(nil)) ]
DataNum : 1 , [ (7,(nil)) ]
DataNum : 1 , [ (8,(nil)) ]
TotalDataNum : 8
ArrayMaxLen : 9
继续进入循环,我们从栈中压出节点2,开始纵向扫描节点2,发现0节点,且出度都是3,1,2,3节点都被访问过,可以直接计算,根据公式vl(j) = Min(vl(j) - w(i,j)),进行计算:
(1)0->1,0->2,0->3,vl(0) = Min(vl(1) - w(0,1),vl(2) - w(0,2),vl(3) - w(0,4)) = Min(6 - 6,6 - 4,8 - 5) = Min(0,2,3) = 0
这些点访问过,我们压入访问数组中,具体如下:
2023-8-23 14:6:28--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,6 ,8 ,7 ,10 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf SqStack
Data : [ 6 ,1 ,0 ]
Flag : INT_TYPE_FLAG
2023-8-23 14:6:28--[ Debug ]--Printf HashTable
DataNum : 1 , [ (0,(nil)) ]
DataNum : 1 , [ (1,(nil)) ]
DataNum : 1 , [ (2,(nil)) ]
DataNum : 1 , [ (3,(nil)) ]
DataNum : 1 , [ (4,(nil)) ]
DataNum : 1 , [ (5,(nil)) ]
DataNum : 1 , [ (6,(nil)) ]
DataNum : 1 , [ (7,(nil)) ]
DataNum : 1 , [ (8,(nil)) ]
TotalDataNum : 9
ArrayMaxLen : 9
所有点被访问完了,事件最迟发生时间也就被算出来了。
有了事件最迟发生时间和事件最早发生时间,活动最早开始、最迟时间,关键路径就好算了,直接套公式。
我们一条边一条边来。
关键路径我是活动最早开始事件 - 活动最迟开始事件,所以是负值,但不影响取关键路径。
弧信息 | 活动最早开始事件 | 活动最迟开始事件 | 关键路径 |
a1边,0->1 | e(1) = ve(0) = 0 | l(1) = vl(1) - w(0,1) = 0 |
0 - 0 = 0 |
a2边,0->2 | e(2) = ve(0) = 0 | l(2) = vl(2) - w(0,2) = 2 |
0 - 2 = -2 |
a3边,0->3 | e(3) = ve(0) = 0 | l(3) = vl(3) - w(0,3) = 3 |
0 - 3 = -3 |
a4边,1->4 | e(4) = ve(1) = 6 | l(4) = vl(4) - w(1,4) = 6 |
6 - 6 = 0 |
a5边,2->4 | e(5) = ve(2) = 4 | l(5) = vl(4) - w(2,4) = 6 |
4 - 6 = -2 |
a6边,3->5 | e(6) = ve(3) = 5 | l(6) = vl(5) - w(3,5) = 8 |
5 - 8 = -3 |
a7边,4->6 | e(7) = ve(4) = 7 | l(7) = vl(6) - w(4,6) = 7 |
7 - 7 = 0 |
a8边,4->7 | e(8) = ve(4) = 7 | l(8) = vl(7) - w(4,7) = 7 |
7 - 7 = 0 |
a9边,5->7 | e(9) = ve(5) = 7 | l(9) = vl(7) - w(5,7) = 10 |
7 - 10 = -3 |
a10边,6->8 | e(10) = ve(6) = 16 | l(10) = vl(8) - w(6,8) = 16 |
16 - 16 = 0 |
a11边,7->8 | e(11) = ve(7) = 14 | l(11) = vl(8) - w(7,8) = 14 |
14 - 14 = 0 |
#define CRITICAL_PATH_INIT_VAL -1
typedef struct CriticalPathEventSt
{
SqQueue* VertexEarlyQueue; //事件最早发生权值或时间的队列。公式:ve(j) = Max(ve(i) + w(i,j)),表示i->j的情况下。
SqQueue* VertexLateQueue; //事件最晚发生权值或时间的队列。公式:vl(i) = Min(vl(j) - w(i,j)),表示i->j的情况下。
}CriticalPathEventSt;
typedef struct CriticalPathActivitySt
{
SqQueue* ArcStartVertexQueue; //存放活动(弧)的起始节点索引的队列。
SqQueue* ArcEndVertexQueue; //存放活动(弧)的结束节点索引的队列。
SqQueue* ArcEarlyQueue; //活动最早发生权值或时间的队列。公式:e(i) = ve(j),表示j->k,第i各活动的情况下。
SqQueue* ArcLateQueue; //活动最晚发生权值或时间的队列。公式:l(i) = vl(k) - w(j,k),表示j->k,第i各活动的情况下。
SqQueue* CriticalPathQueue; //关键路径的队列。
}CriticalPathActivitySt;
typedef struct CriticalPathSt
{
CriticalPathEventSt* Event;
CriticalPathActivitySt* Activity;
}CriticalPathSt;
Status InitCriticalPathEventSt(CriticalPathEventSt** CpEvent, VertexIndexType ArrayMaxLen)
{
JudgeAllNullPointer(CpEvent);
*CpEvent = (CriticalPathEventSt*)MyMalloc(sizeof(CriticalPathEventSt));
(*CpEvent)->VertexEarlyQueue = NULL;
(*CpEvent)->VertexLateQueue = NULL;
InitSqQueue(&((*CpEvent)->VertexEarlyQueue),ArrayMaxLen,INT_TYPE_FLAG);
InitSqQueue(&((*CpEvent)->VertexLateQueue),ArrayMaxLen,INT_TYPE_FLAG);
LogFormat(Debug, "%s\n", "Init Critical Path Event St OK.");
return SuccessFlag;
}
Status DestroyCriticalPathEventSt(CriticalPathEventSt** CpEvent)
{
JudgeAllNullPointer(*CpEvent);
DestroySqQueue(&((*CpEvent)->VertexEarlyQueue));
DestroySqQueue(&((*CpEvent)->VertexLateQueue));
(*CpEvent)->VertexEarlyQueue = NULL;
(*CpEvent)->VertexLateQueue = NULL;
free(*CpEvent);
*CpEvent = NULL;
LogFormat(Debug, "%s\n", "Destroy Critical Path Event St OK.");
return SuccessFlag;
}
Status InitCriticalPathActivitySt(CriticalPathActivitySt** CpActivity, VertexIndexType ArrayMaxLen)
{
JudgeAllNullPointer(CpActivity);
*CpActivity = (CriticalPathActivitySt*)MyMalloc(sizeof(CriticalPathActivitySt));
(*CpActivity)->ArcStartVertexQueue = NULL;
(*CpActivity)->ArcEndVertexQueue = NULL;
(*CpActivity)->ArcEarlyQueue = NULL;
(*CpActivity)->ArcLateQueue = NULL;
(*CpActivity)->CriticalPathQueue = NULL;
InitSqQueue(&((*CpActivity)->ArcStartVertexQueue),ArrayMaxLen,INT_TYPE_FLAG);
InitSqQueue(&((*CpActivity)->ArcEndVertexQueue),ArrayMaxLen,INT_TYPE_FLAG);
InitSqQueue(&((*CpActivity)->ArcEarlyQueue),ArrayMaxLen,INT_TYPE_FLAG);
InitSqQueue(&((*CpActivity)->ArcLateQueue),ArrayMaxLen,INT_TYPE_FLAG);
InitSqQueue(&((*CpActivity)->CriticalPathQueue),ArrayMaxLen,INT_TYPE_FLAG);
LogFormat(Debug, "%s\n", "Init Critical Path Activity St OK.");
return SuccessFlag;
}
Status DestroyCriticalPathActivitySt(CriticalPathActivitySt** CpActivity)
{
JudgeAllNullPointer(*CpActivity);
DestroySqQueue(&((*CpActivity)->ArcStartVertexQueue));
DestroySqQueue(&((*CpActivity)->ArcEndVertexQueue));
DestroySqQueue(&((*CpActivity)->ArcEarlyQueue));
DestroySqQueue(&((*CpActivity)->ArcLateQueue));
DestroySqQueue(&((*CpActivity)->CriticalPathQueue));
(*CpActivity)->ArcStartVertexQueue = NULL;
(*CpActivity)->ArcEndVertexQueue = NULL;
(*CpActivity)->ArcEarlyQueue = NULL;
(*CpActivity)->ArcLateQueue = NULL;
(*CpActivity)->CriticalPathQueue = NULL;
free(*CpActivity);
*CpActivity = NULL;
LogFormat(Debug, "%s\n", "Destroy Critical Path Activity St OK.");
return SuccessFlag;
}
Status InitCriticalPathSt(CriticalPathSt** CP, AMGraph* AMG)
{
JudgeAllNullPointer(CP);
JudgeAllNullPointer(AMG);
if (AMG->DirectionFlag == NET_UNDIRECTION_FLAG)//关键路径只支持有向网。
{
LogFormat(Warning,"Critical Path Init Only Support Directed Net, Exit.");
return FailFlag;
}
*CP = (CriticalPathSt*)MyMalloc(sizeof(CriticalPathSt));
(*CP)->Event = NULL;
(*CP)->Activity = NULL;
InitCriticalPathEventSt(&((*CP)->Event), AMG->CurVertexNum);
InitCriticalPathActivitySt(&((*CP)->Activity), AMG->CurArcNum);
LogFormat(Debug, "%s\n", "Init Critical Path St OK.");
return SuccessFlag;
}
Status DestroyCriticalPathSt(CriticalPathSt** CP)
{
JudgeAllNullPointer(*CP);
DestroyCriticalPathEventSt(&((*CP)->Event));
DestroyCriticalPathActivitySt(&((*CP)->Activity));
(*CP)->Event = NULL;
(*CP)->Activity = NULL;
free(*CP);
*CP = NULL;
LogFormat(Debug, "%s\n", "Destroy Critical Path St OK.");
return SuccessFlag;
}
//检查邻接矩阵是否适用于关键路径算法,只有一个起点和一个汇点。
//检查起点是否合法。
Status CheckCriticalPathAmgIllegal(AMGraph* AMG, VertexIndexType StartVertexIndex)
{
JudgeAllNullPointer(AMG);
//判断起始节点StartVertexIndex是否是在顶点索引范围内,不在,退出函数。
if (StartVertexIndex < 0 || StartVertexIndex >= (AMG->CurVertexNum))
{
LogFormat(Debug,"StartVertexIndex : %d Is Illegal Node.\n",StartVertexIndex);
return FailFlag;
}
VertexIndexType i;
VertexIndexType StartVertexNum = 0; //起点个数
VertexIndexType EndVertexNum = 0; //汇点个数
VertexIndexType TmpStartVertexIndex = -1; //起点索引,和StartVertexIndex做对比。
VertexIndexType TmpEndVertexIndex = -1; //汇点索引。
for ( i = 0; i < AMG->CurVertexNum; i++)
{
if (AMG->InduityArray[i] == 0)
{
StartVertexNum++;
TmpStartVertexIndex = i;
}
if (StartVertexNum > 1)
{
LogFormat(Debug,"Adjacency Matrix Graph Has Multiple Starting Vertex.\n");
return FailFlag;
}
}
if (StartVertexNum != TmpStartVertexIndex)
{
LogFormat(Debug,"StartVertexIndex : %d ,It Has Precursor Vertex, Check Adjacency Matrix Graph Fail\n",StartVertexIndex);
}
for ( i = 0; i < AMG->CurVertexNum; i++)
{
if (AMG->OutdegreeArray[i] == 0)
{
EndVertexNum++;
TmpEndVertexIndex = i;
}
if (EndVertexNum > 1)//汇点数量大于1,不符合关键路径的场景。
{
LogFormat(Debug,"Adjacency Matrix Graph Has Multiple Ending Vertex, Check Adjacency Matrix Graph Fail\n");
return FailFlag;
}
}
LogFormat(Debug, "(StartVertexIndex : %d,EndVertexIndex : %d), Check Adjacency Matrix Graph OK.\n",TmpStartVertexIndex,TmpEndVertexIndex);
return SuccessFlag;
}
//检查某个顶点的入度顶点是否都存在于访问哈希表中。
//都被访问过返回:SuccessFlag。反之返回:FailFlag。
Status CheckInduityVertexExists(AMGraph* AMG, VertexIndexType VertexIndex, MyHashTable* VisitedHashTable, SqQueue* VertexEarlyQueue, WeightType* MaxWeight)
{
JudgeAllNullPointer(AMG);
JudgeAllNullPointer(VisitedHashTable);
VertexIndexType i;
VertexIndexType Induity = AMG->InduityArray[VertexIndex];
WeightType PreVertexWeight = 0;//上一个节点的权值
if (Induity == 0)
{
LogFormat(Error,"Internal Logic Error, VertexIndex(%d) Induity(0).\n",VertexIndex);
return FailFlag;
}
HashTabElemType HashValue;
for (i = 0; i < AMG->CurVertexNum; i++)//入度为复数的情况
{
if (AMG->ArcArray[i][VertexIndex] != MAX_INT_TYPE_NUM)
{
if (SearchHashTable(VisitedHashTable,&i,&HashValue) == SuccessFlag)
{
ReadSqQueue(VertexEarlyQueue,i,&PreVertexWeight);
if (Induity == AMG->InduityArray[VertexIndex])//给MaxWeight赋予初值
{
*MaxWeight = AMG->ArcArray[i][VertexIndex] + PreVertexWeight;
}
else
{
*MaxWeight = MY_MAX(*MaxWeight,AMG->ArcArray[i][VertexIndex] + PreVertexWeight);
}
Induity--;
}
else
{
return FailFlag;
}
}
if (Induity == 0)//说明所有入度点全部被找到,下面的顶点不需要再扫描,跳出循环。
{
break;
}
}
return SuccessFlag;
}
//检查某个顶点的出度顶点是否都存在于访问哈希表中。
//都被访问过返回:SuccessFlag。反之返回:FailFlag。
Status CheckOutDegreeVertexExists(AMGraph* AMG, VertexIndexType VertexIndex, MyHashTable* VisitedHashTable, SqQueue* VertexLateQueue, WeightType* MinWeight)
{
JudgeAllNullPointer(AMG);
JudgeAllNullPointer(VisitedHashTable);
VertexIndexType i;
VertexIndexType OutDegree = AMG->OutdegreeArray[VertexIndex];
WeightType PreVertexWeight = 0;//上一个节点的权值
if (OutDegree == 0)
{
LogFormat(Error,"Internal Logic Error, VertexIndex(%d) OutDegree(0).\n",VertexIndex);
return FailFlag;
}
HashTabElemType HashValue;
for (i = 0; i < AMG->CurVertexNum; i++)//出度为复数的情况
{
if (AMG->ArcArray[VertexIndex][i] != MAX_INT_TYPE_NUM)
{
if (SearchHashTable(VisitedHashTable,&i,&HashValue) == SuccessFlag)
{
ReadSqQueue(VertexLateQueue,i,&PreVertexWeight);
if (OutDegree == AMG->OutdegreeArray[VertexIndex])//给MinWeight赋予初值
{
*MinWeight = PreVertexWeight - AMG->ArcArray[VertexIndex][i];
}
else
{
*MinWeight = MY_MIN(*MinWeight,PreVertexWeight - AMG->ArcArray[VertexIndex][i]);
}
OutDegree--;
}
else
{
return FailFlag;
}
}
if (OutDegree == 0)//说明所有出度点全部被找到,下面的顶点不需要再扫描,跳出循环。
{
break;
}
}
return SuccessFlag;
}
Status ComputeCriticalPath(CriticalPathSt* CP,AMGraph* AMG, VertexIndexType StartVertexIndex)
{
JudgeAllNullPointer(CP);
JudgeAllNullPointer(AMG);
if (CheckCriticalPathAmgIllegal(AMG, StartVertexIndex) == FailFlag)
{
return FailFlag;
}
ComputeCriticalPathEvent(CP, AMG, StartVertexIndex);
ComputeCriticalPathActivity(CP, AMG);
LogFormat(Debug, "%s\n", "Compute Critical Path OK.");
return SuccessFlag;
}
Status ComputeCriticalPathActivity(CriticalPathSt* CP,AMGraph* AMG)
{
JudgeAllNullPointer(CP);
JudgeAllNullPointer(AMG);
VertexIndexType i;
VertexIndexType j;
WeightType VertexEarlyWeight;
WeightType VertexLateWeight;
WeightType CriticalPathWeight;
for (i = 0; i < AMG->CurVertexNum; i++)
{
for (j = 0; j < AMG->CurVertexNum; j++)
{
if (AMG->ArcArray[i][j] != MAX_INT_TYPE_NUM)
{
EnterSqQueue(CP->Activity->ArcStartVertexQueue,&i);
EnterSqQueue(CP->Activity->ArcEndVertexQueue,&j);
ReadSqQueue(CP->Event->VertexEarlyQueue,i,&VertexEarlyWeight);
EnterSqQueue(CP->Activity->ArcEarlyQueue,&VertexEarlyWeight);
ReadSqQueue(CP->Event->VertexLateQueue,j,&VertexLateWeight);
VertexLateWeight = VertexLateWeight - AMG->ArcArray[i][j];
EnterSqQueue(CP->Activity->ArcLateQueue,&VertexLateWeight);
CriticalPathWeight = VertexEarlyWeight - VertexLateWeight;
EnterSqQueue(CP->Activity->CriticalPathQueue,&CriticalPathWeight);
}
}
}
LogFormat(Debug, "%s\n", "Compute Critical Path Activity OK.");
return SuccessFlag;
}
Status ComputeCriticalPathEvent(CriticalPathSt* CP,AMGraph* AMG, VertexIndexType StartVertexIndex)
{
JudgeAllNullPointer(CP);
JudgeAllNullPointer(AMG);
VertexIndexType InitVal = CRITICAL_PATH_INIT_VAL;
VertexIndexType j;
VertexIndexType NextVertexIndex = StartVertexIndex;//下一个需要访问的顶点行
MyHashTable* VisitedHashTable = NULL;
WeightType TmpWeight = 0; //下一个需要访问的顶点的权值
WeightType TmpAddWeight = 0; //临时权值和
SqStack* VisitedStack = NULL;
InitSqStack(&VisitedStack,INT_TYPE_FLAG);
//1、处理事件最早发生
//初始化事件队列
for ( j = 0; j < AMG->CurVertexNum; j++)
{
EnterSqQueue(CP->Event->VertexEarlyQueue,&InitVal);
EnterSqQueue(CP->Event->VertexLateQueue,&InitVal);
}
j = 0;
UpdateSqQueue(CP->Event->VertexEarlyQueue,StartVertexIndex,&j);
//初始化访问数组
InitHashTable(&VisitedHashTable, AMG->CurVertexNum, INT_TYPE_FLAG);
InsertHashTable(&StartVertexIndex, VisitedHashTable);
PushSqStack(VisitedStack,&StartVertexIndex);
// PrintfSqQueue(CP->Event->VertexEarlyQueue);
// PrintfSqStack(VisitedStack);
// PrintfHashTable(VisitedHashTable,Debug);
while (VisitedHashTable->TotalDataNum != AMG->CurVertexNum)//所有节点访问一遍,退出循环
{
PopSqStack(VisitedStack,&NextVertexIndex);
ReadSqQueue(CP->Event->VertexEarlyQueue,NextVertexIndex,&TmpWeight);
for (j = 0; j < AMG->CurVertexNum; j++)//横向扫描AMG
{
if (AMG->ArcArray[NextVertexIndex][j] != MAX_INT_TYPE_NUM )//不等于无穷大,说明一定有入度。
{
if (AMG->InduityArray[j] == 1)//入度为1的情况
{
InsertHashTable(&j, VisitedHashTable);
PushSqStack(VisitedStack,&j);
TmpAddWeight = AMG->ArcArray[NextVertexIndex][j] + TmpWeight;
UpdateSqQueue(CP->Event->VertexEarlyQueue,j,&TmpAddWeight);
}
else if (CheckInduityVertexExists(AMG, j, VisitedHashTable, CP->Event->VertexEarlyQueue, &TmpAddWeight) == SuccessFlag)
{
InsertHashTable(&j, VisitedHashTable);
PushSqStack(VisitedStack,&j);
UpdateSqQueue(CP->Event->VertexEarlyQueue,j,&TmpAddWeight);
}
// PrintfSqQueue(CP->Event->VertexEarlyQueue);
// PrintfSqStack(VisitedStack);
// PrintfHashTable(VisitedHashTable,Debug);
}
}
}
//清理访问栈和哈希表
ClearSqStack(VisitedStack);
ClearHashTable(VisitedHashTable);
//2、处理事件最晚发生
//和上面时间最早发生的区别是,处理事件最晚是纵向扫描,看顶点的出度,且是从汇点算到起点,倒着算。
//初始化
for ( j = 0; j < AMG->CurVertexNum; j++)
{
if (AMG->OutdegreeArray[j] == 0)//取汇点索引值。
{
InitVal = j;
break;
}
}
InsertHashTable(&InitVal, VisitedHashTable);
PushSqStack(VisitedStack,&InitVal);
ReadSqQueue(CP->Event->VertexEarlyQueue,InitVal,&TmpWeight); //读出事件最早发生的汇点权值。
UpdateSqQueue(CP->Event->VertexLateQueue,InitVal,&TmpWeight);//更新事件最晚发生的汇点权值。
// PrintfSqQueue(CP->Event->VertexLateQueue);
// PrintfSqStack(VisitedStack);
// PrintfHashTable(VisitedHashTable,Debug);
while (VisitedHashTable->TotalDataNum != AMG->CurVertexNum)//所有节点访问一遍,退出循环
{
PopSqStack(VisitedStack,&NextVertexIndex);
ReadSqQueue(CP->Event->VertexLateQueue,NextVertexIndex,&TmpWeight);
for (j = 0; j < AMG->CurVertexNum; j++)//纵向扫描AMG
{
if (AMG->ArcArray[j][NextVertexIndex] != MAX_INT_TYPE_NUM )//不等于无穷大,说明一定有出度。
{
if (AMG->OutdegreeArray[j] == 1)//出度为1的情况
{
InsertHashTable(&j, VisitedHashTable);
PushSqStack(VisitedStack,&j);
TmpAddWeight = TmpWeight - AMG->ArcArray[j][NextVertexIndex];
UpdateSqQueue(CP->Event->VertexLateQueue,j,&TmpAddWeight);
}
else if (CheckOutDegreeVertexExists(AMG, j, VisitedHashTable, CP->Event->VertexLateQueue, &TmpAddWeight) == SuccessFlag)
{
InsertHashTable(&j, VisitedHashTable);
PushSqStack(VisitedStack,&j);
UpdateSqQueue(CP->Event->VertexLateQueue,j,&TmpAddWeight);
}
// PrintfSqQueue(CP->Event->VertexLateQueue);
// PrintfSqStack(VisitedStack);
// PrintfHashTable(VisitedHashTable,Debug);
}
}
}
DestroyHashTable(&VisitedHashTable);
DestroyStack(&VisitedStack);
LogFormat(Debug, "%s\n", "Compute Critical Path Event OK.");
return SuccessFlag;
}
[gbase@czg2 Graph]$ make
gcc -Wall -Wextra -O3 Graph.c MinimumSpanningTree.c ShortestPath.c TopologicalOrder.c CriticalPath.c main.c -o TestGraph -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/HashTable/include/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqQueue/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqStack/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -lPublicFunction -lLog -lMyHashTable -lSqStack -lSqQueue
[gbase@czg2 Graph]$ ./TestGraph
2023-8-23 16:5:57--[ Debug ]--Create Net Data : OK
2023-8-23 16:5:57--[ Debug ]--Create Net Use AMGraph : OK
2023-8-23 16:5:57--[ Debug ]--Printf AMGraph :
VertexArray : [0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ]
ArcArray :
0 : [32767 ,6 ,4 ,5 ,32767 ,32767 ,32767 ,32767 ,32767 ]
1 : [32767 ,32767 ,32767 ,32767 ,1 ,32767 ,32767 ,32767 ,32767 ]
2 : [32767 ,32767 ,32767 ,32767 ,1 ,32767 ,32767 ,32767 ,32767 ]
3 : [32767 ,32767 ,32767 ,32767 ,32767 ,2 ,32767 ,32767 ,32767 ]
4 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,9 ,7 ,32767 ]
5 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,4 ,32767 ]
6 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,2 ]
7 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,4 ]
8 : [32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ,32767 ]
InduityArray : [0 ,1 ,1 ,1 ,2 ,1 ,1 ,2 ,2 ]
OutdegreeArray : [3 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,0 ]
CurVertexNum : 9
CurArcNum : 11
2023-8-23 16:5:57--[ Debug ]--Init SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Init SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Init Critical Path Event St OK.
2023-8-23 16:5:57--[ Debug ]--Init SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Init SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Init SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Init SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Init SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Init Critical Path Activity St OK.
2023-8-23 16:5:57--[ Debug ]--Init Critical Path St OK.
2023-8-23 16:5:57--[ Debug ]--StartVertexIndex : 0 ,It Has Precursor Vertex, Check Adjacency Matrix Graph Fail
2023-8-23 16:5:57--[ Debug ]--(StartVertexIndex : 0,EndVertexIndex : 8), Check Adjacency Matrix Graph OK.
2023-8-23 16:5:57--[ Debug ]--Init SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Init Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Hash : (0,9,0).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (1,9,1).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (2,9,2).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (3,9,3).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (5,9,5).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (4,9,4).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table Fail, HashValue : 4.
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (1,9,1).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 1.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (2,9,2).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 2.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (4,9,4).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (6,9,6).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (4,9,4).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 4.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (5,9,5).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 5.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (7,9,7).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (6,9,6).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 6.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (7,9,7).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 7.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (8,9,8).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Clear SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Clear Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Hash : (8,9,8).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (6,9,6).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (7,9,7).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (6,9,6).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 6.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (7,9,7).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 7.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (4,9,4).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (5,9,5).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (3,9,3).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (1,9,1).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table Fail, HashValue : 1.
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (1,9,1).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (2,9,2).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Judge SqStack Not Empty
2023-8-23 16:5:57--[ Debug ]--Pop SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (1,9,1).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 1.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (2,9,2).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 2.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (3,9,3).
2023-8-23 16:5:57--[ Debug ]--Search Hash Table OK, HashValue : 3.
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Hash : (0,9,0).
2023-8-23 16:5:57--[ Debug ]--New Hash Table Node OK.
2023-8-23 16:5:57--[ Debug ]--Insert Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Push SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Update SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Clear Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Destroy Hash Table OK.
2023-8-23 16:5:57--[ Debug ]--Destroy SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Compute Critical Path Event OK.
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Read SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Enter SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Compute Critical Path Activity OK.
2023-8-23 16:5:57--[ Debug ]--Compute Critical Path OK.
2023-8-23 16:5:57--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,4 ,5 ,7 ,7 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 16:5:57--[ Debug ]--SqQueue Data :
Data : [ 0 ,6 ,6 ,8 ,7 ,10 ,16 ,14 ,18 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 9
SqQueueMaxLen : 9
Flag : INT_TYPE_FLAG
2023-8-23 16:5:57--[ Debug ]--SqQueue Data :
Data : [ 0 ,0 ,0 ,1 ,2 ,3 ,4 ,4 ,5 ,6 ,7 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 11
SqQueueMaxLen : 11
Flag : INT_TYPE_FLAG
2023-8-23 16:5:57--[ Debug ]--SqQueue Data :
Data : [ 1 ,2 ,3 ,4 ,4 ,5 ,6 ,7 ,7 ,8 ,8 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 11
SqQueueMaxLen : 11
Flag : INT_TYPE_FLAG
2023-8-23 16:5:57--[ Debug ]--SqQueue Data :
Data : [ 0 ,0 ,0 ,6 ,4 ,5 ,7 ,7 ,7 ,16 ,14 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 11
SqQueueMaxLen : 11
Flag : INT_TYPE_FLAG
2023-8-23 16:5:57--[ Debug ]--SqQueue Data :
Data : [ 0 ,2 ,3 ,6 ,6 ,8 ,7 ,7 ,10 ,16 ,14 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 11
SqQueueMaxLen : 11
Flag : INT_TYPE_FLAG
2023-8-23 16:5:57--[ Debug ]--SqQueue Data :
Data : [ 0 ,-2 ,-3 ,0 ,-2 ,-3 ,0 ,0 ,-3 ,0 ,0 ]
FrontIndex : 0
RearIndex : 0
SqQueueLen : 11
SqQueueMaxLen : 11
Flag : INT_TYPE_FLAG
2023-8-23 16:5:57--[ Debug ]--Destroy SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Destroy SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Destroy Critical Path Event St OK.
2023-8-23 16:5:57--[ Debug ]--Destroy SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Destroy SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Destroy SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Destroy SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Destroy SqQueue OK
2023-8-23 16:5:57--[ Debug ]--Destroy Critical Path Activity St OK.
2023-8-23 16:5:57--[ Debug ]--Destroy Critical Path St OK.
2023-8-23 16:5:57--[ Debug ]--Destroy SqStack OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StAccessPath OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StAccessPath OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StAccessPath OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StAccessPath OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StAccessPath OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StAccessPath OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StAccessPath OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StAccessPath OK.
2023-8-23 16:5:57--[ Debug ]--Destroy StDijkstraAccees OK.
2023-8-23 16:5:57--[ Debug ]--Destroy Net Data : OK
2023-8-23 16:5:57--[ Debug ]--Destroy Net Use AMGraph : OK
2023-8-23 16:5:57--[ Debug ]--Destroy Net Use AGraph : OK