[英]Graph and Dijkstra infinite loop?
So I creating a minecraft plugin where I am in need of a graph to create a navigation system. 所以我创建了一个Minecraft插件,我需要一个图形来创建导航系统。 I researched a bit and found out that I should be able to use Dijkstra, but I have a problem.
我研究了一下,发现我应该可以使用Dijkstra,但我有一个问题。 When searching for the shortest path I am sometimes getting an infinite loop(not always, it usally works the first 2-3 runs but after that it goes into the loop).
当搜索最短路径时,我有时会得到一个无限循环(并不总是,它通常在前2-3次运行时起作用,但之后会进入循环)。
When the player wants to get to a destination I search for the closest vertex and use computePaths with that vertex as parameter. 当玩家想要到达目的地时,我搜索最近的顶点并使用带有该顶点的computePaths作为参数。 When I then run the getShortestPathTo it sometimes gets stuck in an infinite loop and I run out of memory(which makes sence since im adding the same vertexes to the list).
然后,当我运行getShortestPathTo时,它有时会卡在无限循环中,并且我的内存耗尽(因为我将相同的顶点添加到列表中,因此会产生这种情况)。 Can you see why it is getting stuck?
你能明白为什么会卡住吗? As far as I knew Dijkstra should be able to handle going from A node to B node and from B node to A node right?
据我所知,Dijkstra应该能够处理从A节点到B节点以及从B节点到A节点的权利吗?
Below is my code: 以下是我的代码:
public class Dijkstra {
public static void computePaths(Vertex source) {
source.minDistance = 0.;
PriorityQueue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
vertexQueue.add(source);
while (!vertexQueue.isEmpty()) {
Vertex u = vertexQueue.poll();
// Visit each edge exiting u
for (Edge e : u.adjacencies) {
Vertex v = e.target;
double weight = e.weight;
double distanceThroughU = u.minDistance + weight;
if (distanceThroughU < v.minDistance) {
vertexQueue.remove(v);
v.minDistance = distanceThroughU;
v.previous = u;
vertexQueue.add(v);
}
}
}
}
public static List<Vertex> getShortestPathTo(Vertex target) {
List<Vertex> path = new ArrayList<Vertex>();
for (Vertex vertex = target; vertex != null; vertex = vertex.previous) {
path.add(vertex);
}
Collections.reverse(path);
return path;
}
}
and the vertex class: 和顶点类:
public class Vertex implements Comparable<Vertex>
{
public final String name;
public Edge[] adjacencies;
public double minDistance = Double.POSITIVE_INFINITY;
public Vertex previous;
public Location location;
public Vertex(String argName) { name = argName; }
public Vertex(String argName,Location l) { name = argName; location = l;}
public String toString() { return name; }
public int compareTo(Vertex other)
{
return Double.compare(minDistance, other.minDistance);
}
}
When first the plugin is enabled I load all the vertexes from a config file looking something like this(It is the test one i am using) 当第一个插件启用时,我从配置文件加载所有顶点看起来像这样(这是我正在使用的测试)
I am adding vertexes and edges here(not sure if relevent but thought it might be?): 我在这里添加顶点和边缘(不确定是否相关,但认为它可能是?):
public void loadAllVertex() {
ConfigurationSection section = nodeConfig.config.getConfigurationSection("nodes");
for (String key: section.getKeys(false)) {
String locationString = nodeConfig.getString("nodes." + key + ".location");
if (locationString == null)
return;
String[] locationSplit = locationString.split(",");
if (locationSplit.length <=1) {
log.log(Level.SEVERE, "Location is not specified correctly in nodes.yml");
return;
}
Location l = new Location(Bukkit.getWorlds().get(0),Integer.parseInt(locationSplit[0]),Integer.parseInt(locationSplit[1]),Integer.parseInt(locationSplit[2]));
Vertex tmpVertex = new Vertex(key, l);
allNodes.add(tmpVertex);
}
for (Vertex v : allNodes) {
String path = "nodes." + v.name + ".connectedTo";
List<String> connectedTo = nodeConfig.getStringList(path,true);
List<Edge> edges = new ArrayList<>();
for (String sideNodeName : connectedTo) {
Vertex vertexCon = GraphUtils.getVertexByName(allNodes, sideNodeName);
if (vertexCon == null) {
log.warning("The '" + sideNodeName + "' node is not defined");
return;
}
//A.adjacencies = new Edge[]{ new Edge(M, 8) };
edges.add(new Edge(vertexCon,vertexCon.location.distance(v.location)));
}
Edge[] arrayEdges = new Edge[edges.size()];
arrayEdges = edges.toArray(arrayEdges);
v.adjacencies = arrayEdges;
}
}
Think i found the error, so I never had any loops the first time I ran the compute path and findshortestpath so I finally figured out that I could not be resetting things correctly(should have been obvious I know) - I didn't update the vertexes afterwards. 我觉得我发现了错误,所以我第一次运行计算路径和findshortestpath时从来没有任何循环,所以我终于弄清楚我无法正确地重置东西(应该很明显我知道) - 我没有更新之后的顶点。 So I added a method to reset the mindistance and previous attributes and this seems to have done the trick.
所以我添加了一个方法来重置思维和以前的属性,这似乎已经成功了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.