您的位置:首页 > 理论基础 > 数据结构算法

拓扑排序和关键路径

2017-08-13 16:11 218 查看
一、拓扑排序

1、AOV网络

顶点活动网络(Activity On Vertex Network),即一个有向图G,各顶点表示活动,各条边表示活动之间的领先关系。

AOV网络是一个有向无环图。

2、拓扑排序算法

(1)在图中选择一个入度为0 的顶点,并输出之;

(2)从图中删除该顶点极其所有出边,借助栈或队列存储产生的新的入读为0 的顶点;

(3)重复(1)和(2)直至输出所有顶点。

3、代码

public void TopoSort(Graph graph, int[] order) {
System.out.println("初始入度:");
for (int i = 0; i < nodeNum; i++)
System.out.print(inDegree[i] + " ");
System.out.println();

Queue<Node> queue = new LinkedList<>();

for (int i = 0; i < nodeNum; i++) {
if (inDegree[i] == 0) {
// 入度为零的节点入队列
queue.offer(vertex[i]);
}
}

int count = 0, nextPos;
for (int i = 0; i < nodeNum; i++) {
if (!queue.isEmpty()) {
Node node = queue.poll();
order[count++] = node.id;
// 将该节点的所有邻接点的入度减一
while (node.next != null) {
node = node.next;
nextPos = getVertexPos(node.id);
inDegree[nextPos]--;
if (inDegree[nextPos] == 0)
queue.offer(vertex[nextPos]);
}
}
}

System.out.println("拓扑排序:");
for (int i = 0; i < nodeNum; i++) {
System.out.print(order[i] + " ");
}
System.out.println();
}


执行结果

拓扑排序:
0 1 7 4 2 8 3 6 5


二、关键路径

1、AOE网络

顶点表示事件,有向边表示活动,有向边的权值表示活动的所需时间,入边代表活动已完成,出边表示活动刚开始。

2、关键路径

完成工程所需的最短时间,即从开始顶点到完成顶点的最长路径的长度,该最长路径称为关键路径。

3、关键路径算法

(1)求事件可能的最早发生时间earliest[]

earliest(0) = 0

earliest(j) = max{earliest(i) + w(i,j)}

(2)求时间允许的最迟发生时间latest[]

latest(n-1) = earliest(n-1)

latest(i) = min{latest(j) - w(i,j)}

(3)求活动的最早开始时间和最迟发生时间early[]和late[]

early(k) = earlest(i)

late(k) = latest(j) -w(i,j)

当early[k] = late[k]时,对应的ak即为一个关键路径。

4、代码

/**
* 事件可能的最早发生时间
*
* @param g
* @param order
* @param earliest
*/
public void Earliest(Graph g, int[] order, int[] earliest) {
int i, k;
for (i = 0; i < nodeNum; i++) {
earliest[i] = 0;
}
for (i = 0; i < nodeNum; i++) {
k = order[i];
Node node = vertex[getVertexPos(k)].next;
while (node != null) {
if (earliest[node.id] < earliest[k] + node.weight)
earliest[node.id] = earliest[k] + node.weight;
node = node.next;
}
}
}

/**
* 事件允许的最晚发生时间
*
* @param g
* @param order
* @param earliest
* @param latest
*/
public void Latest(Graph g, int[] order, int[] earliest, int[] latest) {
int i, j, k;
for (i = 0; i < nodeNum; i++) {
latest[i] = earliest[nodeNum - 1];
}
for (i = nodeNum - 2; i > -1; i--) {
j = order[i];
Node node = vertex[getVertexPos(j)].next;
while (node != null) {
k = node.id;
if (latest[j] > latest[k] - node.weight)
latest[j] = latest[k] - node.weight;
node = node.next;
}
}
}

public void CriticalPath(Graph graph, int[] earliest, int[] latest) {
int[] early = new int[edgeNum], late = new int[edgeNum];
early[0] = earliest[0];
early[1] = earliest[0];
early[2] = earliest[0];
early[3] = earliest[1];
early[4] = earliest[2];
early[5] = earliest[3];
early[6] = earliest[4];
early[7] = earliest[4];
early[8] = earliest[5];
early[9] = earliest[6];
early[10] = earliest[7];

late[0] = latest[1] - a[0];
late[1] = latest[2] - a[1];
late[2] = latest[3] - a[2];
late[3] = latest[4] - a[3];
late[4] = latest[4] - a[4];
late[5] = latest[5] - a[5];
late[6] = latest[6] - a[6];
late[7] = latest[7] - a[7];
late[8] = latest[7] - a[8];
late[9] = latest[8] - a[9];
late[10] = latest[8] - a[10];

System.out.println("关键路径:");
for (int i = 0; i < edgeNum; i++) {
if (early[i] == late[i]) {
System.out.print("a" + i + " ");
}
}
System.out.println();
}


执行结果

earliest:
0 6 4 5 7 7 16 15 19
latest:
0 6 6 9 7 11 17 15 19
early:
0 0 0 6 4 5 7 7 7 16 15
late:
0 2 4 6 6 9 8 7 11 17 15
关键路径:
a0 a3 a7 a10
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构