1,拓扑排序是关键路径的一部分。
2,关键路径长度, 其实是最远路径长度。然而,它并非最短路径的对偶问题。
3,正向算每个节点的最早开始时间, 逆向算每个节点的最晚开始时间, 设计太了。
4,最晚开始时间的初始化容易弄错, 经典算法是不好对付的。
需要连接第38天的代码,在这里贴出来
package java31to40;
import java.util.Arrays;
public class D38_Net {
public static final int MAX_DISTANCE = 10000;
int numNodes;
D31_IntMatrix weightMatrix;
public static void main(String[] args) {
D38_Net tempNet0 = new D38_Net(3);
System.out.println(tempNet0);
int[][] tempMatrix1 = { { 0, 9, 3, 6 }, { 5, 0, 2, 4 }, { 3, 2, 0, 1 }, { 2, 8, 7, 0 } };
D38_Net tempNet1 = new D38_Net(tempMatrix1);
System.out.println(tempNet1);
tempNet1.dijkstra(1);
int[][] tempMatrix2 = { { 0, 7, MAX_DISTANCE, 5, MAX_DISTANCE }, { 7, 0, 8, 9, 7 },
{ MAX_DISTANCE, 8, 0, MAX_DISTANCE, 5 }, { 5, 9, MAX_DISTANCE, 0, 15 }, { MAX_DISTANCE, 7, 5, 15, 0 } };
D38_Net tempNet2 = new D38_Net(tempMatrix2);
tempNet2.prim();
}
public D38_Net(int paraNumNodes) {
numNodes = paraNumNodes;
weightMatrix = new D31_IntMatrix(numNodes, numNodes);
for (int i = 0; i < numNodes; i++) {
Arrays.fill(weightMatrix.getData()[i], MAX_DISTANCE);
}
}
public D38_Net(int[][] paraMatrix) {
weightMatrix = new D31_IntMatrix(paraMatrix);
numNodes = weightMatrix.getRows();
}
public String toString() {
String resultString = "图的权重矩阵。\r\n" + weightMatrix;
return resultString;
}
public int[] dijkstra(int paraSource) {
int[] tempDistanceArray = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
tempDistanceArray[i] = weightMatrix.getValue(paraSource, i);
}
int[] tempParentArray = new int[numNodes];
Arrays.fill(tempParentArray, paraSource);
tempParentArray[paraSource] = -1;
boolean[] tempVisitedArray = new boolean[numNodes];
tempVisitedArray[paraSource] = true;
int tempMinDistance;
int tempBestNode = -1;
for (int i = 0; i < numNodes - 1; i++) {
tempMinDistance = Integer.MAX_VALUE;
for (int j = 0; j < numNodes; j++) {
if (tempVisitedArray[j]) {
continue;
}
if (tempMinDistance > tempDistanceArray[j]) {
tempMinDistance = tempDistanceArray[j];
tempBestNode = j;
}
}
tempVisitedArray[tempBestNode] = true;
for (int j = 0; j < numNodes; j++) {
if (tempVisitedArray[j]) {
continue;
}
if (weightMatrix.getValue(tempBestNode, j) >= MAX_DISTANCE) {
continue;
}
if (tempDistanceArray[j] > tempDistanceArray[tempBestNode] + weightMatrix.getValue(tempBestNode, j)) {
tempDistanceArray[j] = tempDistanceArray[tempBestNode] + weightMatrix.getValue(tempBestNode, j);
tempParentArray[j] = tempBestNode;
}
}
System.out.println("到每个节点的距离: " + Arrays.toString(tempDistanceArray));
System.out.println("每个节点的父节点: " + Arrays.toString(tempParentArray));
}
System.out.println("最终");
System.out.println("到每个节点的距离: " + Arrays.toString(tempDistanceArray));
System.out.println("每个节点的父节点: " + Arrays.toString(tempParentArray));
return tempDistanceArray;
}
public int prim() {
int tempSource = 0;
int[] tempDistanceArray = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
tempDistanceArray[i] = weightMatrix.getValue(tempSource, i);
}
int[] tempParentArray = new int[numNodes];
Arrays.fill(tempParentArray, tempSource);
tempParentArray[tempSource] = -1;
boolean[] tempVisitedArray = new boolean[numNodes];
tempVisitedArray[tempSource] = true;
int tempMinDistance;
int tempBestNode = -1;
for (int i = 0; i < numNodes - 1; i++) {
tempMinDistance = Integer.MAX_VALUE;
for (int j = 0; j < numNodes; j++) {
if (tempVisitedArray[j]) {
continue;
}
if (tempMinDistance > tempDistanceArray[j]) {
tempMinDistance = tempDistanceArray[j];
tempBestNode = j;
}
}
tempVisitedArray[tempBestNode] = true;
for (int j = 0; j < numNodes; j++) {
if (tempVisitedArray[j]) {
continue;
}
if (weightMatrix.getValue(tempBestNode, j) >= MAX_DISTANCE) {
continue;
}
if (tempDistanceArray[j] > weightMatrix.getValue(tempBestNode, j)) {
tempDistanceArray[j] = weightMatrix.getValue(tempBestNode, j);
tempParentArray[j] = tempBestNode;
}
}
System.out.println("每个节点的选定距离: " + Arrays.toString(tempDistanceArray));
System.out.println("每个节点的父节点: " + Arrays.toString(tempParentArray));
}
int resultCost = 0;
for (int i = 0; i < numNodes; i++) {
resultCost += tempDistanceArray[i];
}
System.out.println("最终");
System.out.println("每个节点的父节点: " + Arrays.toString(tempParentArray));
System.out.println("总成本: " + resultCost);
return resultCost;
}
public boolean[] criticalPath() {
int tempValue;
int[] tempInDegrees = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
for (int j = 0; j < numNodes; j++) {
if (weightMatrix.getValue(i, j) != -1) {
tempInDegrees[j]++;
}
}
}
System.out.println("节点的入度: " + Arrays.toString(tempInDegrees));
int[] tempEarliestTimeArray = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
if (tempInDegrees[i] > 0) {
continue;
}
System.out.println("正在删除 " + i);
for (int j = 0; j < numNodes; j++) {
if (weightMatrix.getValue(i, j) != -1) {
tempValue = tempEarliestTimeArray[i] + weightMatrix.getValue(i, j);
if (tempEarliestTimeArray[j] < tempValue) {
tempEarliestTimeArray[j] = tempValue;
}
tempInDegrees[j]--;
}
}
}
System.out.println("最早开始时间: " + Arrays.toString(tempEarliestTimeArray));
int[] tempOutDegrees = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
for (int j = 0; j < numNodes; j++) {
if (weightMatrix.getValue(i, j) != -1) {
tempOutDegrees[i]++;
}
}
}
System.out.println("节点的出度: " + Arrays.toString(tempOutDegrees));
int[] tempLatestTimeArray = new int[numNodes];
for (int i = 0; i < numNodes; i++) {
tempLatestTimeArray[i] = tempEarliestTimeArray[numNodes - 1];
}
for (int i = numNodes - 1; i >= 0; i--) {
if (tempOutDegrees[i] > 0) {
continue;
}
System.out.println("正在删除 " + i);
for (int j = 0; j < numNodes; j++) {
if (weightMatrix.getValue(j, i) != -1) {
tempValue = tempLatestTimeArray[i] - weightMatrix.getValue(j, i);
if (tempLatestTimeArray[j] > tempValue) {
tempLatestTimeArray[j] = tempValue;
}
tempOutDegrees[j]--;
System.out.println("减少1," + j + " 出度.");
}
}
}
System.out.println("最晚开始时间: " + Arrays.toString(tempLatestTimeArray));
boolean[] resultCriticalArray = new boolean[numNodes];
for (int i = 0; i < numNodes; i++) {
if (tempEarliestTimeArray[i] == tempLatestTimeArray[i]) {
resultCriticalArray[i] = true;
}
}
System.out.println("临界阵列: " + Arrays.toString(resultCriticalArray));
System.out.print("关键节点: ");
for (int i = 0; i < numNodes; i++) {
if (resultCriticalArray[i]) {
System.out.print(" " + i);
}
}
System.out.println();
return resultCriticalArray;
}
}
第39天的代码
package java31to40;
public class D39_criticalPath {
public static final int MAX_DISTANCE = 10000;
public static void main(String[] args) {
D38_Net tempNet0 = new D38_Net(3);
System.out.println(tempNet0);
int[][] tempMatrix1 = { { 0, 9, 3, 6 }, { 5, 0, 2, 4 }, { 3, 2, 0, 1 }, { 2, 8, 7, 0 } };
D38_Net tempNet1 = new D38_Net(tempMatrix1);
System.out.println(tempNet1);
tempNet1.dijkstra(1);
int[][] tempMatrix2 = { { 0, 7, MAX_DISTANCE, 5, MAX_DISTANCE }, { 7, 0, 8, 9, 7 },
{ MAX_DISTANCE, 8, 0, MAX_DISTANCE, 5 }, { 5, 9, MAX_DISTANCE, 0, 15, },
{ MAX_DISTANCE, 7, 5, 15, 0 } };
D38_Net tempNet2 = new D38_Net(tempMatrix2);
tempNet2.prim();
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 } };
D38_Net tempNet3 = new D38_Net(tempMatrix3);
System.out.println("-------关键路径");
tempNet3.criticalPath();
}
}
结果输出:
图的权重矩阵。
[[10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000]]
图的权重矩阵。
[[0, 9, 3, 6], [5, 0, 2, 4], [3, 2, 0, 1], [2, 8, 7, 0]]
到每个节点的距离: [5, 0, 2, 3]
每个节点的父节点: [1, -1, 1, 2]
到每个节点的距离: [5, 0, 2, 3]
每个节点的父节点: [1, -1, 1, 2]
到每个节点的距离: [5, 0, 2, 3]
每个节点的父节点: [1, -1, 1, 2]
最终
到每个节点的距离: [5, 0, 2, 3]
每个节点的父节点: [1, -1, 1, 2]
每个节点的选定距离: [0, 7, 10000, 5, 15]
每个节点的父节点: [-1, 0, 0, 0, 3]
每个节点的选定距离: [0, 7, 8, 5, 7]
每个节点的父节点: [-1, 0, 1, 0, 1]
每个节点的选定距离: [0, 7, 5, 5, 7]
每个节点的父节点: [-1, 0, 4, 0, 1]
每个节点的选定距离: [0, 7, 5, 5, 7]
每个节点的父节点: [-1, 0, 4, 0, 1]
最终
每个节点的父节点: [-1, 0, 4, 0, 1]
总成本: 24
-------关键路径
节点的入度: [0, 1, 1, 2, 1, 3]
正在删除 0
正在删除 1
正在删除 2
正在删除 3
正在删除 4
正在删除 5
最早开始时间: [0, 3, 2, 6, 6, 8]
节点的出度: [2, 2, 2, 1, 1, 0]
正在删除 5
减少1,2 出度.
减少1,3 出度.
减少1,4 出度.
正在删除 4
减少1,1 出度.
正在删除 3
减少1,1 出度.
减少1,2 出度.
正在删除 2
减少1,0 出度.
正在删除 1
减少1,0 出度.
正在删除 0
最晚开始时间: [0, 4, 2, 6, 7, 8]
临界阵列: [true, false, true, true, false, true]
关键节点: 0 2 3 5