[英]Algorithm Dijkstra Java
表示vertex
public interface Vertex<V> {
public V element()throws InvalidVertexException;
}
代表edge
public interface Edge<E,V> {
public E element()throws InvalidEdgeException;
public Vertex<V>[] vertices();
}
表示Graph<V,E>
public interface Graph<V, E> {
public Iterable<Vertex<V>> vertices();
public Iterable<Edge<E, V>> incidentEdges(Vertex<V> v)
public Vertex<V> opposite(Vertex<V> v, Edge<E, V> e);
public Iterable<Edge<E, V>> edges();
public Vertex<V> insertVertex(V o);
public Edge<E, V> insertEdge(Vertex<V> u, Vertex<V> v, E o);
public Edge<E, V> insertEdge(V elem1, V elem2, E o);
}
具有算法实现的class Dijkstra
public class Dijkstra<V, E> {
//To store a distance from each of the vertices to the vertex source.
private Map<Vertex<V>, Integer> distances;
//To save the predecessor vertex on the shortest path
private Map<Vertex<V>, Vertex<V>> path;
//To save visited vertices
private Set<Vertex<V>> visited;
//Construtor
public Dijkstra() {
this.distances = new HashMap<>();
this.path = new HashMap<>();
this.visited = new HashSet<>();
}
//remove u from Q;
private Vertex<V> remove(ArrayList<Vertex<V>> queue) {//Q = Q - {v}
Iterator<Vertex<V>> it = queue.iterator();
while (it.hasNext()) {
Vertex<V> u = it.next();
if (u != null) {
it.remove();
return u;
}
}
return null;
}
算法实现
//Dijkstra (graph, origin)
private void dijkstra(Graph <V,E> graph, Vertex<V> origin) {
//Q list of vertex
ArrayList <Vertex<V>> Q = new ArrayList<> ();
//for each vertex v in the graph
for (Vertex <V> v: graph.vertices()) {
//vertex v diferent vertex origin
if (v.element().equals(origin.element()) != true) {
//distance [v] = Infinite;
distances.put(v, Integer.MAX_VALUE);
//predecessor [v] = -1;
path.put(origin, v);
} //vertex v equal vertex origin
else {
//distance [source] = 0;
distances.put(origin, Integer.MIN_VALUE);
} //Q = all vertices of graph;
Q.add(v);
}
//while (Q is not empty) do,
while (Q.isEmpty() != true) {
//remove u from Q;
Vertex <V> u = remove(Q);
//u = vertex is graph with less distance;
int distanceU = distances.get(u);
//if (distance [u] == Infinity)
if (distanceU == Integer.MAX_VALUE) {
//return visited;
visited.add(u);
} else {
for (Edge <E, V> edge: graph.incidentEdges(u)) {
//for every neighbor v of u
Vertex <V> v = graph.opposite(u, edge);
//distance [v]
int distanceV = distances.get(v);
//distance between u and v;
int distanceUV = distanceU + distanceV;
//d = distance [u] + distance between u and v;
int d = distanceU + distanceUV;
//(d < distance [v])
if (d < distances.get(v)) {
//distance [v] = d;
distances.put(v, d);
//predecessor [v] = u;
path.put(u, v);
}
}
}
}
}
这张图包含 4 个顶点和边,如果我计算了[C, D]之间的最小距离
结果应该是[C,D] = [C,A] -> [A, D]
计算与顶点原点和目的地的距离的方法
我找不到正确的逻辑来实现以获得正确的结果,我遵循了 dijkstra 算法的描述,但我找不到任何解决方案来解决
public void executeDijkstra(Graph<V, E> graph, Vertex<V> origin, Vertex<V> destiny) {
//execute dijkstra
dijkstra(graph, origin);
//need to return all vertices with distances
}
有什么建议吗?
你的代码充满了错误。
remove 方法应该从 Q 中删除距离最小的顶点:
private Vertex<V> remove(List<Vertex<V>> queue) {//Q = Q - {v}
if (queue.isEmpty()) {
return null;
}
int ix = 0;
int min = distances.get(queue.get(0));
for (int i = 1; i < queue.size(); ++i) {
int dist = distances.get(queue.get(i));
if (dist < min) {
ix = i;
min = dist;
}
}
return queue.remove(ix);
}
初始化:不初始化路径,将到原点的距离初始化为零(如注释中所示):
for (Vertex<V> v : graph.vertices()) {
//vertex v diferent vertex origin
if (v.element().equals(origin.element()) != true) {
//distance [v] = Infinite;
distances.put(v, Integer.MAX_VALUE);
} //Q = all vertices of graph;
Q.add(v);
}
//distance [source] = 0;
distances.put(origin, 0);
现在,您的图似乎未加权,否则,它将是Graph<V,Integer>
,因此我假设任何边的距离为 1:
//while (Q is not empty) do,
while (!Q.isEmpty()) {
//remove u from Q;
Vertex<V> u = remove(Q);
//u = vertex is graph with less distance;
int distanceU = distances.get(u);
//if (distance [u] == Infinity)
for (Edge<E, V> edge : graph.incidentEdges(u)) {
//for every neighbor v of u
Vertex<V> v = graph.opposite(u, edge);
//distance [v]
int d = distanceU + 1;
//(d < distance [v])
if (d < distances.get(v)) {
//distance [v] = d;
distances.put(v, d);
//predecessor [v] = u;
path.put(v, u);
}
}
}
现在在您的示例中构建图形:
Graph<String,String> graph = new GraphImpl<>();
Vertex<String> a = graph.insertVertex("a");
Vertex<String> b = graph.insertVertex("b");
Vertex<String> c = graph.insertVertex("c");
Vertex<String> d = graph.insertVertex("d");
graph.insertEdge(a, b, "ab");
graph.insertEdge(a, c, "ac");
graph.insertEdge(a, d, "ad");
调用dijkstra(graph, c)
,您将得到:
dijkstra.path:
b-a
a-c
d-a
dijkstra.distances:
b: 2
a: 1
c: 0
d: 2
小菜一碟!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.