簡體   English   中英

算法 Dijkstra Java

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM