gpt4 book ai didi

java - 使用 Java 中的 Floyd Warshall 算法保存图中的最短路径

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:51:17 28 4
gpt4 key购买 nike

我正在尝试为 Java 中的无向、未加权(权重 = 1)图编写 Betweeness Centrality 方法。我采用的方法是找到图中的所有最短路径,然后遍历这些路径并计算顶点在该路径中出现的频率。我使用 Floyd Warshall 算法找到最短路径,并使用另一个数组重建路径,类似于 pseudo code on the Wikipedia.

但是,我的结果不正确,我试图找出问题所在,但我做不到。为了完整起见,我将在这里发布整个代码,但是它很困惑,所以我深表歉意。我会评论我认为会出现问题的位。

public void calculateBetweenessCentrality() {
// Floyd warshall algorithm, storing paths with R
int noPath = Integer.MAX_VALUE / 4;
int[][] adjMatrix = getAdjacencyMatrix();
int distances[][] = new int[numVertices][numVertices];
int[][] R = new int[numVertices][numVertices];

// Initialize the arrays, setting "-5000" as null instead. Possible error here?
for (int i = 0; i < numVertices; i++) {
for (int j = 0; j < numVertices; j++) {
if (adjMatrix[i][j] == 0) {
distances[i][j] = noPath;
R[i][j] = -5000; // null
}
else {
distances[i][j] = adjMatrix[i][j];
R[i][j] = j;
}

}
}
// Do the algorithm, and save in R, possible error here?
for (int k = 0; k < numVertices; k++) {
for (int i = 0; i < numVertices; i++) {
for (int j = 0; j < numVertices; j++) {
if (distances[i][j] > distances[i][k] + distances[k][j]) {
distances[i][j] = distances[i][k] + distances[k][j];
R[i][j] = R[i][k];
}

}
}
}

// Go through R and construct the shortest paths, record the frequency for each node (indexs). Possible error here?
HashMap<Integer, Integer> frequencies = new HashMap<>(); // Key = index, Value = frequency
for (int i = 0; i < numVertices; i++) {
for (int j = 0; j < numVertices; j++) {
ArrayList<Integer> path = findShortestPath(R, i, j);
for (int p : path) {
int freq = frequencies.containsKey(p) ? frequencies.get(p) : 0;
frequencies.put(p, freq + 1);
}
}
}

HashMap<Integer, Integer> temp = new HashMap<Integer, Integer>(); // Instead of printing the vertex's adjacency matrix index value, get the actual value for displaying purposes.
for (Entry<Integer, Integer> freq : frequencies.entrySet()) {
temp.put(verticesIndexValue.get(freq.getKey()), freq.getValue());

}
System.out.println("Top 5 nodes: \nNode - Count");
frequencies.entrySet().stream().sorted(Map.Entry.comparingByValue(Collections.reverseOrder())).limit(5)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new))
.forEach((node, frequency) -> System.out.println(node + " - " + frequency));

}

private ArrayList<Integer> findShortestPath(int[][] R, int u, int v) {

ArrayList<Integer> paths = new ArrayList<>();

if(R[u][v] == -5000)
return paths;

paths.add(u);
while(u != v) {
u = R[u][v];
paths.add(u);
}

return paths;
}

我正在测试的图表来自 this input here ,其中每条线都是一条边。该 pastebin 中的图形创建了两个连接的组件。我得到的第一个组件的输出如下:

Top 5 nodes: 
Node - Count
11336782 - 11393
50393960 - 9047
627363 - 4079
849131 - 3799
5676102 - 3351

答案其实是50393960是顶级节点。如果有人可以指导我去哪里出错,我将不胜感激。谢谢 =)

最佳答案

您的代码在计算频率的地方包含错误 - 根据介数中心性的定义,在计算特定顶点 V 时,您应该排除以顶点 V 开始或结束的最短路径。基本上这意味着当遍历最短路径时,您不应该将开始和结束顶点添加到频率中。试试这个:

HashMap<Integer, Integer> frequencies = new HashMap<>(); // Key = index, Value = frequency
for (int i = 0; i < numVertices; i++) {
for (int j = 0; j < numVertices; j++) {
ArrayList<Integer> path = findShortestPath(R, i, j);
for (int p : path) {
if (p == i || p == j) {
continue;
}
int freq = frequencies.containsKey(p) ? frequencies.get(p) : 0;
frequencies.put(p, freq + 1);
}
}
}

关于java - 使用 Java 中的 Floyd Warshall 算法保存图中的最短路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50542749/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com