gpt4 book ai didi

java - 用Dijkstra算法求距离为坐标的最短路径

转载 作者:搜寻专家 更新时间:2023-11-01 03:03:48 29 4
gpt4 key购买 nike

我在 SO 上查看了与此相关的其他帖子。

我试图找到图中节点之间的最短路径。节点之间的每条边都有一个 (X, Y) 坐标。

我想计算从 Node INode J 的最短距离。一旦有了,我想从最短路径的坐标中将所有 X 值和 Y 值相加。

我已经坚持了几个小时,希望能有一些见解。

代码如下:

class Vertex implements Comparable<Vertex> {
private int id;
private List<Edge> adjacencyList;
private Vertex previousVertex;
private double minDistance;
private Coordinate point;

public Vertex(int id, Coordinate point) {
this.id = id;
this.point = point;
this.adjacencyList = new ArrayList<>();
}

public int getID() {
return this.id;
}

public Coordinate getPoint() {
return this.point;
}

public List<Edge> getAdjacencyList() {
return this.adjacencyList;
}

public void addNeighbour(Edge edge) {
this.adjacencyList.add(edge);
}

public Vertex getPreviousVertex() {
return this.previousVertex;
}

public void setPreviousVertex(Vertex previousVertex) {
this.previousVertex = previousVertex;
}

public double getMinDistance() {
return this.minDistance;
}

public void setMinDistance(double minDistance) {
this.minDistance = minDistance;
}

public int compareTo(Vertex other) {
return Double.compare(this.minDistance, other.minDistance);
}
}


class Edge {
private double weight;
private Vertex targetVertex;

public Edge(double weight, Vertex targetVertex) {
this.weight = weight;
this.targetVertex = targetVertex;
}

public double getWeight() {
return this.weight;
}

public void setWeight(double weight) {
this.weight = weight;
}

public Vertex getTargetVertex() {
return this.targetVertex;
}

public void setTargetVertex(Vertex targetVertex) {
this.targetVertex = targetVertex;
}
}

class Algorithm {
public void shortestPath(Vertex startVertex) {
startVertex.setMinDistance(0);
PriorityQueue<Vertex> queue = new PriorityQueue<>();
queue.add(startVertex);

while (!queue.isEmpty()) {
Vertex actualVertex = queue.poll();

for (Edge edge : actualVertex.getAdjacencyList()) {
Vertex v = edge.getTargetVertex();
double weight = edge.getWeight();
double currentDistance = actualVertex.getMinDistance() + weight;

if (currentDistance < v.getMinDistance()) {
queue.remove(v);
v.setMinDistance(currentDistance);
v.setPreviousVertex(actualVertex);
queue.add(v);
}
}
}
}

public List<Vertex> getShortestPathTo(Vertex targetVertex){
List<Vertex> path = new ArrayList<Vertex>();
for (Vertex vertex = targetVertex; vertex != null; vertex = vertex.getPreviousVertex()){
path.add(vertex);
}
Collections.reverse(path);
return path;
}
}

class Coordinate {
private int x;
private int y;

Coordinate(int x, int y) {
this.x = x;
this.y = y;
}

public int getX() {
return this.x;
}

public int getY() {
return this.y;
}

public static Coordinate readInput(Scanner in) {
String[] temp = in.nextLine().split(" ");
return new Coordinate(Integer.parseInt(temp[0]), Integer.parseInt(temp[1]));
}
}

如果我从这个文本文件中读取

3 //# of coordinates

0 0 // (x, y)

1 1 // (x, y)

2 0 // (x, y)

1 2 //edge between coordinate 1 to 2

2 3 //edge between coordinate 2 to 3

我的测试用例看起来像这样:

class Test {
public static void main(String[] args) {

Scanner s = new Scanner(System.in);
String[] constants = s.nextLine().split(" ");

final int N = Integer.parseInt(constants[0]);

List<Coordinate> junctions = new ArrayList<>();
List<Coordinate> paths = new ArrayList<>();
List<Vertex> vertices = new ArrayList<>();

for(int i = 0; i < N; i++) {
junctions.add(Coordinate.readInput(s));
}

for(int i = 0; i < N-1; i++) {
paths.add(Coordinate.readInput(s));
}

for(int i = 0; i < N-1; i++) {
int x = junctions.get(paths.get(i).getX() - 1).getX();
int x1 = junctions.get(paths.get(i).getY() - 1).getX();
int y = junctions.get(paths.get(i).getX() - 1).getY();
int y1 = junctions.get(paths.get(i).getY() - 1).getY();

Vertex vertex1 = new Vertex(paths.get(i).getX(), new Coordinate(x, y));
Vertex vertex2 = new Vertex(paths.get(i).getY(), new Coordinate(x1, y1));

double distance = Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2));

vertex1.addNeighbour(new Edge(distance, vertex2));

vertices.add(vertex1);
vertices.add(vertex2);
}

Algorithm a = new Algorithm();
int x = 0;
int y = 0;

for(int i = 0; i < vertices.size(); i++) {
a.shortestPath(vertices.get(i));

for(Vertex vertex : a.getShortestPathTo(vertices.get(i+1))) {
x += vertices.get(vertex.getID()).getPoint().getX();
y += vertices.get(vertex.getID()).getPoint().getY();
}

}
//This prints out "Total X: 5 Total Y: 3" (should be 3 and 1)
System.out.println("Total X: " + x + " Total Y: " + y);
}
}

最佳答案

您的问题出在这部分:

public void shortestPath(Vertex startVertex) {
startVertex.setMinDistance(0);
PriorityQueue<Vertex> queue = new PriorityQueue<>();
queue.add(startVertex);
//The rest is omitted
}

每次运行 shortestPath 方法时,您应该将所有顶点中的所有 minDistance 重置为无穷大,而不仅仅是 startVertex

对于除startVertex之外的所有顶点,开头的minDistance应该设置为无穷大(或Double.MAX_VALUE),或者它将始终为 0

代码:

for(Vertex v : vertices){
v.setMinDistance(Double.MAX_VALUE);
v.setPreviousVertex(null);
}
a.shortestPath(vertices.get(i));

此外,在 Test 类的第三个循环中,您多次初始化相同的顶点。所以,你应该做的是,预初始化所有顶点并将它们保存在一个数组中,如下所示:

for(int i = 0; i < N; i++){
vertices.add(new Vertex(i + 1, junctions.get(i));
}

for(int i = 0; i < N - 1; i++){
//Initialize x, y, x1, y1 here, I just skipped it
Vertex vertex1 = vertices.get(paths.getX() - 1);
Vertex vertex2 = vertices.get(paths.getY() - 1);

double distance = Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2));

vertex1.addNeighbour(new Edge(distance, vertex2));


}

关于java - 用Dijkstra算法求距离为坐标的最短路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29680904/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com