第 39 天: 关键路径
/**
* Critical path. Net validity checks such as loop check not implemented.
* The source should be 0 and the destination should be n-1.
*
* @return The node sequence of the path.
*/
public boolean[] criticalPath() {
// One more value to save simple computation.
int tempVale;
// Step 1. The in-degree of each node.
int[] tempInDegree = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
for (int j = 0; j < numNodes; j++) {
if (weightMatrix.getValue(i, j) != -1) {
tempInDegree[j]++;
}// Of if
}// Of for j
}// Of for i
System.out.println("In-degree of nodes: " + Arrays.toString(tempInDegree));
// Step 2. Topology sorting.
int[] tempEarliestTimeArray = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
// This node cannot be removed.
if (tempInDegree[i] > 0) {
continue;
}// Of if
System.out.println("Removing " + i);
for (int j = 0; j < numNodes; j++) {
if (weightMatrix.getValue(i, j) != -1) {
tempVale = tempEarliestTimeArray[i] + weightMatrix.getValue(i, j);
if (tempEarliestTimeArray[j] < tempVale) {
tempEarliestTimeArray[j] = tempVale;
}// Of if
tempInDegree[j]--;
}// Of if
}// Of for j
}// Of for i
System.out.println("Earliest start time : " + Arrays.toString(tempEarliestTimeArray));
// Step 3. The out-degree of each node.
int[] tempOutDegree = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
for (int j = 0; j < numNodes; j++) {
if (weightMatrix.getValue(i, j) != -1) {
tempOutDegree[i]++;
}// Of if
}// Of for j
}// Of for i
System.out.println("Out-degree of nodes: " + Arrays.toString(tempOutDegree));
// Step 4. Reverse the topology sorting.
int[] tempLatestTimeArray = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
tempLatestTimeArray[i] = tempEarliestTimeArray[numNodes - 1];
}// Of for i
for (int i = numNodes-1; i >=0; i--) {
// This node cannot be removed.
if (tempOutDegree[i] != 0) {
continue;
}// Of if
System.out.println("Removing " + i);
for (int j = 0; j < numNodes; j++) {
if (weightMatrix.getValue(j, i) != -1) {
tempVale = tempLatestTimeArray[i] - weightMatrix.getValue(j, i);
if (tempLatestTimeArray[j] > tempVale) {
tempLatestTimeArray[j] = tempVale;
}// Of if
tempOutDegree[j]--;
System.out.println("The out-degree of " + j + " decreases by 1.");
}// Of if
}// Of for j
}// Of for i
System.out.println("Latest start time :" + Arrays.toString(tempLatestTimeArray));
boolean[] resultCriticalArray = new boolean[numNodes];
for (int i = 0; i < numNodes; i++) {
if (tempLatestTimeArray[i] == tempEarliestTimeArray[i]) {
resultCriticalArray[i] = true;
}// Of if
}// Of for i
System.out.println("Critical array: " + Arrays.toString(resultCriticalArray));
System.out.print("Critical nodes:");
for (int i = 0; i < numNodes; i++) {
if (resultCriticalArray[i]) {
System.out.print(" " + i);
}// Of if
}// Of for i
System.out.println();
return resultCriticalArray;
}// Of criticalPath
// A directed net without loop is required.
// Node cannot reach itself. It is indicated by -1.
int[][] tempMatrix3 = {{-1, 3, 2, -1, -1, -1}, {-1, -1, -1, 2, 3, -1},
{-1, -1, -1, 4, -1, 3}, {-1, -1, -1, -1, -1, 2}, {-1, -1, -1, -1, -1, 1},
{-1, -1, -1, -1, -1, -1}};
Net tempNet3 = new Net(tempMatrix3);
System.out.println("-------critical path");
tempNet3.criticalPath();
这里老师是确定了0是源点,最后一个是汇点,一般情况的话,可以借用一个栈来存储出入度为0的顶点并访问。计算最早开始时间和最晚开始时间需要细心一点,一个是正向求,一个是反向求。