【发布时间】:2016-03-26 18:08:36
【问题描述】:
我正在尝试通过邻接列表使用有向图来实现 Dijkstra 算法。我找到了一些我一直用作示例的示例代码。在该代码中,图表填充如下:
private static final Graph.Edge[] GRAPH = {
new Graph.Edge("a", "b", 7),
new Graph.Edge("a", "c", 9),
new Graph.Edge("a", "f", 14),
new Graph.Edge("b", "c", 10),
new Graph.Edge("b", "d", 15),
new Graph.Edge("c", "d", 11),
new Graph.Edge("c", "f", 2),
new Graph.Edge("d", "e", 6),
new Graph.Edge("e", "f", 9),};
private static final String START = "a";
private static final String END = "e";
由于我需要从文本文件中的邻接列表中进行填充,因此我尝试以这种方式进行:
List<Graph.Edge> list = new ArrayList<>();
try {
Scanner scanner = new Scanner(new File(filename));
while (scanner.hasNextLine()) {
String source = scanner.findInLine(NAME);
if (source != null) {
while (true) {
String to = scanner.findInLine(NAME);
if (to == null) {
break;
}
int weight = Integer.valueOf(scanner.findInLine(WEIGHT));
list.add(new Graph.Edge(source, to, weight));
}
}
scanner.nextLine();
}
} catch (FileNotFoundException | NumberFormatException e) {
}
与
static final Pattern NAME = Pattern.compile("\\w+");
static final Pattern WEIGHT = Pattern.compile("\\d+");
在示例代码中,他们然后以下列方式在图上运行dijkstra的算法:
Graph g = new Graph(GRAPH);
g.dijkstra(START);
g.printPath(END);
g.printAllPaths();
我尝试更新我的代码以适用于该算法的实现。我想出了以下几点:
try {
Scanner scanner = new Scanner(new File(filename));
while (scanner.hasNextLine()) {
String source = scanner.findInLine(NAME);
if (source != null) {
while (true) {
String go = scanner.findInLine(NAME);
if (go == null) {
break;
}
int weight = Integer.valueOf(scanner.findInLine(WEIGHT));
Graph.Edge edge = new Graph.Edge(source, go, weight);
Graph g = new Graph(GRAPH);
g.dijkstra(source);
g.printPath(go);
}
}
scanner.nextLine();
}
} catch (FileNotFoundException | NumberFormatException e) {
}
当我尝试运行它时,它似乎没有正确填充我的图表。它从 dijkstra 和 printPath 方法产生错误,说“图形不包含开始/结束顶点”。如何更新我的代码,以便正确填充图形并能够正确实现算法?谢谢!
编辑:这是我的输入文件的示例
1 2 1 3 1
2 4 2
3 2 2 5 4
4 3 3 5 3
5 1 4
它遵循格式源,adj。顶点,权重,形容词。顶点,权重....
编辑 2:Graph.Edge 的使用`
class Graph {
private final Map<String, Vertex> graph; // mapping of vertex names to Vertex objects, built from a set of Edges
/**
* One edge of the graph (only used by Graph constructor)
*/
public static class Edge {
public final String v1, v2;
public final int dist;
public Edge(String v1, String v2, int dist) {
this.v1 = v1;
this.v2 = v2;
this.dist = dist;
}
}
和
public Graph(Edge[] edges) {
graph = new HashMap<>(edges.length);
//one pass to find all vertices
for (Edge e : edges) {
if (!graph.containsKey(e.v1)) {
graph.put(e.v1, new Vertex(e.v1));
}
if (!graph.containsKey(e.v2)) {
graph.put(e.v2, new Vertex(e.v2));
}
}
//another pass to set neighbouring vertices
for (Edge e : edges) {
graph.get(e.v1).neighbours.put(graph.get(e.v2), e.dist);
//graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // also do this for an undirected graph
}
}
编辑:这是我从http://rosettacode.org/wiki/Dijkstra%27s_algorithm#Java 找到原始示例代码的地方
【问题讨论】:
-
你应该做一些调试。
-
在什么方面?据我所知,我填充 ArrayList 的方法是正确的。我只是在努力解决如何将其转换为图表。
-
我们可以看看您的输入文件的样本吗?
-
我已更新帖子以添加它
-
在这两种算法尝试中,您在哪里使用从输入数据创建的
Graph.Edge?list和edge变量似乎没有在其他地方使用。
标签: java graph dijkstra directed-graph adjacency-list