represent vertex
public interface Vertex<V> {
public V element()throws InvalidVertexException;
}
represent edge
public interface Edge<E,V> {
public E element()throws InvalidEdgeException;
public Vertex<V>[] vertices();
}
represent 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
with implementation of algorithm
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;
}
implementation of algorithm
//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);
}
}
}
}
}
with this graph that contains 4 vertices and the edges and if I calculated the smallest distance between [C, D]
the result should be [C,D] = [C,A] -> [A, D]
method to calculate the distance with vertex origin and destin
I could not find the correct logic to implement to get the correct result, I followed the description of the dijkstra algorithm but I can not find any solution to solve
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
}
any suggestion?
Your code is full of errors.
The remove method is supposed to remove from Q the vertex with the minimal distance:
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);
}
Initialization: don't initialize path, initialize the distance to the origin to zero (as in the comments):
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);
Now, your graph seems to be unweighted, otherwise, it would be a Graph<V,Integer>
, so I'll assume the distance for any edge is 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);
}
}
}
Now to build the graph in your example:
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");
After dijkstra(graph, c)
is called, you get:
dijkstra.path:
b-a
a-c
d-a
dijkstra.distances:
b: 2
a: 1
c: 0
d: 2
Piece of cake!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.