所以我正在做一个数学项目,而不是计算机科学项目,但是我想使用代码来帮助收集数据。为此,我想使用Dijkstra的算法并计算出要获得答案之前必须走多少个边。但是我找不到适用于我的图形的任何现有代码。
package mathematicsia;
import java.util.PriorityQueue;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
class Vertex implements Comparable<Vertex>
{
public final String name;
public Edge[] adjacencies;
public double minDistance = Double.POSITIVE_INFINITY;
public Vertex previous;
public Vertex(String argName) { name = argName; }
public String toString() { return name; }
public int compareTo(Vertex other)
{
return Double.compare(minDistance, other.minDistance);
}
}
class Edge
{
public final Vertex target;
public final double weight;
public Edge(Vertex argTarget, double argWeight)
{ target = argTarget; weight = argWeight; }
}
public class DijkstrasAlgorithm
{
public static void computePaths(Vertex source)
{
source.minDistance = 0.;
PriorityQueue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
vertexQueue.add(source);
while (!vertexQueue.isEmpty()) {
Vertex u = vertexQueue.poll();
// Visit each edge exiting u
for (Edge e : u.adjacencies)
{
Vertex v = e.target;
double weight = e.weight;
double distanceThroughU = u.minDistance + weight;
if (distanceThroughU < v.minDistance) {
vertexQueue.remove(v);
v.minDistance = distanceThroughU ;
v.previous = u;
vertexQueue.add(v);
}
}
}
}
public static List<Vertex> getShortestPathTo(Vertex target)
{
List<Vertex> path = new ArrayList<Vertex>();
for (Vertex vertex = target; vertex != null; vertex = vertex.previous)
path.add(vertex);
Collections.reverse(path);
return path;
}
public static void main(String[] args)
{
// mark all the vertices
Vertex P = new Vertex("P");
Vertex L = new Vertex("L");
Vertex E = new Vertex("E");
Vertex B4 = new Vertex("B4"); //Bridge Level 4
Vertex B5 = new Vertex("B5"); //Bridge Level 5
Vertex A2 = new Vertex("A2"); //Stairs A
Vertex A3 = new Vertex("A3");
Vertex A4 = new Vertex("A4");
Vertex A5 = new Vertex("A5");
Vertex A6 = new Vertex("A6");
Vertex C2 = new Vertex("C2"); //Stairs C
Vertex C3 = new Vertex("C3");
Vertex C4 = new Vertex("C4");
Vertex C5 = new Vertex("C5");
Vertex C6 = new Vertex("C6");
// set the edges and weight
L.adjacencies = new Edge[]{ new Edge(A2, 83) }; //A
L.adjacencies = new Edge[]{ new Edge(B4, 90) }; //B
L.adjacencies = new Edge[]{ new Edge(B5, 130) }; //C
L.adjacencies = new Edge[]{ new Edge(C2,86 ) }; //D
B4.adjacencies = new Edge[]{ new Edge(C4, 33) }; //E
B4.adjacencies = new Edge[]{ new Edge(A4,59 ) }; //F
A2.adjacencies = new Edge[]{ new Edge(C2, 97) }; //G
A3.adjacencies = new Edge[]{ new Edge(C3,70 ) }; //H
A4.adjacencies = new Edge[]{ new Edge(C4,71 ) }; //I
A2.adjacencies = new Edge[]{ new Edge(A3,15 ) }; //J
A3.adjacencies = new Edge[]{ new Edge(A4,15 ) }; //K
A4.adjacencies = new Edge[]{ new Edge(A5,15 ) }; //L
A5.adjacencies = new Edge[]{ new Edge(A6, 15) }; //M
A6.adjacencies = new Edge[]{ new Edge(C6, 75) }; //N
P.adjacencies = new Edge[]{ new Edge(A6, 27) }; //O
E.adjacencies = new Edge[]{ new Edge(A3,85 ) }; //P
P.adjacencies = new Edge[]{ new Edge(C6, 97) }; //Q
E.adjacencies = new Edge[]{ new Edge(C3, 25) }; //R
B5.adjacencies = new Edge[]{ new Edge(C5,33 ) }; //S
B5.adjacencies = new Edge[]{ new Edge(A5, 59) }; //T
C5.adjacencies = new Edge[]{ new Edge(C4, 15) }; //U
C4.adjacencies = new Edge[]{ new Edge(C3, 15) }; //V
C3.adjacencies = new Edge[]{ new Edge(C2,24 ) }; //W
C6.adjacencies = new Edge[]{ new Edge(C5, 15) }; //X
P.adjacencies = new Edge[]{ new Edge(C6,73 ) }; //Y
A5.adjacencies = new Edge[]{ new Edge(C5, 75) }; //Z
computePaths(L); // run Dijkstra
System.out.println("Distance to " + P + ": " + P.minDistance);
List<Vertex> path = getShortestPathTo(P);
System.out.println("Path: " + path);
}
}
这不起作用,因为它在我尝试运行时给我一个错误,请帮助!
答案 0 :(得分:0)
让我们从您的Vertex类开始。您无法同时存储两个地形信息的最佳设计:
关于遍历的可变信息:
让我们首先“净化”顶点以仅表示地形信息。另外,让我们实现hashCode()和equals(),以便可以在字典中使用它。
class Vertex
{
public final String name;
public Edge[] adjacencies;
public Vertex(String argName) { name = argName; }
public String toString() { return name; }
public int equals(Vertex other) {
return this.name.compareTo(other.name);
}
public int hashCode() {
return this.name.hashCode();
}
}
然后让结果类保存路径集:
class Path {
HashMap<Vertex, Integer> distances = new HashMap<>();
HashMap<Vertex, Vertex> backtrack = new HashMap<>();
}
现在,我们可以实现Dijkstras。我对您的实现进行了一些修改,以使其在功能上与wikipedia entry相匹配。这样,您就可以跟随他们的动画了。
public Path computePaths(Vertex source)
{
Path p = new Path();
Set<Vertex> visited = new HashSet<>();
distances.put(source, 0); // Distance from source to source
Queue<Vertex> vertexQueue = new LinkedList<Vertex>();
vertexQueue.add(source);
visited.add(source);
while (!vertexQueue.isEmpty()) {
Vertex u = vertexQueue.remove();
// Visit each edge exiting u
for (Edge e : u.adjacencies)
{
Vertex v = e.target;
double distanceThroughU = p.distances.get(u) + e.weight;
if (!p.distances.contains(v) || distanceThroughU < p.distances.get(v)) {
p.distances.put(v, distance);
p.backtrack.put(v, u);
}
// We didn't prime the queue but we need to make sure we visit everyone
// at least once.
if (!visited.contains(v)) {
vertexQueue.add(v);
visited.add(v);
}
}
}
return p;
}
最后,我们可以使用该路径创建路径:
public static List<Vertex> getShortestPathTo(Path p, Vertex target)
{
List<Vertex> path = new List<Vertex>();
for (Vertex vertex = target; vertex != null; vertex = p.backtrack.get(vertex))
path.add(vertex);
Collections.reverse(path);
return path;
}