Java 如果我们有能力克服最多1个障碍,则计算从开始到结束的最短路径

Java 如果我们有能力克服最多1个障碍,则计算从开始到结束的最短路径,java,dijkstra,shortest-path,Java,Dijkstra,Shortest Path,我们得到了一个二维整数矩阵形式的迷宫;其中0是可通行空间,1是墙 起始位置始终为:数组[0][0],结束位置始终为:数组[HEIGHT-1][WIDTH-1] array[0][0] array[HEIGHT -1][WIDTH-1] 唯一可能的移动是向上、向下、向右或向左。 考虑到我们最多可以克服迷宫内部的一堵墙,我想找到从开始到结束的最短路径。我首先创建了一个迷宫类和一个顶点类。我的第一个想法是使用BFS,然而,我最近意识到这当然行不通,我现在正在尝试Dijkstra的算法。一个想法是给墙的

我们得到了一个二维整数矩阵形式的迷宫;其中0是可通行空间,1是墙

起始位置始终为:数组[0][0],结束位置始终为:数组[HEIGHT-1][WIDTH-1] array[0][0] array[HEIGHT -1][WIDTH-1] 唯一可能的移动是向上、向下、向右或向左。 考虑到我们最多可以克服迷宫内部的一堵墙,我想找到从开始到结束的最短路径。我首先创建了一个迷宫类和一个顶点类。我的第一个想法是使用BFS,然而,我最近意识到这当然行不通,我现在正在尝试Dijkstra的算法。一个想法是给墙的重量比可通过的空间要昂贵得多,并使用Dijkstra的来寻找从开始到结束的最短路径。然后,计算每面墙到终点的最短路径。在这之后,我想我可以比较从墙到终点的路径,以及从起点到终点的路径,然后用它来决定移除墙是否会让我的路径更短

我真的在和迪克斯特拉斗争,把所有这些放在一起也许能得到一些有用的东西。我从创建一个迷宫类开始,该类将获取2d数组输入并从中生成一个图形。迷宫类:

   class Maze{
     Vertex[][] vertices;
     ArrayList<Edge> edges;
     ArrayList<Vertex> walls;
     HashSet<Vertex> settledVertices;
     HashSet<Vertex> unsettledVertices;
     HashMap<Vertex,Integer> distanceMap;
     HashMap<Vertex,Vertex> predecessors;

     Vertex start, end;
     int width;
     int height;

 //Maze Contructor  
  public Maze(int arr[][]){
     this.height = arr.length;
     this.width = arr[0].length;
     this.vertices = new Vertex[height][width];
     this.edges = new ArrayList<>();
     this.walls = new ArrayList<>();

     for(int i = 0 ; i < height; i++){
       for(int j = 0; j < width; j++){
         this.vertices[i][j] = arr[i][j] == 1 ? new Wall(arr[i][j]) : new Vertex(arr[i][j]);
         if(this.vertices[i][j].value == 1)
            this.walls.add(this.vertices[i][j]);
       }
     }

   //Build() sets the Edges and their weights, as well as determine each Vertexs neighbors
     build();

     this.start = this.vertices[0][0];
     this.end = this.vertices[height-1][width-1];

  }

  //Attempting Dijkstra
  public void executeDij(Vertex source){
    this.settledVertices = new HashSet<>();
    this.unsettledVertices = new HashSet<>();
    this.distanceMap = new HashMap<>();
    this.predecessors = new HashMap<>();

    this.distanceMap.put(source,0);
    this.unsettledVertices.add(source);

    while(unsettledVertices.size() > 0){
      Vertex v = getMinimum(unsettledVertices);
      unsettledVertices.remove(v);
      findMinDistance(v);
    }
  }


   public int getDistance(Vertex arrow, Vertex target){
      for(Edge e : edges)
        if(e.source.equals(arrow) && e.destination.equals(target))
       return e.weight;

   throw new RuntimeException("Get distance error");
  }




  public void findMinDistance(Vertex vertex){
       for (Vertex target : vertex.neighbors) {
         if(getShortestDistance(target) > getShortestDistance(vertex) + getDistance(vertex, target))
           distanceMap.put(target, getShortestDistance(vertex) + getDistance(vertex,target));
       }

  }




  public int getShortestDistance(Vertex destination){
    Integer d = distanceMap.get(destination);

    if(d == null)
      return Integer.MAX_VALUE;
    return d; 
    }



  public Vertex getMinimum(HashSet<Vertex> set){
    Vertex min = null;

    for(Vertex v : set){
      if(min == null){
        min = v;
      }else{
         if(getShortestDistance(v) < getShortestDistance(min)){
        min = v;
        }     
      }
    }
    return min;
  }



  public boolean isSettled(Vertex v){
    return settledVertices.contains(v);
  }



  public LinkedList<Vertex> getPath(Vertex target){
    LinkedList<Vertex> path = new LinkedList<>();
    Vertex singleStep = target;

    if(predecessors.get(singleStep) == null)
        return null;

    path.add(singleStep);

    while(predecessors.get(singleStep) != null){
      singleStep = predecessors.get(singleStep);
      path.add(singleStep);
    }

    Collections.reverse(path);
    return path;

  }
类迷宫{
顶点[][]个顶点;
阵列列表边;
阵列式墙;
散列集固定顶点;
散列集未结算广告;
HashMap距离映射;
HashMap的前身;
顶点开始、结束;
整数宽度;
内部高度;
//迷宫控制器
公共迷宫(int arr[]{
此高度=arr长度;
this.width=arr[0]。长度;
this.vertices=新顶点[高度][宽度];
this.edges=新的ArrayList();
this.walls=新的ArrayList();
对于(int i=0;i0){
顶点v=getMinimum(未结算的广告);
未结算的广告。删除(v);
FindAdministration(五);
}
}
公共int getDistance(顶点箭头、顶点目标){
用于(边e:边)
if(e.source.equals(箭头)和&e.destination.equals(目标))
返回e.weight;
抛出新的RuntimeException(“获取距离错误”);
}
公共无效FindInstance(顶点){
用于(顶点目标:Vertex.Neights){
if(getShortestDistance(目标)>getShortestDistance(顶点)+getDistance(顶点,目标))
放置(目标,获取最短距离(顶点)+获取距离(顶点,目标));
}
}
公共int getShortestDistance(顶点目标){
整数d=距离映射.get(目的地);
如果(d==null)
返回Integer.MAX_值;
返回d;
}
公共顶点getMinimum(哈希集){
顶点最小值=零;
用于(顶点v:集){
if(min==null){
min=v;
}否则{
if(getShortestDistance(v)
我的顶点类:

 class Vertex{
    int value;
    boolean visited;
    int distance;
    Vertex previous;
    ArrayList<Vertex> neighbors = new ArrayList<>();

    public Vertex(int value){
      this.value = value;
    }

    public boolean isWall(){
      return this.value == 1;
    }

    public void setVisited(){
      this.visited = true;
    }

    public int getValue(){
      return this.value;
    }

 }
类顶点{
int值;
参观;
整数距离;
顶点前向;
ArrayList邻居=新的ArrayList();
公共顶点(int值){
这个值=值;
}
公共布尔值isWall(){
返回此值。值==1;
}
公众假期{
这是真的;
}
public int getValue(){
返回此.value;
}
}

在这一点上,我基本上迷失了自己,我甚至不知道自己在做什么。当我尝试使用getPath方法时,我得到了一个空指针异常。总之,我想我的问题是如何从起点到终点,然后是墙到终点的最便宜路径;对于每面墙。

使用Dijkstra算法构建到任何一点的最短路径都是好的,但要从起点到终点都这样做

假设你有一个迷宫,用
\uu
表示空间,用
X
表示墙:

s\ux\uu
X X X X
__ux_uuu
_X_uux_uu
_X X_ux_u
__X_ue
首先,填写从起点到终点的最短距离:

s1 s2 X\uu
X s2 X X X
s4 s3 X_uuu
s5 X_uux_uu
中六X X_ux_u
s7 s8 X_uuu
如果这让你走到了尽头,你就不用跳过墙了。
否则,请填写距离末端的最短距离:

s1s2 X e6 e7
X s2 X X e5 X
s4 s3 X e5 e4 e3
s5 X e5 e4 X e2
s6 X e3 X e1
s7 s8 X e2 e1 e
现在,查找起点值和终点值旁边的墙:

s1s2--e6 e7
X s2 X X e5 X
s4 s3--e5 e4 e3
s5--e5 e4 X e2
s6 X e3 X e1
s7 s8--e2 e1 e
选择两个距离之和最小的墙。