1,又需要画个几个图, 换几个例子。
2,Dijkstra 算法需要有向图, Prim 算法需要无向图. 代码中也需要更换后者。
3,两个算法的结构相同. 不同之处是比较距离的时候, 是用累计的 (Dijkstra) 还是当前边的 (Prim). 建议先写 Dijkstra, 然后拷贝、修改变成 Prim. 到这个阶段, 应该已经具备这样的能力。
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;
}
}
结果输出:
图的权重矩阵。
[[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