[英]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.