Java 迪克斯特拉';s算法寻找所有可能的最短路径

Java 迪克斯特拉';s算法寻找所有可能的最短路径,java,algorithm,graph,dijkstra,shortest-path,Java,Algorithm,Graph,Dijkstra,Shortest Path,我正在研究Dijkstra的算法,我需要找到所有可能的最短路径。Dijkstra算法只返回一条短路径,如果另一条路径的成本相同,我想打印它。我没有主意了,请帮帮我 多谢各位 这是我的算法: public class Dijkstra { private static final Graph.Edge[] GRAPH = { new Graph.Edge("a", "b", 7), new Graph.Edge("a", "c", 9), new Graph.Edge(

我正在研究Dijkstra的算法,我需要找到所有可能的最短路径。Dijkstra算法只返回一条短路径,如果另一条路径的成本相同,我想打印它。我没有主意了,请帮帮我

多谢各位

这是我的算法:

public class Dijkstra {
  private static final Graph.Edge[] GRAPH = {
    new Graph.Edge("a", "b", 7),
    new Graph.Edge("a", "c", 9),
    new Graph.Edge("a", "f", 14),
    new Graph.Edge("b", "c", 10),
    new Graph.Edge("b", "d", 13),
    new Graph.Edge("c", "d", 11),
    new Graph.Edge("c", "f", 2),
    new Graph.Edge("d", "e", 6),
    new Graph.Edge("e", "f", 9),
  };
  private static final String START = "a";
  private static final String END = "e";

  public static void main(String[] args) {
    Graph g = new Graph(GRAPH);
    g.dijkstra(START);
    g.printPath(END);
    //g.printAllPaths();
  }
}

import java.io.*;
import java.util.*;

class Graph {
  private final Map<String, Vertex>
      graph; // mapping of vertex names to Vertex objects, built from a set of Edges

  /** One edge of the graph (only used by Graph constructor) */
  public static class Edge {
    public final String v1, v2;
    public final int dist;

    public Edge(String v1, String v2, int dist) {
      this.v1 = v1;
      this.v2 = v2;
      this.dist = dist;
    }
  }

  /** One vertex of the graph, complete with mappings to neighbouring vertices */
  public static class Vertex implements Comparable<Vertex> {
    public final String name;
    public int dist = Integer.MAX_VALUE; // MAX_VALUE assumed to be infinity
    public Vertex previous = null;
    public final Map<Vertex, Integer> neighbours = new HashMap<>();

    public Vertex(String name) {
      this.name = name;
    }

    private void printPath() {
      if (this == this.previous) {
        System.out.printf("%s", this.name);
      } else if (this.previous == null) {
        System.out.printf("%s(unreached)", this.name);
      } else {
        this.previous.printPath();
        System.out.printf(" -> %s(%d)", this.name, this.dist);
      }
    }

    public int compareTo(Vertex other) {
      return Integer.compare(dist, other.dist);
    }
  }

  /** Builds a graph from a set of edges */
  public Graph(Edge[] edges) {
    graph = new HashMap<>(edges.length);

    //one pass to find all vertices
    for (Edge e : edges) {
      if (!graph.containsKey(e.v1)) graph.put(e.v1, new Vertex(e.v1));
      if (!graph.containsKey(e.v2)) graph.put(e.v2, new Vertex(e.v2));
    }

    //another pass to set neighbouring vertices
    for (Edge e : edges) {
      graph.get(e.v1).neighbours.put(graph.get(e.v2), e.dist);
      //graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // also do this for an undirected graph
    }
  }

  /** Runs dijkstra using a specified source vertex */
  public void dijkstra(String startName) {
    if (!graph.containsKey(startName)) {
      System.err.printf("Graph doesn't contain start vertex \"%s\"\n", startName);
      return;
    }
    final Vertex source = graph.get(startName);
    NavigableSet<Vertex> q = new TreeSet<>();

    // set-up vertices
    for (Vertex v : graph.values()) {
      v.previous = v == source ? source : null;
      v.dist = v == source ? 0 : Integer.MAX_VALUE;
      q.add(v);
    }

    dijkstra(q);
  }

  /** Implementation of dijkstra's algorithm using a binary heap. */
  private void dijkstra(final NavigableSet<Vertex> q) {
    Vertex u, v;
    while (!q.isEmpty()) {

      u = q.pollFirst(); // vertex with shortest distance (first iteration will return source)
      if (u.dist == Integer.MAX_VALUE)
        break; // we can ignore u (and any other remaining vertices) since they are unreachable

      //look at distances to each neighbour
      for (Map.Entry<Vertex, Integer> a : u.neighbours.entrySet()) {
        v = a.getKey(); //the neighbour in this iteration

        final int alternateDist = u.dist + a.getValue();
        if (alternateDist < v.dist) { // shorter path to neighbour found
          q.remove(v);
          v.dist = alternateDist;
          v.previous = u;
          q.add(v);
        } else if (alternateDist == v.dist) {
          // Here I Would do something
        }
      }
    }
  }

  /** Prints a path from the source to the specified vertex */
  public void printPath(String endName) {
    if (!graph.containsKey(endName)) {
      System.err.printf("Graph doesn't contain end vertex \"%s\"\n", endName);
      return;
    }

    graph.get(endName).printPath();
    System.out.println();
  }
  /** Prints the path from the source to every vertex (output order is not guaranteed) */
  public void printAllPaths() {
    for (Vertex v : graph.values()) {
      v.printPath();
      System.out.println();
    }
  }

  public void printAllPaths2() {
    graph.get("e").printPath();
    System.out.println();
  }
}
Dijkstra公共类{
私有静态最终图。边[]图={
新的图边(“a”、“b”、7),
新的图边(“a”,“c”,9),
新的图形边缘(“a”、“f”、14),
新的边图(“b”、“c”、10),
新的边图(“b”、“d”、13),
新的边图(“c”,“d”,11),
新的图边(“c”、“f”、2),
新的边图(“d”、“e”、6),
新的边图(“e”、“f”、9),
};
私有静态最终字符串START=“a”;
私有静态最终字符串END=“e”;
公共静态void main(字符串[]args){
图g=新图(图);
g、 迪克斯特拉(起点);
g、 打印路径(结束);
//g、 printalpath();
}
}
导入java.io.*;
导入java.util.*;
类图{
私人最终地图
graph;//顶点名称到顶点对象的映射,从一组边构建
/**图的一条边(仅由图构造函数使用)*/
公共静态类边缘{
公共最终字符串v1、v2;
公共终审法院;
公共边缘(字符串v1、字符串v2、int-dist){
这1.v1=v1;
这1.v2=v2;
this.dist=dist;
}
}
/**图的一个顶点,完成到相邻顶点的映射*/
公共静态类{
公共最终字符串名;
public int dist=Integer.MAX_VALUE;//假定MAX_值为无穷大
公共顶点上一个=空;
公共最终映射邻居=新HashMap();
公共顶点(字符串名称){
this.name=名称;
}
私有void printPath(){
if(this==this.previous){
System.out.printf(“%s”,此.name);
}else if(this.previous==null){
System.out.printf(“%s(未访问)”,此.name);
}否则{
this.previous.printPath();
System.out.printf(“->%s(%d)”,this.name,this.dist);
}
}
公共整数比较(顶点其他){
返回整数.compare(dist,other.dist);
}
}
/**从一组边生成图形*/
公共图(边[]边){
图形=新的HashMap(edges.length);
//一次查找所有顶点
用于(边e:边){
如果(!graph.containsKey(e.v1))graph.put(e.v1,新顶点(e.v1));
如果(!graph.containsKey(e.v2))graph.put(e.v2,新顶点(e.v2));
}
//另一个过程用于设置相邻顶点
用于(边e:边){
graph.get(e.v1)、neights.put(graph.get(e.v2)、e.dist);
//graph.get(e.v2).neights.put(graph.get(e.v1),e.dist);//对无向图也这样做
}
}
/**使用指定的源顶点运行dijkstra*/
公共无效dijkstra(字符串起始名){
if(!graph.containsKey(startName)){
System.err.printf(“图形不包含起始顶点\%s\“\n”,起始名称);
返回;
}
最终顶点源=graph.get(startName);
NavigableSet q=新树集();
//设置顶点
对于(顶点v:graph.values()){
v、 previous=v==source?source:null;
v、 dist=v==source?0:Integer.MAX_值;
q、 添加(v);
}
迪克斯特拉(q);
}
/**使用二进制堆实现dijkstra算法*/
私人void dijkstra(最终NavigableSet q){
顶点u,v;
而(!q.isEmpty()){
u=q.pollFirst();//距离最短的顶点(第一次迭代将返回源)
if(u.dist==整数.MAX_值)
break;//我们可以忽略u(和任何其他剩余顶点),因为它们是不可访问的
//看看每个邻居的距离
对于(Map.Entry a:u.neights.entrySet()){
v=a.getKey();//此迭代中的邻居
最终int alternateDist=u.dist+a.getValue();
if(alternativeist
看看所谓的。这些解决了枚举图中第一、第二、…、第k条最短路径的问题。文献中有几种算法,例如,参见或


请注意,大多数算法不要求您预先指定
k
,即,您可以使用它们按递增顺序枚举最短路径,并在长度严格增加时停止。

如果一个节点有多条路径,则给定节点可能有多个以前的节点,每个都有相同的
dist
值。因此,首先,您需要将
Vertex.previous
放入某种集合中。请注意,查找所有最短路径可能无法在多项式时间内完成。例如,当从两个相同长度的负载中有许多单独的选择时,将有太多的最短路径。