我遇到了一个将Dijkstras算法的伪代码转换为实际代码的问题。我给出了邻接列表,如“位置-相邻位置-到位置的距离”,一个节点的例子:AAA AAC 180 AAD 242 AAH 40。我的任务是读取一个按邻接列表组织的文件,并计算从一个节点到另一个节点的最短路径。下面是Dijkstra伪代码:
void dijkstra( Vertex s )
{
for each Vertex v
{
v.dist = INFINITY;
v.known = false;
}
s.dist = 0;
while( there is an unknown distance vertex )
{
Vertex v = smallest unknown distance vertex;
v.known = true;
for each Vertex w adjacent to v
if( !w.known )
{
DistType cvw = cost of edge from v to w;
if( v.dist + cvw < w.dist )
{
// Update w
decrease( w.dist to v.dist + cvw );
w.path = v;
}
}
}
}
我遇到的最大的麻烦是“对于与v相邻的每个顶点w”这一行,这里是我的非工作代码:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class Dijkstra {
public static boolean isInteger(String s) {
return isInteger(s, 10);
}
public static boolean isInteger(String s, int radix) {
if (s.isEmpty())
return false;
for (int i = 0; i < s.length(); i++) {
if (i == 0 && s.charAt(i) == '-') {
if (s.length() == 1)
return false;
else
continue;
}
if (Character.digit(s.charAt(i), radix) < 0)
return false;
}
return true;
}
public static void dijkstra(Vertex[] a, Vertex s, int lineCount) {
int i = 0;
while (i < (lineCount)) // each Vertex v
{
a[i].dist = Integer.MAX_VALUE;
a[i].known = false;
i++;
}
s.dist = 0;
int min = Integer.MAX_VALUE; //
while (!(a[0].known == true && a[1].known == true && a[2].known == true && a[3].known == true
&& a[4].known == true && a[5].known == true && a[6].known == true && a[7].known == true
&& a[8].known == true && a[9].known == true && a[10].known == true && a[11].known == true
&& a[12].known == true)) {
System.out.println("here");
for (int b = 0; b < lineCount; b++) {
if (a[b].dist < min && a[b].known == false) {
min = a[b].dist;
}
}
int c = 0;
while (c < lineCount) {
if (a[c].dist == min && a[c].known == false) {
break;
}
c++++;
}
System.out.println(min);
a[c].known = true;
int adjSize = a[c].adj.size();
int current = 0;
System.out.println(adjSize);
while (current < adjSize - 1) {
String currentAdjacent = (String) a[c].adj.get(current);
int p = 0;
while (p < lineCount) {
if (a[p].name.equals(currentAdjacent)) {
if (!a[p].known) {
String cvwString = (String) a[c].distance.get(current);
int cvw = Integer.parseInt(cvwString);
System.out.println(" This is cvw" + cvw);
System.out.println("Here2");
if (a[c].dist + cvw < a[p].dist) {
a[p].dist = a[c].dist + cvw;
a[p].path = a[c];
}
}
}
p++;
}
current++;
}
}
}
public static class Vertex {
public List adj; // Adjacency list
public List distance;
public boolean known;
public int dist; // DistType is probably int
public Vertex path;
public String name;
// Other fields and methods as needed
}
public static void printPath(Vertex v) {
if (v.path != null) {
printPath(v.path);
System.out.print(" to ");
}
System.out.print(v);
}
public static void main(String[] args) throws IOException {
int lineCounter = 0;
BufferedReader br = new BufferedReader(new FileReader("airport.txt"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
lineCounter = lineCounter + 1;
}
Vertex[] arr = new Vertex[lineCounter];
for (int i = 0; i < lineCounter; i++) {
arr[i] = new Vertex();
arr[i].adj = new LinkedList<String>();
arr[i].distance = new LinkedList<Integer>();
}
;
//
int arrayCounter = 0;
String everything = sb.toString();
String[] lines = everything.split("\\s*\\r?\\n\\s*");
for (String line1 : lines) {
arr[arrayCounter] = new Vertex();
arr[arrayCounter].adj = new LinkedList<String>();
arr[arrayCounter].distance = new LinkedList<Integer>();
String[] result = line1.split("\\s+");
for (int x = 0; x < result.length; x++) {
if (x == 0) {
arr[arrayCounter].name = result[0];
continue;
} else if (isInteger(result[x])) {
arr[arrayCounter].distance.add(result[x]);
continue;
} else {
arr[arrayCounter].adj.add(result[x]);
continue;
}
}
arrayCounter++;
}
for (int i = 0; i < 12; i++) {
System.out.println(arr[i].name);
}
System.out.println(lineCounter);
dijkstra(arr, arr[3], lineCounter - 1);
printPath(arr[11]);
} finally {
br.close();
}
}
}
使用我的顶点类,我使用了一系列while循环,首先遍历存储在链表中的邻接字符串,同时进行比较,查看哪个顶点与邻接列表字符串等价。有没有更好的方法使用我的顶点类来编码“为与v相邻的每个顶点w”?并为我可能犯下的乱七八糟的代码和任何其他风格的罪过道歉。谢谢!
为了解决这个问题,您需要一堆“节点”对象,存储在HashMap中,并根据源位置进行键控。
在节点中,你需要一个对相邻“节点”对象的引用集合(或者至少是它们的“键”,这样你就可以针对它编写逻辑。“节点”还需要知道它的位置和到每个“相邻”节点的距离。想想伦敦地铁地图--每个车站都连接到至少一个其他车站。通常是两个或更多。因此,地铁车站的相邻节点是你可以从那个车站到达的紧接下一站。
一旦有了数据结构,就可以使用递归例程迭代每个节点。然后,它应该遍历每个子节点(也就是相邻节点),并通过将该数据存储在散列图中并使用当前累积的距离来跟踪从初始(源)节点到当前节点的距离,同时递归(或“遍历”图)。在递归时,此跟踪信息应该是您的方法签名的一部分。您还需要跟踪在递归时所采用的当前路径,以避免循环(具有讽刺意味的是,这最终将导致StackOverflowError)。您可以通过使用哈希集来完成此操作。这个集合应该跟踪源和当前节点的位置作为输入键。如果您在递归过程中看到了这个结果,那么您就已经看到了,所以不要继续处理。
我不打算为您编写解决方案的代码,因为我怀疑您在理解答案的过程中会问更多具体的问题,而这些问题很可能在其他地方得到了答案。
本文向大家介绍Dijkstra的邻接表表示算法,包括了Dijkstra的邻接表表示算法的使用技巧和注意事项,需要的朋友参考一下 有一个给定的图G(V,E)及其邻接列表表示形式,并且还提供了一个源顶点。Dijkstra的算法,用于找到源顶点与图G的任何其他顶点之间的最小最短路径。 为了解决这个问题,我们将使用两个列表。一种是存储已被视为最短路径树的顶点,另一种将保存尚未被考虑的顶点。在算法的每个阶段
我有一个无向加权图,作为邻接列表实现。有一个hashmap,其中节点对象作为键,边对象列表作为值。这些边对象包含两个节点之间边的权重。 我试图编写一个Dijkstra的最短路径算法;但是我担心我的图结构太复杂,无法理解我能为Dijkstra找到的所有示例/伪代码。有人能提供任何帮助吗?提前感谢。
实现稀疏连接图的更空间高效的方法是使用邻接表。在邻接表实现中,我们保存Graph 对象中的所有顶点的主列表,然后图中的每个顶点对象维护连接到的其他顶点的列表。 在我们的顶点类的实现中,我们将使用字典而不是列表,其中字典键是顶点,值是权重。 Figure 4 展示了 Figure 2中的图的邻接列表示。 Figure 4 邻接表实现的优点是它允许我们紧凑地表示稀疏图。 邻接表还允许我们容易找到直接连
作为一项练习,我必须建立一个卫星导航系统,规划从一个位置到另一个位置的最短和最快路线。它必须尽可能快,而不需要使用太多内存。 我很难决定使用哪种结构来表示图形。我知道矩阵更适合密集图,列表更适合稀疏图。我更倾向于使用列表,因为我认为添加顶点将是这个程序中最累人的部分。 我只是想听听你们的意见。如果我把一个典型的路线图看作一个图形,其中不同的位置是节点,道路是边缘。你认为它是稀疏的还是密集的?在这种
实现图的最简单的方法之一是使用二维矩阵。在该矩阵实现中,每个行和列表示图中的顶点。存储在行 v 和列 w 的交叉点处的单元中的值表示是否存在从顶点 v 到顶点 w 的边。 当两个顶点通过边连接时,我们说它们是相邻的。 Figure 3 展示了 Figure 2 中的图的邻接矩阵。单元格中的值表示从顶点 v 到顶点 w 的边的权重。 Figure 3 邻接矩阵的优点是简单,对于小图,很容易看到哪些节
在斯坦福的一门算法课程中,教授为图的邻接表表示列出了以下成分: 顶点数组或列表 边的数组或列表 顶点列表中的每个顶点都指向其上的边。 边列表中的每个边都指向其边点。 这种表示法与图形的“关联表”表示法相同吗?如果是,为什么本文认为“邻接表”和“发生率表”是分开的?