赞
踩
bool TopologicalSort(MGraph g, int indegree[MaxVertenNum], int print[MaxVertenNum]) { SqStack st; InitStack(st); int i, j, count = 0; for (i = 0; i < g.vexnum; i++) { print[i] = -1; //初始全部为-1 if (indegree[i] == 0) Push(st, i); //把入度为零的顶点入栈 } while (!StackEmpty(st)) //栈不空时循环 { Pop(st, i); print[count++] = i; for (j = 0; j < g.vexnum; j++) if (g.Edge[i][j] == 1) if (!(--indegree[j])) Push(st, j); } if (count < g.vexnum) return false; else return true; }
bool TopologicalSort(AdjGraph g,int indegree[MaxVertexNum],int print[MaxVertexNum]) { SqStack st; InitStack(st); //初始化栈,存储入度为0的顶点 int i, j; ArcNode* p; for (i = 0; i < g.vexnum; i++) { print[i] = -1; //初始全部为-1 if (indegree[i] == 0) Push(st, i); //将所有入度为0的顶点进栈 } int count = 0; //计数,记录当前已经输出的顶点数 while (!StackEmpty(st)) //栈不空,则存在入度为0的顶点 { Pop(st, i); //输出顶点i print[count++] = i; p = g.adjlist[i].firstarc; while (p != NULL) //将所有i指向的顶点的入度减1,并且将入度减为0的顶点压入栈st { j = p->adjvex; if (!(--indegree[j])) Push(st, j); //入度为0,则入栈 p = p->nextarc; } } if (count < g.vexnum) return false; //拓扑排序失败,有向图中有回路 else return true; //拓扑排序成功 }
bool visited[MaxVertenNum]; //访问标记数组 int finishTime[MaxVertenNum]; int time = 0; void DFS(MGraph& g,int v) //深度优先遍历图G,统计访问过的顶点数和边数,通过Vnum和Enum返回 { visited[v] = true; //作访问标记 for (int w = FirstNeighbor(g, v); w >= 0; w = NextNeighbor(g, v, w)) //取v的第一个邻接顶点 if (!visited[w]) DFS(g, w); //当该邻接顶点为访问过 time = time + 1; finishTime[v] = time; } void DFSTraverse(MGraph g) { int i; for (i = 0; i < g.vexnum; i++) visited[i] = false; for (i = 0; i < g.vexnum; i++) if (!visited[i]) DFS(g, g.Vex[i]); }
bool Reverse_TopologicalSort(MGraph g, int outdegree[MaxVertenNum], int print[MaxVertenNum]) { SqStack st; InitStack(st); int i, j, count = 0; for (i = 0; i < g.vexnum; i++) { print[i] = -1; if (outdegree[i] == 0) Push(st, i); } while (!StackEmpty(st)) { Pop(st, i); print[count++] = i; for (j = 0; j < g.vexnum; j++) if (g.Edge[j][i] == 1) if (!(--outdegree[j])) Push(st, j); } if (count < g.vexnum) return false; else return true; }
bool Reverse_TopologicalSort(AdjGraph g,int outdegree[MaxVertexNum],int print[MaxVertexNum]) { SqStack st; InitStack(st); //初始化栈,存储出度为0的顶点 int i, j; ArcNode* p; for (i = 0; i < g.vexnum; i++) { print[i] = -1; //初始全部为-1 if (outdegree[i] == 0) Push(st, i); //将所有出度为0的顶点进栈 } int count = 0; //计数,记录当前已经输出的顶点数 while (!StackEmpty(st)) //栈不空,则存在出度为0的顶点 { Pop(st, i); //输出顶点i print[count++] = i; p = g.adjlist[i].firstarc; while (p != NULL) //将所有i指向的顶点的出度减1,并且将出度减为0的顶点压入栈st { j = p->adjvex; if (!(--outdegree[j])) Push(st, j); //出度为0,则入栈 p = p->nextarc; } } if (count < g.vexnum) return false; //拓扑排序失败,有向图中有回路 else return true; //拓扑排序成功 }
bool visited[MaxVertexNum]; //访问标记数组 void DFS(AdjGraph g, int v) { visited[v] = true; //设已访问标记 for (int w = FirstNeighbor(g, v); w >= 0; w = NextNeighbor(g, v, w)) if (!visited[w]) DFS(g, w); //尚未访问的邻接顶点 printf("%d ", v); //访问顶点 } void DFSTraverse(AdjGraph g) //对G进行深度优先遍历 { int i; for (i = 0; i < g.vexnum; i++) visited[i] = false; //初始化已访问标记数据 for (i = 0; i < g.vexnum; i++) //从0号顶点开始遍历 if (!visited[i]) DFS(g, i); }
在带权有向图中,以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的开销(如完成活动所需的时间),称之为用边表示活动的网络,简称AOE网(Activity On Edge NetWork)。AOE网和AOV网都是有向无环图,不同之处在于它们的边和顶点所代表的含义是不同的,AOE网中的边有权值;而AOV网中的边无权值,仅表示顶点之间的前后关系。
AOE网具有以下两个性质:
①只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动才能开始;
②只有在进入某顶点的各有向边所代表的活动都已结束时,该顶点所代表的事件才能发生。
在AOE网中仅有一个入度为0的顶点,称为开始顶点(源点),它表示整个工程的开始;网中也仅存在一个出度为0的顶点,称为结束顶点(汇点),它表示整个工程的结束。
在AOE网中,有些活动是可以并行进行的。从源点到汇点的有向路径可能有多条,并且这些路径长度可能不同。完成不同路径上的活动所需的时间虽然不同,但是只有所有路径上的活动都已完成,整个工程才能算结束。因此,从源点到汇点的所有路径中,具有最大路径长度的路径称为关键路径,而把关键路径上的活动称为关键活动。
完成整个工程的最短时间就是关键路径的长度,即关键路径上各活动花费开销的总和。这是因为关键活动影响了整个工程的时间,即若关键活动不能按时完成,则整个工程的完成时间就会延长。因此,只要找到了关键活动,就找到了关键路径,也就可以得出最短完成时间。
下面给出在寻找关键活动时所用到的几个参量的定义。
求关键路径的算法步骤如下:
从源点出发,令
v
e
ve
ve(源点)=0,按拓扑有序求其余顶点的最早发生时间
v
e
(
)
ve()
ve()。
从汇点出发,令
v
l
vl
vl(汇点)=
v
e
ve
ve(汇点),按逆拓扑有序求其余顶点的最迟发生时间
v
l
(
)
vl()
vl()。
根据各顶点的
v
e
(
)
ve()
ve()值求所有弧的最早开始时间
e
(
)
e()
e()。
根据各顶点的
v
l
(
)
vl()
vl()值求所有弧的最迟开始时间
l
(
)
l()
l()。
求AOE网中所有活动的差额
d
(
)
d()
d(),找出所有
d
(
)
=
0
d()=0
d()=0的活动构成关键路径。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。