Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一段代码如何影响算法?_Java_Algorithm_Priority Queue_Treeset - Fatal编程技术网

Java 一段代码如何影响算法?

Java 一段代码如何影响算法?,java,algorithm,priority-queue,treeset,Java,Algorithm,Priority Queue,Treeset,抱歉,如果这是一个愚蠢或错误的问题,我在Java中找到了短路径算法的解决方案。代码如下: import java.io.*; import java.util.*; 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",

抱歉,如果这是一个愚蠢或错误的问题,我在Java中找到了短路径算法的解决方案。代码如下:

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

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", 15),
      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();
   }
}

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);
            } 
         }
      }
   }

   /** 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();
      }
   }
}
import java.io.*;
导入java.util.*;
公共级迪杰斯特拉酒店{
私有静态最终图。边[]图={
新的图边(“a”、“b”、7),
新的图边(“a”,“c”,9),
新的图形边缘(“a”、“f”、14),
新的边图(“b”、“c”、10),
新的边图(“b”,“d”,15),
新的边图(“c”,“d”,11),
新的图边(“c”、“f”、2),
新的边图(“d”、“e”、6),
新的边图(“e”、“f”、9),
};
私有静态最终字符串START=“a”;
私有静态最终字符串END=“e”;
公共静态void main(字符串[]args){
图g=新图(图);
g、 迪克斯特拉(起点);
g、 打印路径(结束);
//g、 printalpath();
}
}
类图{
private final Map 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();//距离最短的顶点(第一次迭代将返回源)
如果(u.dist==Integer.MAX_VALUE)break;//我们可以忽略u(和任何其他剩余顶点),因为它们是不可访问的
//看看每个邻居的距离
对于(Map.Entry a:u.neights.entrySet()){
v=a.getKey();//此迭代中的邻居
最终int alternateDist=u.dist+a.getValue();
if(alternativeist
我了解这个算法的大部分内容,但方法
private void dijkstra(最终NavigableSet q)
让我困惑的是以下问题:

  • 由于它并没有任何返回方法,所以代码的其余部分是如何评估它的
  • 使用NavigableSet/TreeSet是否比使用PriorityQueue更好 我还有一个关于compareTo方法的问题,这个方法在Vertex类中被重写,它是如何调用的

    谢谢

  • 由于它并没有任何返回方法,所以代码的其余部分是如何评估它的
  • 该方法的参数是一个可变容器,该容器由算法的各个部分引用

     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);
    
    final Vertex source=graph.get(startName);
    NavigableSet q=新树集();
    //设置顶点
    对于(顶点v:graph.values()){
    v、 previous=v==source?source:null;
    v、 dist=v==source?0:Integer.MAX_值;
    q、 添加(v);
    }
    迪克斯特拉(q);
    
  • 使用NavigableSet/TreeSet是否比使用PriorityQueue更好? 你可以在这个问题中找到答案
  • 1) 有两种方法具有相同的名称:

    public void dijkstra(String startName)
    private void dijkstra(final NavigableSet<Vertex> q)
    
    public void dijkstra(字符串起始名)
    私人void dijkstra(最终NavigableSet q)
    
    如果您调用dijkstra(“a”)
    ,则
    u = q.pollFirst();
    
    if (alternateDist < v.dist) { // shorter path to neighbour found
        q.remove(v);
        v.dist = alternateDist;
        v.previous = u;
        q.add(v);
    }